]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
a243109947e2ebf4e9f6aab9067d696b8dbbfe0c
[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
96 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
97 ;; from i386.c.
98
99 \f
100 ;; Processor type. This attribute must exactly match the processor_type
101 ;; enumeration in i386.h.
102 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
103 (const (symbol_ref "ix86_cpu")))
104
105 ;; A basic instruction type. Refinements due to arguments to be
106 ;; provided in other attributes.
107 (define_attr "type"
108 "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"
109 (const_string "other"))
110
111 ;; Main data type used by the insn
112 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
113 (const_string "unknown"))
114
115 ;; Set for i387 operations.
116 (define_attr "i387" ""
117 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
118 (const_int 1)
119 (const_int 0)))
120
121 ;; The (bounding maximum) length of an instruction immediate.
122 (define_attr "length_immediate" ""
123 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
124 (const_int 0)
125 (eq_attr "i387" "1")
126 (const_int 0)
127 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
128 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
129 (eq_attr "type" "imov,test")
130 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
131 (eq_attr "type" "call")
132 (if_then_else (match_operand 0 "constant_call_address_operand" "")
133 (const_int 4)
134 (const_int 0))
135 (eq_attr "type" "callv")
136 (if_then_else (match_operand 1 "constant_call_address_operand" "")
137 (const_int 4)
138 (const_int 0))
139 (eq_attr "type" "ibr")
140 (if_then_else (and (ge (minus (match_dup 0) (pc))
141 (const_int -128))
142 (lt (minus (match_dup 0) (pc))
143 (const_int 124)))
144 (const_int 1)
145 (const_int 4))
146 ]
147 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
148
149 ;; The (bounding maximum) length of an instruction address.
150 (define_attr "length_address" ""
151 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
152 (const_int 0)
153 (and (eq_attr "type" "call")
154 (match_operand 1 "constant_call_address_operand" ""))
155 (const_int 0)
156 (and (eq_attr "type" "callv")
157 (match_operand 1 "constant_call_address_operand" ""))
158 (const_int 0)
159 ]
160 (symbol_ref "ix86_attr_length_address_default (insn)")))
161
162 ;; Set when length prefix is used.
163 (define_attr "prefix_data16" ""
164 (if_then_else (eq_attr "mode" "HI")
165 (const_int 1)
166 (const_int 0)))
167
168 ;; Set when string REP prefix is used.
169 (define_attr "prefix_rep" "" (const_int 0))
170
171 ;; Set when 0f opcode prefix is used.
172 (define_attr "prefix_0f" ""
173 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
174 (const_int 1)
175 (const_int 0)))
176
177 ;; Set when modrm byte is used.
178 (define_attr "modrm" ""
179 (cond [(eq_attr "type" "str,cld")
180 (const_int 0)
181 (eq_attr "i387" "1")
182 (const_int 0)
183 (and (eq_attr "type" "incdec")
184 (ior (match_operand:SI 1 "register_operand" "")
185 (match_operand:HI 1 "register_operand" "")))
186 (const_int 0)
187 (and (eq_attr "type" "push")
188 (not (match_operand 1 "memory_operand" "")))
189 (const_int 0)
190 (and (eq_attr "type" "pop")
191 (not (match_operand 0 "memory_operand" "")))
192 (const_int 0)
193 (and (eq_attr "type" "imov")
194 (and (match_operand 0 "register_operand" "")
195 (match_operand 1 "immediate_operand" "")))
196 (const_int 0)
197 ]
198 (const_int 1)))
199
200 ;; The (bounding maximum) length of an instruction in bytes.
201 (define_attr "length" ""
202 (cond [(eq_attr "type" "other,multi")
203 (const_int 16)
204 ]
205 (plus (plus (attr "modrm")
206 (plus (attr "prefix_0f")
207 (plus (attr "i387")
208 (const_int 1))))
209 (plus (attr "prefix_rep")
210 (plus (attr "prefix_data16")
211 (plus (attr "length_immediate")
212 (attr "length_address")))))))
213
214 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
215 ;; `store' if there is a simple memory reference therein, or `unknown'
216 ;; if the instruction is complex.
217
218 (define_attr "memory" "none,load,store,both,unknown"
219 (cond [(eq_attr "type" "other,multi,str")
220 (const_string "unknown")
221 (eq_attr "type" "lea,fcmov,fpspc,cld")
222 (const_string "none")
223 (eq_attr "type" "push")
224 (if_then_else (match_operand 1 "memory_operand" "")
225 (const_string "both")
226 (const_string "store"))
227 (eq_attr "type" "pop,setcc")
228 (if_then_else (match_operand 0 "memory_operand" "")
229 (const_string "both")
230 (const_string "load"))
231 (eq_attr "type" "icmp,test")
232 (if_then_else (ior (match_operand 0 "memory_operand" "")
233 (match_operand 1 "memory_operand" ""))
234 (const_string "load")
235 (const_string "none"))
236 (eq_attr "type" "ibr")
237 (if_then_else (match_operand 0 "memory_operand" "")
238 (const_string "load")
239 (const_string "none"))
240 (eq_attr "type" "call")
241 (if_then_else (match_operand 0 "constant_call_address_operand" "")
242 (const_string "none")
243 (const_string "load"))
244 (eq_attr "type" "callv")
245 (if_then_else (match_operand 1 "constant_call_address_operand" "")
246 (const_string "none")
247 (const_string "load"))
248 (and (eq_attr "type" "alu1,negnot")
249 (match_operand 1 "memory_operand" ""))
250 (const_string "both")
251 (and (match_operand 0 "memory_operand" "")
252 (match_operand 1 "memory_operand" ""))
253 (const_string "both")
254 (match_operand 0 "memory_operand" "")
255 (const_string "store")
256 (match_operand 1 "memory_operand" "")
257 (const_string "load")
258 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
259 (match_operand 2 "memory_operand" ""))
260 (const_string "load")
261 (and (eq_attr "type" "icmov")
262 (match_operand 3 "memory_operand" ""))
263 (const_string "load")
264 ]
265 (const_string "none")))
266
267 ;; Indicates if an instruction has both an immediate and a displacement.
268
269 (define_attr "imm_disp" "false,true,unknown"
270 (cond [(eq_attr "type" "other,multi")
271 (const_string "unknown")
272 (and (eq_attr "type" "icmp,test,imov")
273 (and (match_operand 0 "memory_displacement_operand" "")
274 (match_operand 1 "immediate_operand" "")))
275 (const_string "true")
276 (and (eq_attr "type" "alu,ishift,imul,idiv")
277 (and (match_operand 0 "memory_displacement_operand" "")
278 (match_operand 2 "immediate_operand" "")))
279 (const_string "true")
280 ]
281 (const_string "false")))
282
283 ;; Indicates if an FP operation has an integer source.
284
285 (define_attr "fp_int_src" "false,true"
286 (const_string "false"))
287
288 ;; Describe a user's asm statement.
289 (define_asm_attributes
290 [(set_attr "length" "128")
291 (set_attr "type" "multi")])
292 \f
293 ;; Pentium Scheduling
294 ;;
295 ;; The Pentium is an in-order core with two integer pipelines.
296
297 ;; True for insns that behave like prefixed insns on the Pentium.
298 (define_attr "pent_prefix" "false,true"
299 (if_then_else (ior (eq_attr "prefix_0f" "1")
300 (ior (eq_attr "prefix_data16" "1")
301 (eq_attr "prefix_rep" "1")))
302 (const_string "true")
303 (const_string "false")))
304
305 ;; Categorize how an instruction slots.
306
307 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
308 ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
309 ;; rules, because it results in noticeably better code on non-MMX Pentium
310 ;; and doesn't hurt much on MMX. (Prefixed instructions are not very
311 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
312
313 (define_attr "pent_pair" "uv,pu,pv,np"
314 (cond [(eq_attr "imm_disp" "true")
315 (const_string "np")
316 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
317 (and (eq_attr "type" "pop,push")
318 (eq_attr "memory" "!both")))
319 (if_then_else (eq_attr "pent_prefix" "true")
320 (const_string "pu")
321 (const_string "uv"))
322 (eq_attr "type" "ibr")
323 (const_string "pv")
324 (and (eq_attr "type" "ishift")
325 (match_operand 2 "const_int_operand" ""))
326 (const_string "pu")
327 (and (eq_attr "type" "call")
328 (match_operand 0 "constant_call_address_operand" ""))
329 (const_string "pv")
330 (and (eq_attr "type" "callv")
331 (match_operand 1 "constant_call_address_operand" ""))
332 (const_string "pv")
333 ]
334 (const_string "np")))
335
336 ;; Rough readiness numbers. Fine tuning happens in i386.c.
337 ;;
338 ;; u describes pipe U
339 ;; v describes pipe V
340 ;; uv describes either pipe U or V for those that can issue to either
341 ;; np describes not paring
342 ;; fpu describes fpu
343 ;; fpm describes fp insns of different types are not pipelined.
344 ;;
345 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
346
347 (define_function_unit "pent_np" 1 0
348 (and (eq_attr "cpu" "pentium")
349 (eq_attr "type" "imul"))
350 11 11)
351
352 (define_function_unit "pent_mul" 1 1
353 (and (eq_attr "cpu" "pentium")
354 (eq_attr "type" "imul"))
355 11 11)
356
357 ;; Rep movs takes minimally 12 cycles.
358 (define_function_unit "pent_np" 1 0
359 (and (eq_attr "cpu" "pentium")
360 (eq_attr "type" "str"))
361 12 12)
362
363 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
364 (define_function_unit "pent_np" 1 0
365 (and (eq_attr "cpu" "pentium")
366 (eq_attr "type" "idiv"))
367 46 46)
368
369 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
370 ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
371 ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
372 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
373 ; like normal fp operation and fist takes 6 cycles.
374
375 (define_function_unit "fpu" 1 0
376 (and (eq_attr "cpu" "pentium")
377 (and (eq_attr "type" "fmov")
378 (and (eq_attr "memory" "load,store")
379 (eq_attr "mode" "XF"))))
380 3 3)
381
382 (define_function_unit "pent_np" 1 0
383 (and (eq_attr "cpu" "pentium")
384 (and (eq_attr "type" "fmov")
385 (and (eq_attr "memory" "load,store")
386 (eq_attr "mode" "XF"))))
387 3 3)
388
389 (define_function_unit "fpu" 1 0
390 (and (eq_attr "cpu" "pentium")
391 (and (eq_attr "type" "fmov")
392 (ior (match_operand 1 "immediate_operand" "")
393 (eq_attr "memory" "store"))))
394 2 2)
395
396 (define_function_unit "pent_np" 1 0
397 (and (eq_attr "cpu" "pentium")
398 (and (eq_attr "type" "fmov")
399 (ior (match_operand 1 "immediate_operand" "")
400 (eq_attr "memory" "store"))))
401 2 2)
402
403 (define_function_unit "pent_np" 1 0
404 (and (eq_attr "cpu" "pentium")
405 (eq_attr "type" "cld"))
406 2 2)
407
408 (define_function_unit "fpu" 1 0
409 (and (eq_attr "cpu" "pentium")
410 (and (eq_attr "type" "fmov")
411 (eq_attr "memory" "none,load")))
412 1 1)
413
414 ; Read/Modify/Write instructions usually take 3 cycles.
415 (define_function_unit "pent_u" 1 0
416 (and (eq_attr "cpu" "pentium")
417 (and (eq_attr "type" "alu,alu1,ishift")
418 (and (eq_attr "pent_pair" "pu")
419 (eq_attr "memory" "both"))))
420 3 3)
421
422 (define_function_unit "pent_uv" 2 0
423 (and (eq_attr "cpu" "pentium")
424 (and (eq_attr "type" "alu,alu1,ishift")
425 (and (eq_attr "pent_pair" "!np")
426 (eq_attr "memory" "both"))))
427 3 3)
428
429 (define_function_unit "pent_np" 1 0
430 (and (eq_attr "cpu" "pentium")
431 (and (eq_attr "type" "alu,alu1,negnot,ishift")
432 (and (eq_attr "pent_pair" "np")
433 (eq_attr "memory" "both"))))
434 3 3)
435
436 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
437 (define_function_unit "pent_u" 1 0
438 (and (eq_attr "cpu" "pentium")
439 (and (eq_attr "type" "alu,ishift")
440 (and (eq_attr "pent_pair" "pu")
441 (eq_attr "memory" "load,store"))))
442 2 2)
443
444 (define_function_unit "pent_uv" 2 0
445 (and (eq_attr "cpu" "pentium")
446 (and (eq_attr "type" "alu,ishift")
447 (and (eq_attr "pent_pair" "!np")
448 (eq_attr "memory" "load,store"))))
449 2 2)
450
451 (define_function_unit "pent_np" 1 0
452 (and (eq_attr "cpu" "pentium")
453 (and (eq_attr "type" "alu,ishift")
454 (and (eq_attr "pent_pair" "np")
455 (eq_attr "memory" "load,store"))))
456 2 2)
457
458 ; Insns w/o memory operands and move instructions usually take one cycle.
459 (define_function_unit "pent_u" 1 0
460 (and (eq_attr "cpu" "pentium")
461 (eq_attr "pent_pair" "pu"))
462 1 1)
463
464 (define_function_unit "pent_v" 1 0
465 (and (eq_attr "cpu" "pentium")
466 (eq_attr "pent_pair" "pv"))
467 1 1)
468
469 (define_function_unit "pent_uv" 2 0
470 (and (eq_attr "cpu" "pentium")
471 (eq_attr "pent_pair" "!np"))
472 1 1)
473
474 (define_function_unit "pent_np" 1 0
475 (and (eq_attr "cpu" "pentium")
476 (eq_attr "pent_pair" "np"))
477 1 1)
478
479 ; Pairable insns only conflict with other non-pairable insns.
480 (define_function_unit "pent_np" 1 0
481 (and (eq_attr "cpu" "pentium")
482 (and (eq_attr "type" "alu,alu1,ishift")
483 (and (eq_attr "pent_pair" "!np")
484 (eq_attr "memory" "both"))))
485 3 3
486 [(eq_attr "pent_pair" "np")])
487
488 (define_function_unit "pent_np" 1 0
489 (and (eq_attr "cpu" "pentium")
490 (and (eq_attr "type" "alu,alu1,ishift")
491 (and (eq_attr "pent_pair" "!np")
492 (eq_attr "memory" "load,store"))))
493 2 2
494 [(eq_attr "pent_pair" "np")])
495
496 (define_function_unit "pent_np" 1 0
497 (and (eq_attr "cpu" "pentium")
498 (eq_attr "pent_pair" "!np"))
499 1 1
500 [(eq_attr "pent_pair" "np")])
501
502 ; Floating point instructions usually blocks cycle longer when combined with
503 ; integer instructions, because of the inpaired fxch instruction.
504 (define_function_unit "pent_np" 1 0
505 (and (eq_attr "cpu" "pentium")
506 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
507 2 2
508 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
509
510 (define_function_unit "fpu" 1 0
511 (and (eq_attr "cpu" "pentium")
512 (eq_attr "type" "fcmp,fxch,fsgn"))
513 1 1)
514
515 ; Addition takes 3 cycles; assume other random cruft does as well.
516 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
517 (define_function_unit "fpu" 1 0
518 (and (eq_attr "cpu" "pentium")
519 (eq_attr "type" "fop,fop1"))
520 3 1)
521
522 ; Multiplication takes 3 cycles and is only half pipelined.
523 (define_function_unit "fpu" 1 0
524 (and (eq_attr "cpu" "pentium")
525 (eq_attr "type" "fmul"))
526 3 1)
527
528 (define_function_unit "pent_mul" 1 1
529 (and (eq_attr "cpu" "pentium")
530 (eq_attr "type" "fmul"))
531 2 2)
532
533 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
534 ; They can overlap with integer insns. Only the last two cycles can overlap
535 ; with other fp insns. Only fsin/fcos can overlap with multiplies.
536 ; Only last two cycles of fsin/fcos can overlap with other instructions.
537 (define_function_unit "fpu" 1 0
538 (and (eq_attr "cpu" "pentium")
539 (eq_attr "type" "fdiv"))
540 39 37)
541
542 (define_function_unit "pent_mul" 1 1
543 (and (eq_attr "cpu" "pentium")
544 (eq_attr "type" "fdiv"))
545 39 39)
546
547 (define_function_unit "fpu" 1 0
548 (and (eq_attr "cpu" "pentium")
549 (eq_attr "type" "fpspc"))
550 70 68)
551
552 (define_function_unit "pent_mul" 1 1
553 (and (eq_attr "cpu" "pentium")
554 (eq_attr "type" "fpspc"))
555 70 70)
556 \f
557 ;; Pentium Pro/PII Scheduling
558 ;;
559 ;; The PPro has an out-of-order core, but the instruction decoders are
560 ;; naturally in-order and asymmetric. We get best performance by scheduling
561 ;; for the decoders, for in doing so we give the oo execution unit the
562 ;; most choices.
563
564 ;; Categorize how many uops an ia32 instruction evaluates to:
565 ;; one -- an instruction with 1 uop can be decoded by any of the
566 ;; three decoders.
567 ;; few -- an instruction with 1 to 4 uops can be decoded only by
568 ;; decoder 0.
569 ;; many -- a complex instruction may take an unspecified number of
570 ;; cycles to decode in decoder 0.
571
572 (define_attr "ppro_uops" "one,few,many"
573 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
574 (const_string "many")
575 (eq_attr "type" "icmov,fcmov,str,cld")
576 (const_string "few")
577 (eq_attr "type" "imov")
578 (if_then_else (eq_attr "memory" "store,both")
579 (const_string "few")
580 (const_string "one"))
581 (eq_attr "memory" "!none")
582 (const_string "few")
583 ]
584 (const_string "one")))
585
586 ;; Rough readiness numbers. Fine tuning happens in i386.c.
587 ;;
588 ;; p0 describes port 0.
589 ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
590 ;; p2 describes port 2 for loads.
591 ;; p34 describes ports 3 and 4 for stores.
592 ;; fpu describes the fpu accessed via port 0.
593 ;; ??? It is less than clear if there are separate fadd and fmul units
594 ;; that could operate in parallel.
595 ;;
596 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
597
598 (define_function_unit "ppro_p0" 1 0
599 (and (eq_attr "cpu" "pentiumpro")
600 (eq_attr "type" "ishift,lea,ibr,cld"))
601 1 1)
602
603 (define_function_unit "ppro_p0" 1 0
604 (and (eq_attr "cpu" "pentiumpro")
605 (eq_attr "type" "imul"))
606 4 1)
607
608 ;; ??? Does the divider lock out the pipe while it works,
609 ;; or is there a disconnected unit?
610 (define_function_unit "ppro_p0" 1 0
611 (and (eq_attr "cpu" "pentiumpro")
612 (eq_attr "type" "idiv"))
613 17 17)
614
615 (define_function_unit "ppro_p0" 1 0
616 (and (eq_attr "cpu" "pentiumpro")
617 (eq_attr "type" "fop,fop1,fsgn"))
618 3 1)
619
620 (define_function_unit "ppro_p0" 1 0
621 (and (eq_attr "cpu" "pentiumpro")
622 (eq_attr "type" "fcmov"))
623 2 1)
624
625 (define_function_unit "ppro_p0" 1 0
626 (and (eq_attr "cpu" "pentiumpro")
627 (eq_attr "type" "fcmp"))
628 1 1)
629
630 (define_function_unit "ppro_p0" 1 0
631 (and (eq_attr "cpu" "pentiumpro")
632 (eq_attr "type" "fmov"))
633 1 1)
634
635 (define_function_unit "ppro_p0" 1 0
636 (and (eq_attr "cpu" "pentiumpro")
637 (eq_attr "type" "fmul"))
638 5 1)
639
640 (define_function_unit "ppro_p0" 1 0
641 (and (eq_attr "cpu" "pentiumpro")
642 (eq_attr "type" "fdiv,fpspc"))
643 56 1)
644
645 (define_function_unit "ppro_p01" 2 0
646 (and (eq_attr "cpu" "pentiumpro")
647 (eq_attr "type" "!imov,fmov"))
648 1 1)
649
650 (define_function_unit "ppro_p01" 2 0
651 (and (and (eq_attr "cpu" "pentiumpro")
652 (eq_attr "type" "imov,fmov"))
653 (eq_attr "memory" "none"))
654 1 1)
655
656 (define_function_unit "ppro_p2" 1 0
657 (and (eq_attr "cpu" "pentiumpro")
658 (ior (eq_attr "type" "pop")
659 (eq_attr "memory" "load,both")))
660 3 1)
661
662 (define_function_unit "ppro_p34" 1 0
663 (and (eq_attr "cpu" "pentiumpro")
664 (ior (eq_attr "type" "push")
665 (eq_attr "memory" "store,both")))
666 1 1)
667
668 (define_function_unit "fpu" 1 0
669 (and (eq_attr "cpu" "pentiumpro")
670 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
671 1 1)
672
673 (define_function_unit "fpu" 1 0
674 (and (eq_attr "cpu" "pentiumpro")
675 (eq_attr "type" "fmul"))
676 5 2)
677
678 (define_function_unit "fpu" 1 0
679 (and (eq_attr "cpu" "pentiumpro")
680 (eq_attr "type" "fdiv,fpspc"))
681 56 56)
682
683 ;; imul uses the fpu. ??? does it have the same throughput as fmul?
684 (define_function_unit "fpu" 1 0
685 (and (eq_attr "cpu" "pentiumpro")
686 (eq_attr "type" "imul"))
687 4 1)
688 \f
689 ;; AMD K6/K6-2 Scheduling
690 ;;
691 ;; The K6 has similar architecture to PPro. Important difference is, that
692 ;; there are only two decoders and they seems to be much slower than execution
693 ;; units. So we have to pay much more attention to proper decoding for
694 ;; schedulers. We share most of scheduler code for PPro in i386.c
695 ;;
696 ;; The fp unit is not pipelined and do one operation per two cycles including
697 ;; the FXCH.
698 ;;
699 ;; alu describes both ALU units (ALU-X and ALU-Y).
700 ;; alux describes X alu unit
701 ;; fpu describes FPU unit
702 ;; load describes load unit.
703 ;; branch describes branch unit.
704 ;; store decsribes store unit. This unit is not modelled completely and only
705 ;; used to model lea operation. Otherwise it lie outside of the critical
706 ;; path.
707 ;;
708 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
709
710 ;; The decoder specification is in the PPro section above!
711
712 ;; Shift instructions and certain arithmetic are issued only to X pipe.
713 (define_function_unit "k6_alux" 1 0
714 (and (eq_attr "cpu" "k6")
715 (eq_attr "type" "ishift,alu1,negnot,cld"))
716 1 1)
717
718 ;; The QI mode arithmetic is issued to X pipe only.
719 (define_function_unit "k6_alux" 1 0
720 (and (eq_attr "cpu" "k6")
721 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
722 (match_operand:QI 0 "general_operand" "")))
723 1 1)
724
725 (define_function_unit "k6_alu" 2 0
726 (and (eq_attr "cpu" "k6")
727 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
728 1 1)
729
730 (define_function_unit "k6_alu" 2 0
731 (and (eq_attr "cpu" "k6")
732 (and (eq_attr "type" "imov")
733 (eq_attr "memory" "none")))
734 1 1)
735
736 (define_function_unit "k6_branch" 1 0
737 (and (eq_attr "cpu" "k6")
738 (eq_attr "type" "call,callv,ibr"))
739 1 1)
740
741 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
742 (define_function_unit "k6_load" 1 0
743 (and (eq_attr "cpu" "k6")
744 (ior (eq_attr "type" "pop")
745 (eq_attr "memory" "load,both")))
746 1 1)
747
748 (define_function_unit "k6_load" 1 0
749 (and (eq_attr "cpu" "k6")
750 (and (eq_attr "type" "str")
751 (eq_attr "memory" "load,both")))
752 10 10)
753
754 ;; Lea have two instructions, so latency is probably 2
755 (define_function_unit "k6_store" 1 0
756 (and (eq_attr "cpu" "k6")
757 (eq_attr "type" "lea"))
758 2 1)
759
760 (define_function_unit "k6_store" 1 0
761 (and (eq_attr "cpu" "k6")
762 (eq_attr "type" "str"))
763 10 10)
764
765 (define_function_unit "k6_store" 1 0
766 (and (eq_attr "cpu" "k6")
767 (ior (eq_attr "type" "push")
768 (eq_attr "memory" "store,both")))
769 1 1)
770
771 (define_function_unit "k6_fpu" 1 1
772 (and (eq_attr "cpu" "k6")
773 (eq_attr "type" "fop,fop1,fmov,fcmp"))
774 2 2)
775
776 (define_function_unit "k6_fpu" 1 1
777 (and (eq_attr "cpu" "k6")
778 (eq_attr "type" "fmul"))
779 2 2)
780
781 ;; ??? Guess
782 (define_function_unit "k6_fpu" 1 1
783 (and (eq_attr "cpu" "k6")
784 (eq_attr "type" "fdiv,fpspc"))
785 56 56)
786
787 (define_function_unit "k6_alu" 2 0
788 (and (eq_attr "cpu" "k6")
789 (eq_attr "type" "imul"))
790 2 2)
791
792 (define_function_unit "k6_alux" 1 0
793 (and (eq_attr "cpu" "k6")
794 (eq_attr "type" "imul"))
795 2 2)
796
797 ;; ??? Guess
798 (define_function_unit "k6_alu" 2 0
799 (and (eq_attr "cpu" "k6")
800 (eq_attr "type" "idiv"))
801 17 17)
802
803 (define_function_unit "k6_alux" 1 0
804 (and (eq_attr "cpu" "k6")
805 (eq_attr "type" "idiv"))
806 17 17)
807 \f
808 ;; AMD Athlon Scheduling
809 ;;
810 ;; The Athlon does contain three pipelined FP units, three integer units and
811 ;; three address generation units.
812 ;;
813 ;; The predecode logic is determining boundaries of instructions in the 64
814 ;; byte cache line. So the cache line straddling problem of K6 might be issue
815 ;; here as well, but it is not noted in the documentation.
816 ;;
817 ;; Three DirectPath instructions decoders and only one VectorPath decoder
818 ;; is available. They can decode three DirectPath instructions or one VectorPath
819 ;; instruction per cycle.
820 ;; Decoded macro instructions are then passed to 72 entry instruction control
821 ;; unit, that passes
822 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
823 ;;
824 ;; The load/store queue unit is not attached to the schedulers but
825 ;; communicates with all the execution units seperately instead.
826
827 (define_attr "athlon_decode" "direct,vector"
828 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
829 (const_string "vector")
830 (and (eq_attr "type" "push")
831 (match_operand 1 "memory_operand" ""))
832 (const_string "vector")
833 (and (eq_attr "type" "fmov")
834 (and (eq_attr "memory" "load,store")
835 (eq_attr "mode" "XF")))
836 (const_string "vector")]
837 (const_string "direct")))
838
839 (define_function_unit "athlon_vectordec" 1 0
840 (and (eq_attr "cpu" "athlon")
841 (eq_attr "athlon_decode" "vector"))
842 1 1)
843
844 (define_function_unit "athlon_directdec" 3 0
845 (and (eq_attr "cpu" "athlon")
846 (eq_attr "athlon_decode" "direct"))
847 1 1)
848
849 (define_function_unit "athlon_vectordec" 1 0
850 (and (eq_attr "cpu" "athlon")
851 (eq_attr "athlon_decode" "direct"))
852 1 1 [(eq_attr "athlon_decode" "vector")])
853
854 (define_function_unit "athlon_ieu" 3 0
855 (and (eq_attr "cpu" "athlon")
856 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
857 1 1)
858
859 (define_function_unit "athlon_ieu" 3 0
860 (and (eq_attr "cpu" "athlon")
861 (eq_attr "type" "str"))
862 15 15)
863
864 (define_function_unit "athlon_ieu" 3 0
865 (and (eq_attr "cpu" "athlon")
866 (eq_attr "type" "imul"))
867 5 0)
868
869 (define_function_unit "athlon_ieu" 3 0
870 (and (eq_attr "cpu" "athlon")
871 (eq_attr "type" "idiv"))
872 42 0)
873
874 (define_function_unit "athlon_muldiv" 1 0
875 (and (eq_attr "cpu" "athlon")
876 (eq_attr "type" "imul"))
877 5 0)
878
879 (define_function_unit "athlon_muldiv" 1 0
880 (and (eq_attr "cpu" "athlon")
881 (eq_attr "type" "idiv"))
882 42 42)
883
884 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
885 (cond [(eq_attr "type" "fop,fop1,fcmp")
886 (const_string "add")
887 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
888 (const_string "mul")
889 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
890 (const_string "store")
891 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
892 (const_string "any")
893 (and (eq_attr "type" "fmov")
894 (ior (match_operand:SI 1 "register_operand" "")
895 (match_operand 1 "immediate_operand" "")))
896 (const_string "store")
897 (eq_attr "type" "fmov")
898 (const_string "muladd")]
899 (const_string "none")))
900
901 ;; We use latencies 1 for definitions. This is OK to model colisions
902 ;; in execution units. The real latencies are modeled in the "fp" pipeline.
903
904 ;; fsin, fcos: 96-192
905 ;; fsincos: 107-211
906 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
907 (define_function_unit "athlon_fp" 3 0
908 (and (eq_attr "cpu" "athlon")
909 (eq_attr "type" "fpspc"))
910 100 1)
911
912 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
913 (define_function_unit "athlon_fp" 3 0
914 (and (eq_attr "cpu" "athlon")
915 (eq_attr "type" "fdiv"))
916 24 1)
917
918 (define_function_unit "athlon_fp" 3 0
919 (and (eq_attr "cpu" "athlon")
920 (eq_attr "type" "fop,fop1,fmul"))
921 4 1)
922
923 ;; XFmode loads are slow.
924 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
925 ;; there are no dependent instructions.
926
927 (define_function_unit "athlon_fp" 3 0
928 (and (eq_attr "cpu" "athlon")
929 (and (eq_attr "type" "fmov")
930 (and (eq_attr "memory" "load")
931 (eq_attr "mode" "XF"))))
932 10 1)
933
934 (define_function_unit "athlon_fp" 3 0
935 (and (eq_attr "cpu" "athlon")
936 (eq_attr "type" "fmov,fsgn"))
937 2 1)
938
939 ;; fcmp and ftst instructions
940 (define_function_unit "athlon_fp" 3 0
941 (and (eq_attr "cpu" "athlon")
942 (and (eq_attr "type" "fcmp")
943 (eq_attr "athlon_decode" "direct")))
944 3 1)
945
946 ;; fcmpi instructions.
947 (define_function_unit "athlon_fp" 3 0
948 (and (eq_attr "cpu" "athlon")
949 (and (eq_attr "type" "fcmp")
950 (eq_attr "athlon_decode" "vector")))
951 3 1)
952
953 (define_function_unit "athlon_fp" 3 0
954 (and (eq_attr "cpu" "athlon")
955 (eq_attr "type" "fcmov"))
956 7 1)
957
958 (define_function_unit "athlon_fp_mul" 1 0
959 (and (eq_attr "cpu" "athlon")
960 (eq_attr "athlon_fpunits" "mul"))
961 1 1)
962
963 (define_function_unit "athlon_fp_add" 1 0
964 (and (eq_attr "cpu" "athlon")
965 (eq_attr "athlon_fpunits" "add"))
966 1 1)
967
968 (define_function_unit "athlon_fp_muladd" 2 0
969 (and (eq_attr "cpu" "athlon")
970 (eq_attr "athlon_fpunits" "muladd,mul,add"))
971 1 1)
972
973 (define_function_unit "athlon_fp_store" 1 0
974 (and (eq_attr "cpu" "athlon")
975 (eq_attr "athlon_fpunits" "store"))
976 1 1)
977
978 ;; We don't need to model the Adress Generation Unit, since we don't model
979 ;; the re-order buffer yet and thus we never schedule more than three operations
980 ;; at time. Later we may want to experiment with MD_SCHED macros modeling the
981 ;; decoders independently on the functional units.
982
983 ;(define_function_unit "athlon_agu" 3 0
984 ; (and (eq_attr "cpu" "athlon")
985 ; (and (eq_attr "memory" "!none")
986 ; (eq_attr "athlon_fpunits" "none")))
987 ; 1 1)
988
989 ;; Model load unit to avoid too long sequences of loads. We don't need to
990 ;; model store queue, since it is hardly going to be bottleneck.
991
992 (define_function_unit "athlon_load" 2 0
993 (and (eq_attr "cpu" "athlon")
994 (eq_attr "memory" "load,both"))
995 1 1)
996
997 \f
998 ;; Compare instructions.
999
1000 ;; All compare insns have expanders that save the operands away without
1001 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
1002 ;; after the cmp) will actually emit the cmpM.
1003
1004 (define_expand "cmpdi"
1005 [(set (reg:CC 17)
1006 (compare:CC (match_operand:DI 0 "x86_64_general_operand" "")
1007 (match_operand:DI 1 "x86_64_general_operand" "")))]
1008 ""
1009 "
1010 {
1011 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1012 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1013 operands[0] = force_reg (DImode, operands[0]);
1014 ix86_compare_op0 = operands[0];
1015 ix86_compare_op1 = operands[1];
1016 DONE;
1017 }")
1018
1019 (define_expand "cmpsi"
1020 [(set (reg:CC 17)
1021 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1022 (match_operand:SI 1 "general_operand" "")))]
1023 ""
1024 "
1025 {
1026 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1027 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1028 operands[0] = force_reg (SImode, operands[0]);
1029 ix86_compare_op0 = operands[0];
1030 ix86_compare_op1 = operands[1];
1031 DONE;
1032 }")
1033
1034 (define_expand "cmphi"
1035 [(set (reg:CC 17)
1036 (compare:CC (match_operand:HI 0 "general_operand" "")
1037 (match_operand:HI 1 "general_operand" "")))]
1038 ""
1039 "
1040 {
1041 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1042 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1043 operands[0] = force_reg (HImode, operands[0]);
1044 ix86_compare_op0 = operands[0];
1045 ix86_compare_op1 = operands[1];
1046 DONE;
1047 }")
1048
1049 (define_expand "cmpqi"
1050 [(set (reg:CC 17)
1051 (compare:CC (match_operand:QI 0 "general_operand" "")
1052 (match_operand:QI 1 "general_operand" "")))]
1053 "TARGET_QIMODE_MATH"
1054 "
1055 {
1056 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1057 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1058 operands[0] = force_reg (QImode, operands[0]);
1059 ix86_compare_op0 = operands[0];
1060 ix86_compare_op1 = operands[1];
1061 DONE;
1062 }")
1063
1064 (define_insn "cmpdi_ccno_1_rex64"
1065 [(set (reg 17)
1066 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
1067 (match_operand:DI 1 "const0_operand" "n,n")))]
1068 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1069 "@
1070 test{q}\\t{%0, %0|%0, %0}
1071 cmp{q}\\t{%1, %0|%0, %1}"
1072 [(set_attr "type" "test,icmp")
1073 (set_attr "length_immediate" "0,1")
1074 (set_attr "mode" "DI")])
1075
1076 (define_insn "*cmpdi_minus_1_rex64"
1077 [(set (reg 17)
1078 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
1079 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
1080 (const_int 0)))]
1081 "ix86_match_ccmode (insn, CCGOCmode)"
1082 "cmp{q}\\t{%1, %0|%0, %1}"
1083 [(set_attr "type" "icmp")
1084 (set_attr "mode" "DI")])
1085
1086 (define_expand "cmpdi_1_rex64"
1087 [(set (reg:CC 17)
1088 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
1089 (match_operand:DI 1 "general_operand" "")))]
1090 ""
1091 "")
1092
1093 (define_insn "cmpdi_1_insn_rex64"
1094 [(set (reg 17)
1095 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1096 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1097 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1098 "cmp{q}\\t{%1, %0|%0, %1}"
1099 [(set_attr "type" "icmp")
1100 (set_attr "mode" "DI")])
1101
1102
1103 (define_insn "*cmpsi_ccno_1"
1104 [(set (reg 17)
1105 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1106 (match_operand:SI 1 "const0_operand" "n,n")))]
1107 "ix86_match_ccmode (insn, CCNOmode)"
1108 "@
1109 test{l}\\t{%0, %0|%0, %0}
1110 cmp{l}\\t{%1, %0|%0, %1}"
1111 [(set_attr "type" "test,icmp")
1112 (set_attr "length_immediate" "0,1")
1113 (set_attr "mode" "SI")])
1114
1115 (define_insn "*cmpsi_minus_1"
1116 [(set (reg 17)
1117 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1118 (match_operand:SI 1 "general_operand" "ri,mr"))
1119 (const_int 0)))]
1120 "ix86_match_ccmode (insn, CCGOCmode)"
1121 "cmp{l}\\t{%1, %0|%0, %1}"
1122 [(set_attr "type" "icmp")
1123 (set_attr "mode" "SI")])
1124
1125 (define_expand "cmpsi_1"
1126 [(set (reg:CC 17)
1127 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1128 (match_operand:SI 1 "general_operand" "ri,mr")))]
1129 ""
1130 "")
1131
1132 (define_insn "*cmpsi_1_insn"
1133 [(set (reg 17)
1134 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1135 (match_operand:SI 1 "general_operand" "ri,mr")))]
1136 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1137 && ix86_match_ccmode (insn, CCmode)"
1138 "cmp{l}\\t{%1, %0|%0, %1}"
1139 [(set_attr "type" "icmp")
1140 (set_attr "mode" "SI")])
1141
1142 (define_insn "*cmphi_ccno_1"
1143 [(set (reg 17)
1144 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1145 (match_operand:HI 1 "const0_operand" "n,n")))]
1146 "ix86_match_ccmode (insn, CCNOmode)"
1147 "@
1148 test{w}\\t{%0, %0|%0, %0}
1149 cmp{w}\\t{%1, %0|%0, %1}"
1150 [(set_attr "type" "test,icmp")
1151 (set_attr "length_immediate" "0,1")
1152 (set_attr "mode" "HI")])
1153
1154 (define_insn "*cmphi_minus_1"
1155 [(set (reg 17)
1156 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1157 (match_operand:HI 1 "general_operand" "ri,mr"))
1158 (const_int 0)))]
1159 "ix86_match_ccmode (insn, CCGOCmode)"
1160 "cmp{w}\\t{%1, %0|%0, %1}"
1161 [(set_attr "type" "icmp")
1162 (set_attr "mode" "HI")])
1163
1164 (define_insn "*cmphi_1"
1165 [(set (reg 17)
1166 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1167 (match_operand:HI 1 "general_operand" "ri,mr")))]
1168 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1169 && ix86_match_ccmode (insn, CCmode)"
1170 "cmp{w}\\t{%1, %0|%0, %1}"
1171 [(set_attr "type" "icmp")
1172 (set_attr "mode" "HI")])
1173
1174 (define_insn "*cmpqi_ccno_1"
1175 [(set (reg 17)
1176 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1177 (match_operand:QI 1 "const0_operand" "n,n")))]
1178 "ix86_match_ccmode (insn, CCNOmode)"
1179 "@
1180 test{b}\\t{%0, %0|%0, %0}
1181 cmp{b}\\t{$0, %0|%0, 0}"
1182 [(set_attr "type" "test,icmp")
1183 (set_attr "length_immediate" "0,1")
1184 (set_attr "mode" "QI")])
1185
1186 (define_insn "*cmpqi_1"
1187 [(set (reg 17)
1188 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1189 (match_operand:QI 1 "general_operand" "qi,mq")))]
1190 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1191 && ix86_match_ccmode (insn, CCmode)"
1192 "cmp{b}\\t{%1, %0|%0, %1}"
1193 [(set_attr "type" "icmp")
1194 (set_attr "mode" "QI")])
1195
1196 (define_insn "*cmpqi_minus_1"
1197 [(set (reg 17)
1198 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1199 (match_operand:QI 1 "general_operand" "qi,mq"))
1200 (const_int 0)))]
1201 "ix86_match_ccmode (insn, CCGOCmode)"
1202 "cmp{b}\\t{%1, %0|%0, %1}"
1203 [(set_attr "type" "icmp")
1204 (set_attr "mode" "QI")])
1205
1206 (define_insn "*cmpqi_ext_1"
1207 [(set (reg 17)
1208 (compare
1209 (match_operand:QI 0 "general_operand" "Qm")
1210 (subreg:QI
1211 (zero_extract:SI
1212 (match_operand 1 "ext_register_operand" "Q")
1213 (const_int 8)
1214 (const_int 8)) 0)))]
1215 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1216 "cmp{b}\\t{%h1, %0|%0, %h1}"
1217 [(set_attr "type" "icmp")
1218 (set_attr "mode" "QI")])
1219
1220 (define_insn "*cmpqi_ext_1_rex64"
1221 [(set (reg 17)
1222 (compare
1223 (match_operand:QI 0 "ext_register_operand" "Q")
1224 (subreg:QI
1225 (zero_extract:SI
1226 (match_operand 1 "ext_register_operand" "Q")
1227 (const_int 8)
1228 (const_int 8)) 0)))]
1229 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1230 "cmp{b}\\t{%h1, %0|%0, %h1}"
1231 [(set_attr "type" "icmp")
1232 (set_attr "mode" "QI")])
1233
1234 (define_insn "*cmpqi_ext_2"
1235 [(set (reg 17)
1236 (compare
1237 (subreg:QI
1238 (zero_extract:SI
1239 (match_operand 0 "ext_register_operand" "Q")
1240 (const_int 8)
1241 (const_int 8)) 0)
1242 (match_operand:QI 1 "const0_operand" "n")))]
1243 "ix86_match_ccmode (insn, CCNOmode)"
1244 "test{b}\\t%h0, %h0"
1245 [(set_attr "type" "test")
1246 (set_attr "length_immediate" "0")
1247 (set_attr "mode" "QI")])
1248
1249 (define_expand "cmpqi_ext_3"
1250 [(set (reg:CC 17)
1251 (compare:CC
1252 (subreg:QI
1253 (zero_extract:SI
1254 (match_operand 0 "ext_register_operand" "")
1255 (const_int 8)
1256 (const_int 8)) 0)
1257 (match_operand:QI 1 "general_operand" "")))]
1258 ""
1259 "")
1260
1261 (define_insn "cmpqi_ext_3_insn"
1262 [(set (reg 17)
1263 (compare
1264 (subreg:QI
1265 (zero_extract:SI
1266 (match_operand 0 "ext_register_operand" "Q")
1267 (const_int 8)
1268 (const_int 8)) 0)
1269 (match_operand:QI 1 "general_operand" "Qmn")))]
1270 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1271 "cmp{b}\\t{%1, %h0|%h0, %1}"
1272 [(set_attr "type" "icmp")
1273 (set_attr "mode" "QI")])
1274
1275 (define_insn "cmpqi_ext_3_insn_rex64"
1276 [(set (reg 17)
1277 (compare
1278 (subreg:QI
1279 (zero_extract:SI
1280 (match_operand 0 "ext_register_operand" "Q")
1281 (const_int 8)
1282 (const_int 8)) 0)
1283 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1284 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1285 "cmp{b}\\t{%1, %h0|%h0, %1}"
1286 [(set_attr "type" "icmp")
1287 (set_attr "mode" "QI")])
1288
1289 (define_insn "*cmpqi_ext_4"
1290 [(set (reg 17)
1291 (compare
1292 (subreg:QI
1293 (zero_extract:SI
1294 (match_operand 0 "ext_register_operand" "Q")
1295 (const_int 8)
1296 (const_int 8)) 0)
1297 (subreg:QI
1298 (zero_extract:SI
1299 (match_operand 1 "ext_register_operand" "Q")
1300 (const_int 8)
1301 (const_int 8)) 0)))]
1302 "ix86_match_ccmode (insn, CCmode)"
1303 "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1304 [(set_attr "type" "icmp")
1305 (set_attr "mode" "QI")])
1306
1307 ;; These implement float point compares.
1308 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1309 ;; which would allow mix and match FP modes on the compares. Which is what
1310 ;; the old patterns did, but with many more of them.
1311
1312 (define_expand "cmpxf"
1313 [(set (reg:CC 17)
1314 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1315 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1316 "TARGET_80387 && !TARGET_64BIT"
1317 "
1318 {
1319 ix86_compare_op0 = operands[0];
1320 ix86_compare_op1 = operands[1];
1321 DONE;
1322 }")
1323
1324 (define_expand "cmptf"
1325 [(set (reg:CC 17)
1326 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1327 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1328 "TARGET_80387"
1329 "
1330 {
1331 ix86_compare_op0 = operands[0];
1332 ix86_compare_op1 = operands[1];
1333 DONE;
1334 }")
1335
1336 (define_expand "cmpdf"
1337 [(set (reg:CC 17)
1338 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1339 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1340 "TARGET_80387 || TARGET_SSE2"
1341 "
1342 {
1343 ix86_compare_op0 = operands[0];
1344 ix86_compare_op1 = operands[1];
1345 DONE;
1346 }")
1347
1348 (define_expand "cmpsf"
1349 [(set (reg:CC 17)
1350 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1351 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1352 "TARGET_80387 || TARGET_SSE"
1353 "
1354 {
1355 ix86_compare_op0 = operands[0];
1356 ix86_compare_op1 = operands[1];
1357 DONE;
1358 }")
1359
1360 ;; FP compares, step 1:
1361 ;; Set the FP condition codes.
1362 ;;
1363 ;; CCFPmode compare with exceptions
1364 ;; CCFPUmode compare with no exceptions
1365
1366 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1367 ;; and that fp moves clobber the condition codes, and that there is
1368 ;; currently no way to describe this fact to reg-stack. So there are
1369 ;; no splitters yet for this.
1370
1371 ;; %%% YIKES! This scheme does not retain a strong connection between
1372 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1373 ;; work! Only allow tos/mem with tos in op 0.
1374 ;;
1375 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1376 ;; things aren't as bad as they sound...
1377
1378 (define_insn "*cmpfp_0"
1379 [(set (match_operand:HI 0 "register_operand" "=a")
1380 (unspec:HI
1381 [(compare:CCFP (match_operand 1 "register_operand" "f")
1382 (match_operand 2 "const0_operand" "X"))] 9))]
1383 "TARGET_80387
1384 && FLOAT_MODE_P (GET_MODE (operands[1]))
1385 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1386 "*
1387 {
1388 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1389 return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1390 else
1391 return \"ftst\;fnstsw\\t%0\";
1392 }"
1393 [(set_attr "type" "multi")
1394 (set_attr "mode" "unknownfp")])
1395
1396 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1397 ;; used to manage the reg stack popping would not be preserved.
1398
1399 (define_insn "*cmpfp_2_sf"
1400 [(set (reg:CCFP 18)
1401 (compare:CCFP
1402 (match_operand:SF 0 "register_operand" "f")
1403 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1404 "TARGET_80387"
1405 "* return output_fp_compare (insn, operands, 0, 0);"
1406 [(set_attr "type" "fcmp")
1407 (set_attr "mode" "SF")])
1408
1409 (define_insn "*cmpfp_2_sf_1"
1410 [(set (match_operand:HI 0 "register_operand" "=a")
1411 (unspec:HI
1412 [(compare:CCFP
1413 (match_operand:SF 1 "register_operand" "f")
1414 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1415 "TARGET_80387"
1416 "* return output_fp_compare (insn, operands, 2, 0);"
1417 [(set_attr "type" "fcmp")
1418 (set_attr "mode" "SF")])
1419
1420 (define_insn "*cmpfp_2_df"
1421 [(set (reg:CCFP 18)
1422 (compare:CCFP
1423 (match_operand:DF 0 "register_operand" "f")
1424 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1425 "TARGET_80387"
1426 "* return output_fp_compare (insn, operands, 0, 0);"
1427 [(set_attr "type" "fcmp")
1428 (set_attr "mode" "DF")])
1429
1430 (define_insn "*cmpfp_2_df_1"
1431 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (unspec:HI
1433 [(compare:CCFP
1434 (match_operand:DF 1 "register_operand" "f")
1435 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1436 "TARGET_80387"
1437 "* return output_fp_compare (insn, operands, 2, 0);"
1438 [(set_attr "type" "multi")
1439 (set_attr "mode" "DF")])
1440
1441 (define_insn "*cmpfp_2_xf"
1442 [(set (reg:CCFP 18)
1443 (compare:CCFP
1444 (match_operand:XF 0 "register_operand" "f")
1445 (match_operand:XF 1 "register_operand" "f")))]
1446 "TARGET_80387 && !TARGET_64BIT"
1447 "* return output_fp_compare (insn, operands, 0, 0);"
1448 [(set_attr "type" "fcmp")
1449 (set_attr "mode" "XF")])
1450
1451 (define_insn "*cmpfp_2_tf"
1452 [(set (reg:CCFP 18)
1453 (compare:CCFP
1454 (match_operand:TF 0 "register_operand" "f")
1455 (match_operand:TF 1 "register_operand" "f")))]
1456 "TARGET_80387"
1457 "* return output_fp_compare (insn, operands, 0, 0);"
1458 [(set_attr "type" "fcmp")
1459 (set_attr "mode" "XF")])
1460
1461 (define_insn "*cmpfp_2_xf_1"
1462 [(set (match_operand:HI 0 "register_operand" "=a")
1463 (unspec:HI
1464 [(compare:CCFP
1465 (match_operand:XF 1 "register_operand" "f")
1466 (match_operand:XF 2 "register_operand" "f"))] 9))]
1467 "TARGET_80387 && !TARGET_64BIT"
1468 "* return output_fp_compare (insn, operands, 2, 0);"
1469 [(set_attr "type" "multi")
1470 (set_attr "mode" "XF")])
1471
1472 (define_insn "*cmpfp_2_tf_1"
1473 [(set (match_operand:HI 0 "register_operand" "=a")
1474 (unspec:HI
1475 [(compare:CCFP
1476 (match_operand:TF 1 "register_operand" "f")
1477 (match_operand:TF 2 "register_operand" "f"))] 9))]
1478 "TARGET_80387"
1479 "* return output_fp_compare (insn, operands, 2, 0);"
1480 [(set_attr "type" "multi")
1481 (set_attr "mode" "XF")])
1482
1483 (define_insn "*cmpfp_2u"
1484 [(set (reg:CCFPU 18)
1485 (compare:CCFPU
1486 (match_operand 0 "register_operand" "f")
1487 (match_operand 1 "register_operand" "f")))]
1488 "TARGET_80387
1489 && FLOAT_MODE_P (GET_MODE (operands[0]))
1490 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1491 "* return output_fp_compare (insn, operands, 0, 1);"
1492 [(set_attr "type" "fcmp")
1493 (set_attr "mode" "unknownfp")])
1494
1495 (define_insn "*cmpfp_2u_1"
1496 [(set (match_operand:HI 0 "register_operand" "=a")
1497 (unspec:HI
1498 [(compare:CCFPU
1499 (match_operand 1 "register_operand" "f")
1500 (match_operand 2 "register_operand" "f"))] 9))]
1501 "TARGET_80387
1502 && FLOAT_MODE_P (GET_MODE (operands[1]))
1503 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1504 "* return output_fp_compare (insn, operands, 2, 1);"
1505 [(set_attr "type" "multi")
1506 (set_attr "mode" "unknownfp")])
1507
1508 ;; Patterns to match the SImode-in-memory ficom instructions.
1509 ;;
1510 ;; %%% Play games with accepting gp registers, as otherwise we have to
1511 ;; force them to memory during rtl generation, which is no good. We
1512 ;; can get rid of this once we teach reload to do memory input reloads
1513 ;; via pushes.
1514
1515 (define_insn "*ficom_1"
1516 [(set (reg:CCFP 18)
1517 (compare:CCFP
1518 (match_operand 0 "register_operand" "f,f")
1519 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1520 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1522 "#")
1523
1524 ;; Split the not-really-implemented gp register case into a
1525 ;; push-op-pop sequence.
1526 ;;
1527 ;; %%% This is most efficient, but am I gonna get in trouble
1528 ;; for separating cc0_setter and cc0_user?
1529
1530 (define_split
1531 [(set (reg:CCFP 18)
1532 (compare:CCFP
1533 (match_operand:SF 0 "register_operand" "")
1534 (float (match_operand:SI 1 "register_operand" ""))))]
1535 "0 && TARGET_80387 && reload_completed"
1536 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1537 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1538 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1539 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1540 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1541 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1542
1543 ;; FP compares, step 2
1544 ;; Move the fpsw to ax.
1545
1546 (define_insn "x86_fnstsw_1"
1547 [(set (match_operand:HI 0 "register_operand" "=a")
1548 (unspec:HI [(reg 18)] 9))]
1549 "TARGET_80387"
1550 "fnstsw\\t%0"
1551 [(set_attr "length" "2")
1552 (set_attr "mode" "SI")
1553 (set_attr "i387" "1")
1554 (set_attr "ppro_uops" "few")])
1555
1556 ;; FP compares, step 3
1557 ;; Get ax into flags, general case.
1558
1559 (define_insn "x86_sahf_1"
1560 [(set (reg:CC 17)
1561 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1562 "!TARGET_64BIT"
1563 "sahf"
1564 [(set_attr "length" "1")
1565 (set_attr "athlon_decode" "vector")
1566 (set_attr "mode" "SI")
1567 (set_attr "ppro_uops" "one")])
1568
1569 ;; Pentium Pro can do steps 1 through 3 in one go.
1570
1571 (define_insn "*cmpfp_i"
1572 [(set (reg:CCFP 17)
1573 (compare:CCFP (match_operand 0 "register_operand" "f")
1574 (match_operand 1 "register_operand" "f")))]
1575 "TARGET_80387 && TARGET_CMOVE
1576 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1577 && FLOAT_MODE_P (GET_MODE (operands[0]))
1578 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1579 "* return output_fp_compare (insn, operands, 1, 0);"
1580 [(set_attr "type" "fcmp")
1581 (set_attr "mode" "unknownfp")
1582 (set_attr "athlon_decode" "vector")])
1583
1584 (define_insn "*cmpfp_i_sse"
1585 [(set (reg:CCFP 17)
1586 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1587 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1588 "TARGET_80387
1589 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1590 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1591 "* return output_fp_compare (insn, operands, 1, 0);"
1592 [(set_attr "type" "fcmp,sse")
1593 (set_attr "mode" "unknownfp")
1594 (set_attr "athlon_decode" "vector")])
1595
1596 (define_insn "*cmpfp_i_sse_only"
1597 [(set (reg:CCFP 17)
1598 (compare:CCFP (match_operand 0 "register_operand" "x")
1599 (match_operand 1 "nonimmediate_operand" "xm")))]
1600 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1601 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1602 "* return output_fp_compare (insn, operands, 1, 0);"
1603 [(set_attr "type" "sse")
1604 (set_attr "mode" "unknownfp")
1605 (set_attr "athlon_decode" "vector")])
1606
1607 (define_insn "*cmpfp_iu"
1608 [(set (reg:CCFPU 17)
1609 (compare:CCFPU (match_operand 0 "register_operand" "f")
1610 (match_operand 1 "register_operand" "f")))]
1611 "TARGET_80387 && TARGET_CMOVE
1612 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1613 && FLOAT_MODE_P (GET_MODE (operands[0]))
1614 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1615 "* return output_fp_compare (insn, operands, 1, 1);"
1616 [(set_attr "type" "fcmp")
1617 (set_attr "mode" "unknownfp")
1618 (set_attr "athlon_decode" "vector")])
1619
1620 (define_insn "*cmpfp_iu_sse"
1621 [(set (reg:CCFPU 17)
1622 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1623 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1624 "TARGET_80387
1625 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1626 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1627 "* return output_fp_compare (insn, operands, 1, 1);"
1628 [(set_attr "type" "fcmp,sse")
1629 (set_attr "mode" "unknownfp")
1630 (set_attr "athlon_decode" "vector")])
1631
1632 (define_insn "*cmpfp_iu_sse_only"
1633 [(set (reg:CCFPU 17)
1634 (compare:CCFPU (match_operand 0 "register_operand" "x")
1635 (match_operand 1 "nonimmediate_operand" "xm")))]
1636 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1637 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1638 "* return output_fp_compare (insn, operands, 1, 1);"
1639 [(set_attr "type" "sse")
1640 (set_attr "mode" "unknownfp")
1641 (set_attr "athlon_decode" "vector")])
1642 \f
1643 ;; Move instructions.
1644
1645 ;; General case of fullword move.
1646
1647 (define_expand "movsi"
1648 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1649 (match_operand:SI 1 "general_operand" ""))]
1650 ""
1651 "ix86_expand_move (SImode, operands); DONE;")
1652
1653 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1654 ;; general_operand.
1655 ;;
1656 ;; %%% We don't use a post-inc memory reference because x86 is not a
1657 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1658 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1659 ;; targets without our curiosities, and it is just as easy to represent
1660 ;; this differently.
1661
1662 (define_insn "*pushsi2"
1663 [(set (match_operand:SI 0 "push_operand" "=<")
1664 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1665 "!TARGET_64BIT"
1666 "push{l}\\t%1"
1667 [(set_attr "type" "push")
1668 (set_attr "mode" "SI")])
1669
1670 ;; For 64BIT abi we always round up to 8 bytes.
1671 (define_insn "*pushsi2_rex64"
1672 [(set (match_operand:SI 0 "push_operand" "=X")
1673 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1674 "TARGET_64BIT"
1675 "push{q}\\t%q1"
1676 [(set_attr "type" "push")
1677 (set_attr "mode" "SI")])
1678
1679 (define_insn "*pushsi2_prologue"
1680 [(set (match_operand:SI 0 "push_operand" "=<")
1681 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1682 (set (reg:SI 6) (reg:SI 6))]
1683 "!TARGET_64BIT"
1684 "push{l}\\t%1"
1685 [(set_attr "type" "push")
1686 (set_attr "mode" "SI")])
1687
1688 (define_insn "*popsi1_epilogue"
1689 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1690 (mem:SI (reg:SI 7)))
1691 (set (reg:SI 7)
1692 (plus:SI (reg:SI 7) (const_int 4)))
1693 (set (reg:SI 6) (reg:SI 6))]
1694 "!TARGET_64BIT"
1695 "pop{l}\\t%0"
1696 [(set_attr "type" "pop")
1697 (set_attr "mode" "SI")])
1698
1699 (define_insn "popsi1"
1700 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1701 (mem:SI (reg:SI 7)))
1702 (set (reg:SI 7)
1703 (plus:SI (reg:SI 7) (const_int 4)))]
1704 "!TARGET_64BIT"
1705 "pop{l}\\t%0"
1706 [(set_attr "type" "pop")
1707 (set_attr "mode" "SI")])
1708
1709 (define_insn "*movsi_xor"
1710 [(set (match_operand:SI 0 "register_operand" "=r")
1711 (match_operand:SI 1 "const0_operand" "i"))
1712 (clobber (reg:CC 17))]
1713 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1714 "xor{l}\\t{%0, %0|%0, %0}"
1715 [(set_attr "type" "alu1")
1716 (set_attr "mode" "SI")
1717 (set_attr "length_immediate" "0")])
1718
1719 (define_insn "*movsi_or"
1720 [(set (match_operand:SI 0 "register_operand" "=r")
1721 (match_operand:SI 1 "immediate_operand" "i"))
1722 (clobber (reg:CC 17))]
1723 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1724 && INTVAL (operands[1]) == -1
1725 && (TARGET_PENTIUM || optimize_size)"
1726 "*
1727 {
1728 operands[1] = constm1_rtx;
1729 return \"or{l}\\t{%1, %0|%0, %1}\";
1730 }"
1731 [(set_attr "type" "alu1")
1732 (set_attr "mode" "SI")
1733 (set_attr "length_immediate" "1")])
1734
1735 (define_insn "*movsi_1"
1736 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!r")
1737 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,r,*y"))]
1738 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1739 "*
1740 {
1741 switch (get_attr_type (insn))
1742 {
1743 case TYPE_MMX:
1744 return \"movd\\t{%1, %0|%0, %1}\";
1745
1746 case TYPE_LEA:
1747 return \"lea{l}\\t{%1, %0|%0, %1}\";
1748
1749 default:
1750 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1751 abort();
1752 return \"mov{l}\\t{%1, %0|%0, %1}\";
1753 }
1754 }"
1755 [(set (attr "type")
1756 (cond [(ior (match_operand:SI 0 "mmx_reg_operand" "")
1757 (match_operand:SI 1 "mmx_reg_operand" ""))
1758 (const_string "mmx")
1759 (and (ne (symbol_ref "flag_pic") (const_int 0))
1760 (match_operand:SI 1 "symbolic_operand" ""))
1761 (const_string "lea")
1762 ]
1763 (const_string "imov")))
1764 (set_attr "modrm" "0,*,0,*,*,*")
1765 (set_attr "mode" "SI")])
1766
1767 ;; Stores and loads of ax to arbitary constant address.
1768 ;; We fake an second form of instruction to force reload to load address
1769 ;; into register when rax is not available
1770 (define_insn "*movabssi_1_rex64"
1771 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1772 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1773 "TARGET_64BIT"
1774 "@
1775 movabs{l}\\t{%1, %P0|%P0, %1}
1776 mov{l}\\t{%1, %a0|%a0, %1}
1777 movabs{l}\\t{%1, %a0|%a0, %1}"
1778 [(set_attr "type" "imov")
1779 (set_attr "modrm" "0,*,*")
1780 (set_attr "length_address" "8,0,0")
1781 (set_attr "length_immediate" "0,*,*")
1782 (set_attr "memory" "store")
1783 (set_attr "mode" "SI")])
1784
1785 (define_insn "*movabssi_2_rex64"
1786 [(set (match_operand:SI 0 "register_operand" "=a,r")
1787 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1788 "TARGET_64BIT"
1789 "@
1790 movabs{l}\\t{%P1, %0|%0, %P1}
1791 mov{l}\\t{%a1, %0|%0, %a1}"
1792 [(set_attr "type" "imov")
1793 (set_attr "modrm" "0,*")
1794 (set_attr "length_address" "8,0")
1795 (set_attr "length_immediate" "0")
1796 (set_attr "memory" "load")
1797 (set_attr "mode" "SI")])
1798
1799 (define_insn "*swapsi"
1800 [(set (match_operand:SI 0 "register_operand" "+r")
1801 (match_operand:SI 1 "register_operand" "+r"))
1802 (set (match_dup 1)
1803 (match_dup 0))]
1804 ""
1805 "xchg{l}\\t%1, %0"
1806 [(set_attr "type" "imov")
1807 (set_attr "pent_pair" "np")
1808 (set_attr "athlon_decode" "vector")
1809 (set_attr "mode" "SI")
1810 (set_attr "modrm" "0")
1811 (set_attr "ppro_uops" "few")])
1812
1813 (define_expand "movhi"
1814 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1815 (match_operand:HI 1 "general_operand" ""))]
1816 ""
1817 "ix86_expand_move (HImode, operands); DONE;")
1818
1819 (define_insn "*pushhi2"
1820 [(set (match_operand:HI 0 "push_operand" "=<,<")
1821 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1822 "!TARGET_64BIT"
1823 "@
1824 push{w}\\t{|WORD PTR }%1
1825 push{w}\\t%1"
1826 [(set_attr "type" "push")
1827 (set_attr "mode" "HI")])
1828
1829 (define_insn "*movhi_1"
1830 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1831 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1832 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1833 "*
1834 {
1835 switch (get_attr_type (insn))
1836 {
1837 case TYPE_IMOVX:
1838 /* movzwl is faster than movw on p2 due to partial word stalls,
1839 though not as fast as an aligned movl. */
1840 return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1841 default:
1842 if (get_attr_mode (insn) == MODE_SI)
1843 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1844 else
1845 return \"mov{w}\\t{%1, %0|%0, %1}\";
1846 }
1847 }"
1848 [(set (attr "type")
1849 (cond [(and (eq_attr "alternative" "0,1")
1850 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1851 (const_int 0))
1852 (eq (symbol_ref "TARGET_HIMODE_MATH")
1853 (const_int 0))))
1854 (const_string "imov")
1855 (and (eq_attr "alternative" "2,3,4")
1856 (match_operand:HI 1 "aligned_operand" ""))
1857 (const_string "imov")
1858 (and (ne (symbol_ref "TARGET_MOVX")
1859 (const_int 0))
1860 (eq_attr "alternative" "0,1,3,4"))
1861 (const_string "imovx")
1862 ]
1863 (const_string "imov")))
1864 (set (attr "mode")
1865 (cond [(eq_attr "type" "imovx")
1866 (const_string "SI")
1867 (and (eq_attr "alternative" "2,3,4")
1868 (match_operand:HI 1 "aligned_operand" ""))
1869 (const_string "SI")
1870 (and (eq_attr "alternative" "0,1")
1871 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1872 (const_int 0))
1873 (eq (symbol_ref "TARGET_HIMODE_MATH")
1874 (const_int 0))))
1875 (const_string "SI")
1876 ]
1877 (const_string "HI")))
1878 (set_attr "modrm" "0,*,*,0,*,*")])
1879
1880 ;; Stores and loads of ax to arbitary constant address.
1881 ;; We fake an second form of instruction to force reload to load address
1882 ;; into register when rax is not available
1883 (define_insn "*movabshi_1_rex64"
1884 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1885 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1886 "TARGET_64BIT"
1887 "@
1888 movabs{w}\\t{%1, %P0|%P0, %1}
1889 mov{w}\\t{%1, %a0|%a0, %1}
1890 movabs{w}\\t{%1, %a0|%a0, %1}"
1891 [(set_attr "type" "imov")
1892 (set_attr "modrm" "0,*,*")
1893 (set_attr "length_address" "8,0,0")
1894 (set_attr "length_immediate" "0,*,*")
1895 (set_attr "memory" "store")
1896 (set_attr "mode" "HI")])
1897
1898 (define_insn "*movabshi_2_rex64"
1899 [(set (match_operand:HI 0 "register_operand" "=a,r")
1900 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1901 "TARGET_64BIT"
1902 "@
1903 movabs{w}\\t{%P1, %0|%0, %P1}
1904 mov{w}\\t{%a1, %0|%0, %a1}"
1905 [(set_attr "type" "imov")
1906 (set_attr "modrm" "0,*")
1907 (set_attr "length_address" "8,0")
1908 (set_attr "length_immediate" "0")
1909 (set_attr "memory" "load")
1910 (set_attr "mode" "HI")])
1911
1912 (define_insn "*swaphi_1"
1913 [(set (match_operand:HI 0 "register_operand" "+r")
1914 (match_operand:HI 1 "register_operand" "+r"))
1915 (set (match_dup 1)
1916 (match_dup 0))]
1917 "TARGET_PARTIAL_REG_STALL"
1918 "xchg{w}\\t%1, %0"
1919 [(set_attr "type" "imov")
1920 (set_attr "pent_pair" "np")
1921 (set_attr "mode" "HI")
1922 (set_attr "modrm" "0")
1923 (set_attr "ppro_uops" "few")])
1924
1925 (define_insn "*swaphi_2"
1926 [(set (match_operand:HI 0 "register_operand" "+r")
1927 (match_operand:HI 1 "register_operand" "+r"))
1928 (set (match_dup 1)
1929 (match_dup 0))]
1930 "! TARGET_PARTIAL_REG_STALL"
1931 "xchg{l}\\t%k1, %k0"
1932 [(set_attr "type" "imov")
1933 (set_attr "pent_pair" "np")
1934 (set_attr "mode" "SI")
1935 (set_attr "modrm" "0")
1936 (set_attr "ppro_uops" "few")])
1937
1938 (define_expand "movstricthi"
1939 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1940 (match_operand:HI 1 "general_operand" ""))]
1941 "! TARGET_PARTIAL_REG_STALL"
1942 "
1943 {
1944 /* Don't generate memory->memory moves, go through a register */
1945 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1946 operands[1] = force_reg (HImode, operands[1]);
1947 }")
1948
1949 (define_insn "*movstricthi_1"
1950 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1951 (match_operand:HI 1 "general_operand" "rn,m"))]
1952 "! TARGET_PARTIAL_REG_STALL
1953 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1954 "mov{w}\\t{%1, %0|%0, %1}"
1955 [(set_attr "type" "imov")
1956 (set_attr "mode" "HI")])
1957
1958 (define_insn "*movstricthi_xor"
1959 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1960 (match_operand:HI 1 "const0_operand" "i"))
1961 (clobber (reg:CC 17))]
1962 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1963 "xor{w}\\t{%0, %0|%0, %0}"
1964 [(set_attr "type" "alu1")
1965 (set_attr "mode" "HI")
1966 (set_attr "length_immediate" "0")])
1967
1968 (define_expand "movqi"
1969 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1970 (match_operand:QI 1 "general_operand" ""))]
1971 ""
1972 "ix86_expand_move (QImode, operands); DONE;")
1973
1974 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1975 ;; "push a byte". But actually we use pushw, which has the effect
1976 ;; of rounding the amount pushed up to a halfword.
1977
1978 (define_insn "*pushqi2"
1979 [(set (match_operand:QI 0 "push_operand" "=X,X")
1980 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1981 "!TARGET_64BIT"
1982 "@
1983 push{w}\\t{|word ptr }%1
1984 push{w}\\t%w1"
1985 [(set_attr "type" "push")
1986 (set_attr "mode" "HI")])
1987
1988 ;; Situation is quite tricky about when to choose full sized (SImode) move
1989 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1990 ;; partial register dependency machines (such as AMD Athlon), where QImode
1991 ;; moves issue extra dependency and for partial register stalls machines
1992 ;; that don't use QImode patterns (and QImode move cause stall on the next
1993 ;; instruction).
1994 ;;
1995 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1996 ;; register stall machines with, where we use QImode instructions, since
1997 ;; partial register stall can be caused there. Then we use movzx.
1998 (define_insn "*movqi_1"
1999 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2000 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2001 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2002 "*
2003 {
2004 switch (get_attr_type (insn))
2005 {
2006 case TYPE_IMOVX:
2007 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
2008 abort ();
2009 return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
2010 default:
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
2013 else
2014 return \"mov{b}\\t{%1, %0|%0, %1}\";
2015 }
2016 }"
2017 [(set (attr "type")
2018 (cond [(and (eq_attr "alternative" "3")
2019 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2020 (const_int 0))
2021 (eq (symbol_ref "TARGET_QIMODE_MATH")
2022 (const_int 0))))
2023 (const_string "imov")
2024 (eq_attr "alternative" "3,5")
2025 (const_string "imovx")
2026 (and (ne (symbol_ref "TARGET_MOVX")
2027 (const_int 0))
2028 (eq_attr "alternative" "2"))
2029 (const_string "imovx")
2030 ]
2031 (const_string "imov")))
2032 (set (attr "mode")
2033 (cond [(eq_attr "alternative" "3,4,5")
2034 (const_string "SI")
2035 (eq_attr "alternative" "6")
2036 (const_string "QI")
2037 (eq_attr "type" "imovx")
2038 (const_string "SI")
2039 (and (eq_attr "type" "imov")
2040 (and (eq_attr "alternative" "0,1,2")
2041 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2042 (const_int 0))))
2043 (const_string "SI")
2044 ;; Avoid partial register stalls when not using QImode arithmetic
2045 (and (eq_attr "type" "imov")
2046 (and (eq_attr "alternative" "0,1,2")
2047 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2048 (const_int 0))
2049 (eq (symbol_ref "TARGET_QIMODE_MATH")
2050 (const_int 0)))))
2051 (const_string "SI")
2052 ]
2053 (const_string "QI")))])
2054
2055 (define_expand "reload_outqi"
2056 [(parallel [(match_operand:QI 0 "" "=m")
2057 (match_operand:QI 1 "register_operand" "r")
2058 (match_operand:QI 2 "register_operand" "=&q")])]
2059 ""
2060 "
2061 {
2062 rtx op0, op1, op2;
2063 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
2064
2065 if (reg_overlap_mentioned_p (op2, op0))
2066 abort ();
2067 if (! q_regs_operand (op1, QImode))
2068 {
2069 emit_insn (gen_movqi (op2, op1));
2070 op1 = op2;
2071 }
2072 emit_insn (gen_movqi (op0, op1));
2073 DONE;
2074 }")
2075
2076 (define_insn "*swapqi"
2077 [(set (match_operand:QI 0 "register_operand" "+r")
2078 (match_operand:QI 1 "register_operand" "+r"))
2079 (set (match_dup 1)
2080 (match_dup 0))]
2081 ""
2082 "xchg{b}\\t%1, %0"
2083 [(set_attr "type" "imov")
2084 (set_attr "pent_pair" "np")
2085 (set_attr "mode" "QI")
2086 (set_attr "modrm" "0")
2087 (set_attr "ppro_uops" "few")])
2088
2089 (define_expand "movstrictqi"
2090 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2091 (match_operand:QI 1 "general_operand" ""))]
2092 "! TARGET_PARTIAL_REG_STALL"
2093 "
2094 {
2095 /* Don't generate memory->memory moves, go through a register */
2096 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
2097 operands[1] = force_reg (QImode, operands[1]);
2098 }")
2099
2100 (define_insn "*movstrictqi_1"
2101 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2102 (match_operand:QI 1 "general_operand" "*qn,m"))]
2103 "! TARGET_PARTIAL_REG_STALL
2104 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2105 "mov{b}\\t{%1, %0|%0, %1}"
2106 [(set_attr "type" "imov")
2107 (set_attr "mode" "QI")])
2108
2109 (define_insn "*movstrictqi_xor"
2110 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2111 (match_operand:QI 1 "const0_operand" "i"))
2112 (clobber (reg:CC 17))]
2113 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
2114 "xor{b}\\t{%0, %0|%0, %0}"
2115 [(set_attr "type" "alu1")
2116 (set_attr "mode" "QI")
2117 (set_attr "length_immediate" "0")])
2118
2119 (define_insn "*movsi_extv_1"
2120 [(set (match_operand:SI 0 "register_operand" "=R")
2121 (sign_extract:SI (match_operand:SI 1 "ext_register_operand" "Q")
2122 (const_int 8)
2123 (const_int 8)))]
2124 ""
2125 "movs{bl|x}\\t{%h1, %0|%0, %h1}"
2126 [(set_attr "type" "imovx")
2127 (set_attr "mode" "SI")])
2128
2129 (define_insn "*movhi_extv_1"
2130 [(set (match_operand:HI 0 "register_operand" "=R")
2131 (sign_extract:HI (match_operand:SI 1 "ext_register_operand" "Q")
2132 (const_int 8)
2133 (const_int 8)))]
2134 ""
2135 "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
2136 [(set_attr "type" "imovx")
2137 (set_attr "mode" "SI")])
2138
2139 (define_insn "*movqi_extv_1"
2140 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2141 (sign_extract:QI (match_operand:SI 1 "ext_register_operand" "Q,Q")
2142 (const_int 8)
2143 (const_int 8)))]
2144 "!TARGET_64BIT"
2145 "*
2146 {
2147 switch (get_attr_type (insn))
2148 {
2149 case TYPE_IMOVX:
2150 return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2151 default:
2152 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2153 }
2154 }"
2155 [(set (attr "type")
2156 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2157 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2158 (ne (symbol_ref "TARGET_MOVX")
2159 (const_int 0))))
2160 (const_string "imovx")
2161 (const_string "imov")))
2162 (set (attr "mode")
2163 (if_then_else (eq_attr "type" "imovx")
2164 (const_string "SI")
2165 (const_string "QI")))])
2166
2167 (define_insn "*movqi_extv_1_rex64"
2168 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2169 (sign_extract:QI (match_operand:SI 1 "ext_register_operand" "Q,Q")
2170 (const_int 8)
2171 (const_int 8)))]
2172 "TARGET_64BIT"
2173 "*
2174 {
2175 switch (get_attr_type (insn))
2176 {
2177 case TYPE_IMOVX:
2178 return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2179 default:
2180 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2181 }
2182 }"
2183 [(set (attr "type")
2184 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2185 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2186 (ne (symbol_ref "TARGET_MOVX")
2187 (const_int 0))))
2188 (const_string "imovx")
2189 (const_string "imov")))
2190 (set (attr "mode")
2191 (if_then_else (eq_attr "type" "imovx")
2192 (const_string "SI")
2193 (const_string "QI")))])
2194
2195 ;; Stores and loads of ax to arbitary constant address.
2196 ;; We fake an second form of instruction to force reload to load address
2197 ;; into register when rax is not available
2198 (define_insn "*movabsqi_1_rex64"
2199 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2200 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
2201 "TARGET_64BIT"
2202 "@
2203 movabs{q}\\t{%1, %P0|%P0, %1}
2204 mov{q}\\t{%1, %a0|%a0, %1}
2205 movabs{q}\\t{%1, %a0|%a0, %1}"
2206 [(set_attr "type" "imov")
2207 (set_attr "modrm" "0,*,*")
2208 (set_attr "length_address" "8,0,0")
2209 (set_attr "length_immediate" "0,*,*")
2210 (set_attr "memory" "store")
2211 (set_attr "mode" "QI")])
2212
2213 (define_insn "*movabsqi_2_rex64"
2214 [(set (match_operand:QI 0 "register_operand" "=a,r")
2215 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2216 "TARGET_64BIT"
2217 "@
2218 movabs{q}\\t{%P1, %0|%0, %P1}
2219 mov{q}\\t{%a1, %0|%0, %a1}"
2220 [(set_attr "type" "imov")
2221 (set_attr "modrm" "0,*")
2222 (set_attr "length_address" "8,0")
2223 (set_attr "length_immediate" "0")
2224 (set_attr "memory" "load")
2225 (set_attr "mode" "QI")])
2226
2227 (define_insn "*movsi_extzv_1"
2228 [(set (match_operand:SI 0 "register_operand" "=R")
2229 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2230 (const_int 8)
2231 (const_int 8)))]
2232 ""
2233 "movz{bl|x}\\t{%h1, %0|%0, %h1}"
2234 [(set_attr "type" "imovx")
2235 (set_attr "mode" "SI")])
2236
2237 (define_insn "*movqi_extzv_2"
2238 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2239 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2240 (const_int 8)
2241 (const_int 8)) 0))]
2242 "!TARGET_64BIT"
2243 "*
2244 {
2245 switch (get_attr_type (insn))
2246 {
2247 case TYPE_IMOVX:
2248 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2249 default:
2250 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2251 }
2252 }"
2253 [(set (attr "type")
2254 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2255 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2256 (ne (symbol_ref "TARGET_MOVX")
2257 (const_int 0))))
2258 (const_string "imovx")
2259 (const_string "imov")))
2260 (set (attr "mode")
2261 (if_then_else (eq_attr "type" "imovx")
2262 (const_string "SI")
2263 (const_string "QI")))])
2264
2265 (define_insn "*movqi_extzv_2_rex64"
2266 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2267 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2268 (const_int 8)
2269 (const_int 8)) 0))]
2270 "TARGET_64BIT"
2271 "*
2272 {
2273 switch (get_attr_type (insn))
2274 {
2275 case TYPE_IMOVX:
2276 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2277 default:
2278 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2279 }
2280 }"
2281 [(set (attr "type")
2282 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2283 (ne (symbol_ref "TARGET_MOVX")
2284 (const_int 0)))
2285 (const_string "imovx")
2286 (const_string "imov")))
2287 (set (attr "mode")
2288 (if_then_else (eq_attr "type" "imovx")
2289 (const_string "SI")
2290 (const_string "QI")))])
2291
2292 (define_insn "*movsi_insv_1"
2293 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2294 (const_int 8)
2295 (const_int 8))
2296 (match_operand:SI 1 "nonimmediate_operand" "Qm"))]
2297 "!TARGET_64BIT"
2298 "mov{b}\\t{%b1, %h0|%h0, %b1}"
2299 [(set_attr "type" "imov")
2300 (set_attr "mode" "QI")])
2301
2302 (define_insn "*movsi_insv_1_rex64"
2303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2304 (const_int 8)
2305 (const_int 8))
2306 (match_operand:SI 1 "ext_register_operand" "Q"))]
2307 "TARGET_64BIT"
2308 "mov{b}\\t{%b1, %h0|%h0, %b1}"
2309 [(set_attr "type" "imov")
2310 (set_attr "mode" "QI")])
2311
2312 (define_insn "*movqi_insv_2"
2313 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2314 (const_int 8)
2315 (const_int 8))
2316 (and:SI (lshiftrt:SI (match_operand:SI 1 "ext_register_operand" "Q")
2317 (const_int 8))
2318 (const_int 255)))]
2319 ""
2320 "mov{b}\\t{%h1, %h0|%h0, %h1}"
2321 [(set_attr "type" "imov")
2322 (set_attr "mode" "QI")])
2323
2324 (define_expand "movdi"
2325 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2326 (match_operand:DI 1 "general_operand" ""))]
2327 ""
2328 "ix86_expand_move (DImode, operands); DONE;")
2329
2330 (define_insn "*pushdi"
2331 [(set (match_operand:DI 0 "push_operand" "=<")
2332 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2333 "!TARGET_64BIT"
2334 "#")
2335
2336 (define_insn "pushdi2_rex64"
2337 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2338 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2339 "TARGET_64BIT"
2340 "@
2341 push{q}\\t%1
2342 #"
2343 [(set_attr "type" "push,multi")
2344 (set_attr "mode" "DI")])
2345
2346 ;; Convert impossible pushes of immediate to existing instructions.
2347 ;; First try to get scratch register and go trought it. In case this
2348 ;; fails, push sign extended lower part first and then overwrite
2349 ;; upper part by 32bit move.
2350 (define_peephole2
2351 [(match_scratch:DI 2 "r")
2352 (set (match_operand:DI 0 "push_operand" "")
2353 (match_operand:DI 1 "immediate_operand" ""))]
2354 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2355 && !x86_64_immediate_operand (operands[1], DImode)"
2356 [(set (match_dup 2) (match_dup 1))
2357 (set (match_dup 0) (match_dup 2))]
2358 "")
2359
2360 ;; We need to define this as both peepholer and splitter for case
2361 ;; peephole2 pass is not run.
2362 (define_peephole2
2363 [(set (match_operand:DI 0 "push_operand" "")
2364 (match_operand:DI 1 "immediate_operand" ""))]
2365 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2366 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2367 [(set (match_dup 0) (match_dup 1))
2368 (set (match_dup 2) (match_dup 3))]
2369 "split_di (operands + 1, 1, operands + 2, operands + 3);
2370 operands[1] = gen_lowpart (DImode, operands[2]);
2371 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2372 GEN_INT (4)));
2373 ")
2374
2375 (define_split
2376 [(set (match_operand:DI 0 "push_operand" "")
2377 (match_operand:DI 1 "immediate_operand" ""))]
2378 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2379 && !symbolic_operand (operands[1], DImode)
2380 && !x86_64_immediate_operand (operands[1], DImode)"
2381 [(set (match_dup 0) (match_dup 1))
2382 (set (match_dup 2) (match_dup 3))]
2383 "split_di (operands + 1, 1, operands + 2, operands + 3);
2384 operands[1] = gen_lowpart (DImode, operands[2]);
2385 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2386 GEN_INT (4)));
2387 ")
2388
2389 (define_insn "*pushdi2_prologue_rex64"
2390 [(set (match_operand:DI 0 "push_operand" "=<")
2391 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2392 (set (reg:DI 6) (reg:DI 6))]
2393 "TARGET_64BIT"
2394 "push{q}\\t%1"
2395 [(set_attr "type" "push")
2396 (set_attr "mode" "DI")])
2397
2398 (define_insn "*popdi1_epilogue_rex64"
2399 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2400 (mem:DI (reg:DI 7)))
2401 (set (reg:DI 7)
2402 (plus:DI (reg:DI 7) (const_int 8)))
2403 (set (reg:DI 6) (reg:DI 6))]
2404 "TARGET_64BIT"
2405 "pop{q}\\t%0"
2406 [(set_attr "type" "pop")
2407 (set_attr "mode" "DI")])
2408
2409 (define_insn "popdi1"
2410 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2411 (mem:DI (reg:DI 7)))
2412 (set (reg:DI 7)
2413 (plus:DI (reg:DI 7) (const_int 8)))]
2414 "TARGET_64BIT"
2415 "pop{q}\\t%0"
2416 [(set_attr "type" "pop")
2417 (set_attr "mode" "DI")])
2418
2419 (define_insn "*movdi_xor_rex64"
2420 [(set (match_operand:DI 0 "register_operand" "=r")
2421 (match_operand:DI 1 "const0_operand" "i"))
2422 (clobber (reg:CC 17))]
2423 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)
2424 && TARGET_64BIT"
2425 "xor{l}\\t{%k0, %k0|%k0, %k0}"
2426 [(set_attr "type" "alu1")
2427 (set_attr "mode" "SI")
2428 (set_attr "length_immediate" "0")])
2429
2430 (define_insn "*movdi_or_rex64"
2431 [(set (match_operand:DI 0 "register_operand" "=r")
2432 (match_operand:DI 1 "const_int_operand" "i"))
2433 (clobber (reg:CC 17))]
2434 "reload_completed && GET_CODE (operands[1]) == CONST_INT
2435 && TARGET_64BIT
2436 && INTVAL (operands[1]) == -1
2437 && (TARGET_PENTIUM || optimize_size)"
2438 "*
2439 {
2440 operands[1] = constm1_rtx;
2441 return \"or{q}\\t{%1, %0|%0, %1}\";
2442 }"
2443 [(set_attr "type" "alu1")
2444 (set_attr "mode" "DI")
2445 (set_attr "length_immediate" "1")])
2446
2447 (define_insn "*movdi_2"
2448 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y")
2449 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))]
2450 "!TARGET_64BIT
2451 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2452 "@
2453 #
2454 #
2455 movq\\t{%1, %0|%0, %1}
2456 movq\\t{%1, %0|%0, %1}"
2457 [(set_attr "type" "*,*,mmx,mmx")])
2458
2459 (define_split
2460 [(set (match_operand:DI 0 "push_operand" "")
2461 (match_operand:DI 1 "general_operand" ""))]
2462 "!TARGET_64BIT && reload_completed && ! MMX_REG_P (operands[1])"
2463 [(const_int 0)]
2464 "ix86_split_long_move (operands); DONE;")
2465
2466 ;; %%% This multiword shite has got to go.
2467 (define_split
2468 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2469 (match_operand:DI 1 "general_operand" ""))]
2470 "!TARGET_64BIT && reload_completed && ! MMX_REG_P (operands[0])
2471 && ! MMX_REG_P (operands[1])"
2472 [(const_int 0)]
2473 "ix86_split_long_move (operands); DONE;")
2474
2475 (define_insn "*movdi_1_rex64"
2476 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,m*Y,*Y")
2477 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*m"))]
2478 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2479 && TARGET_64BIT"
2480 "*
2481 {
2482 switch (get_attr_type (insn))
2483 {
2484 case TYPE_SSE:
2485 case TYPE_MMX:
2486 return \"movd\\t{%1, %0|%0, %1}\";
2487 case TYPE_MULTI:
2488 return \"#\";
2489 case TYPE_LEA:
2490 return \"lea{q}\\t{%a1, %0|%0, %a1}\";
2491 default:
2492 if (flag_pic && SYMBOLIC_CONST (operands[1]))
2493 abort ();
2494 if (get_attr_mode (insn) == MODE_SI)
2495 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
2496 else if (which_alternative == 2)
2497 return \"movabs{q}\\t{%1, %0|%0, %1}\";
2498 else
2499 return \"mov{q}\\t{%1, %0|%0, %1}\";
2500 }
2501 }"
2502 [(set (attr "type")
2503 (cond [(eq_attr "alternative" "5,6")
2504 (const_string "mmx")
2505 (eq_attr "alternative" "7,8")
2506 (const_string "sse")
2507 (eq_attr "alternative" "4")
2508 (const_string "multi")
2509 (and (ne (symbol_ref "flag_pic") (const_int 0))
2510 (match_operand:DI 1 "symbolic_operand" ""))
2511 (const_string "lea")
2512 ]
2513 (const_string "imov")))
2514 (set_attr "modrm" "*,0,0,*,*,*,*,*,*")
2515 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*")
2516 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI")])
2517
2518 ;; Stores and loads of ax to arbitary constant address.
2519 ;; We fake an second form of instruction to force reload to load address
2520 ;; into register when rax is not available
2521 (define_insn "*movabsdi_1_rex64"
2522 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2523 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2524 "TARGET_64BIT"
2525 "@
2526 movabs{q}\\t{%1, %P0|%P0, %1}
2527 mov{q}\\t{%1, %a0|%a0, %1}
2528 movabs{q}\\t{%1, %a0|%a0, %1}"
2529 [(set_attr "type" "imov")
2530 (set_attr "modrm" "0,*,*")
2531 (set_attr "length_address" "8,0,0")
2532 (set_attr "length_immediate" "0,*,*")
2533 (set_attr "memory" "store")
2534 (set_attr "mode" "DI")])
2535
2536 (define_insn "*movabsdi_2_rex64"
2537 [(set (match_operand:DI 0 "register_operand" "=a,r")
2538 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2539 "TARGET_64BIT"
2540 "@
2541 movabs{q}\\t{%P1, %0|%0, %P1}
2542 mov{q}\\t{%a1, %0|%0, %a1}"
2543 [(set_attr "type" "imov")
2544 (set_attr "modrm" "0,*")
2545 (set_attr "length_address" "8,0")
2546 (set_attr "length_immediate" "0")
2547 (set_attr "memory" "load")
2548 (set_attr "mode" "DI")])
2549
2550 ;; Convert impossible stores of immediate to existing instructions.
2551 ;; First try to get scratch register and go trought it. In case this
2552 ;; fails, move by 32bit parts.
2553 (define_peephole2
2554 [(match_scratch:DI 2 "r")
2555 (set (match_operand:DI 0 "memory_operand" "")
2556 (match_operand:DI 1 "immediate_operand" ""))]
2557 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2558 && !x86_64_immediate_operand (operands[1], DImode)"
2559 [(set (match_dup 2) (match_dup 1))
2560 (set (match_dup 0) (match_dup 2))]
2561 "")
2562
2563 ;; We need to define this as both peepholer and splitter for case
2564 ;; peephole2 pass is not run.
2565 (define_peephole2
2566 [(set (match_operand:DI 0 "memory_operand" "")
2567 (match_operand:DI 1 "immediate_operand" ""))]
2568 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2569 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2570 [(set (match_dup 2) (match_dup 3))
2571 (set (match_dup 4) (match_dup 5))]
2572 "split_di (operands, 2, operands + 2, operands + 4);")
2573
2574 (define_split
2575 [(set (match_operand:DI 0 "memory_operand" "")
2576 (match_operand:DI 1 "immediate_operand" ""))]
2577 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2578 && !symbolic_operand (operands[1], DImode)
2579 && !x86_64_immediate_operand (operands[1], DImode)"
2580 [(set (match_dup 2) (match_dup 3))
2581 (set (match_dup 4) (match_dup 5))]
2582 "split_di (operands, 2, operands + 2, operands + 4);")
2583
2584 (define_insn "*swapdi_rex64"
2585 [(set (match_operand:DI 0 "register_operand" "+r")
2586 (match_operand:DI 1 "register_operand" "+r"))
2587 (set (match_dup 1)
2588 (match_dup 0))]
2589 "TARGET_64BIT"
2590 "xchg{q}\\t%1, %0"
2591 [(set_attr "type" "imov")
2592 (set_attr "pent_pair" "np")
2593 (set_attr "athlon_decode" "vector")
2594 (set_attr "mode" "DI")
2595 (set_attr "modrm" "0")
2596 (set_attr "ppro_uops" "few")])
2597
2598
2599 (define_expand "movsf"
2600 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2601 (match_operand:SF 1 "general_operand" ""))]
2602 ""
2603 "ix86_expand_move (SFmode, operands); DONE;")
2604
2605 (define_insn "*pushsf"
2606 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2607 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2608 "!TARGET_64BIT"
2609 "*
2610 {
2611 switch (which_alternative)
2612 {
2613 case 0:
2614 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2615 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2616 operands[2] = stack_pointer_rtx;
2617 operands[3] = GEN_INT (4);
2618 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2619 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2620 else
2621 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2622
2623 case 1:
2624 return \"push{l}\\t%1\";
2625 case 2:
2626 return \"#\";
2627
2628 default:
2629 abort ();
2630 }
2631 }"
2632 [(set_attr "type" "multi,push,multi")
2633 (set_attr "mode" "SF,SI,SF")])
2634
2635 (define_insn "*pushsf_rex64"
2636 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2637 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2638 "TARGET_64BIT"
2639 "*
2640 {
2641 switch (which_alternative)
2642 {
2643 case 0:
2644 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2645 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2646 operands[2] = stack_pointer_rtx;
2647 operands[3] = GEN_INT (8);
2648 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2649 return \"sub{q}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2650 else
2651 return \"sub{q}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2652
2653 case 1:
2654 return \"push{q}\\t%q1\";
2655
2656 case 2:
2657 return \"#\";
2658
2659 default:
2660 abort ();
2661 }
2662 }"
2663 [(set_attr "type" "multi,push,multi")
2664 (set_attr "mode" "SF,DI,SF")])
2665
2666 (define_split
2667 [(set (match_operand:SF 0 "push_operand" "")
2668 (match_operand:SF 1 "memory_operand" ""))]
2669 "reload_completed
2670 && GET_CODE (operands[1]) == MEM
2671 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2672 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2673 [(set (match_dup 0)
2674 (match_dup 1))]
2675 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2676
2677
2678 ;; %%% Kill this when call knows how to work this out.
2679 (define_split
2680 [(set (match_operand:SF 0 "push_operand" "")
2681 (match_operand:SF 1 "register_operand" ""))]
2682 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2683 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2684 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2685
2686 (define_split
2687 [(set (match_operand:SF 0 "push_operand" "")
2688 (match_operand:SF 1 "register_operand" ""))]
2689 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
2690 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2691 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2692
2693 (define_insn "*movsf_1"
2694 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
2695 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
2696 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2697 && (reload_in_progress || reload_completed
2698 || GET_CODE (operands[1]) != CONST_DOUBLE
2699 || memory_operand (operands[0], SFmode))"
2700 "*
2701 {
2702 switch (which_alternative)
2703 {
2704 case 0:
2705 if (REG_P (operands[1])
2706 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2707 return \"fstp\\t%y0\";
2708 else if (STACK_TOP_P (operands[0]))
2709 return \"fld%z1\\t%y1\";
2710 else
2711 return \"fst\\t%y0\";
2712
2713 case 1:
2714 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2715 return \"fstp%z0\\t%y0\";
2716 else
2717 return \"fst%z0\\t%y0\";
2718
2719 case 2:
2720 switch (standard_80387_constant_p (operands[1]))
2721 {
2722 case 1:
2723 return \"fldz\";
2724 case 2:
2725 return \"fld1\";
2726 }
2727 abort();
2728
2729 case 3:
2730 case 4:
2731 return \"mov{l}\\t{%1, %0|%0, %1}\";
2732 case 5:
2733 return \"pxor\\t%0, %0\";
2734 case 6:
2735 if (TARGET_PARTIAL_REG_DEPENDENCY)
2736 return \"movaps\\t{%1, %0|%0, %1}\";
2737 else
2738 return \"movss\\t{%1, %0|%0, %1}\";
2739 case 7:
2740 case 8:
2741 return \"movss\\t{%1, %0|%0, %1}\";
2742
2743 default:
2744 abort();
2745 }
2746 }"
2747 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
2748 (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
2749
2750 (define_insn "*swapsf"
2751 [(set (match_operand:SF 0 "register_operand" "+f")
2752 (match_operand:SF 1 "register_operand" "+f"))
2753 (set (match_dup 1)
2754 (match_dup 0))]
2755 "reload_completed || !TARGET_SSE2"
2756 "*
2757 {
2758 if (STACK_TOP_P (operands[0]))
2759 return \"fxch\\t%1\";
2760 else
2761 return \"fxch\\t%0\";
2762 }"
2763 [(set_attr "type" "fxch")
2764 (set_attr "mode" "SF")])
2765
2766 (define_expand "movdf"
2767 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2768 (match_operand:DF 1 "general_operand" ""))]
2769 ""
2770 "ix86_expand_move (DFmode, operands); DONE;")
2771
2772 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2773 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2774 ;; On the average, pushdf using integers can be still shorter. Allow this
2775 ;; pattern for optimize_size too.
2776
2777 (define_insn "*pushdf_nointeger"
2778 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2779 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2780 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2781 "*
2782 {
2783 switch (which_alternative)
2784 {
2785 case 0:
2786 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2787 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2788 operands[2] = stack_pointer_rtx;
2789 operands[3] = GEN_INT (8);
2790 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2791 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2792 else
2793 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2794
2795 case 1:
2796 case 2:
2797 case 3:
2798 return \"#\";
2799
2800 default:
2801 abort ();
2802 }
2803 }"
2804 [(set_attr "type" "multi")
2805 (set_attr "mode" "DF,SI,SI,DF")])
2806
2807 (define_insn "*pushdf_integer"
2808 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2809 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2810 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2811 "*
2812 {
2813 switch (which_alternative)
2814 {
2815 case 0:
2816 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2817 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2818 operands[2] = stack_pointer_rtx;
2819 operands[3] = GEN_INT (8);
2820 if (TARGET_64BIT)
2821 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2822 return \"sub{q}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2823 else
2824 return \"sub{q}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2825 else
2826 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2828 else
2829 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2830
2831
2832 case 1:
2833 case 2:
2834 return \"#\";
2835
2836 default:
2837 abort ();
2838 }
2839 }"
2840 [(set_attr "type" "multi")
2841 (set_attr "mode" "DF,SI,DF")])
2842
2843 ;; %%% Kill this when call knows how to work this out.
2844 (define_split
2845 [(set (match_operand:DF 0 "push_operand" "")
2846 (match_operand:DF 1 "register_operand" ""))]
2847 "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2848 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2849 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2850 "")
2851
2852 (define_split
2853 [(set (match_operand:DF 0 "push_operand" "")
2854 (match_operand:DF 1 "register_operand" ""))]
2855 "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2856 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2857 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2858 "")
2859
2860 (define_split
2861 [(set (match_operand:DF 0 "push_operand" "")
2862 (match_operand:DF 1 "general_operand" ""))]
2863 "reload_completed"
2864 [(const_int 0)]
2865 "ix86_split_long_move (operands); DONE;")
2866
2867 ;; Moving is usually shorter when only FP registers are used. This separate
2868 ;; movdf pattern avoids the use of integer registers for FP operations
2869 ;; when optimizing for size.
2870
2871 (define_insn "*movdf_nointeger"
2872 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2873 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
2874 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2875 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2876 && (reload_in_progress || reload_completed
2877 || GET_CODE (operands[1]) != CONST_DOUBLE
2878 || memory_operand (operands[0], DFmode))"
2879 "*
2880 {
2881 switch (which_alternative)
2882 {
2883 case 0:
2884 if (REG_P (operands[1])
2885 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2886 return \"fstp\\t%y0\";
2887 else if (STACK_TOP_P (operands[0]))
2888 return \"fld%z1\\t%y1\";
2889 else
2890 return \"fst\\t%y0\";
2891
2892 case 1:
2893 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2894 return \"fstp%z0\\t%y0\";
2895 else
2896 return \"fst%z0\\t%y0\";
2897
2898 case 2:
2899 switch (standard_80387_constant_p (operands[1]))
2900 {
2901 case 1:
2902 return \"fldz\";
2903 case 2:
2904 return \"fld1\";
2905 }
2906 abort();
2907
2908 case 3:
2909 case 4:
2910 return \"#\";
2911 case 5:
2912 return \"pxor\\t%0, %0\";
2913 case 6:
2914 if (TARGET_PARTIAL_REG_DEPENDENCY)
2915 return \"movapd\\t{%1, %0|%0, %1}\";
2916 else
2917 return \"movsd\\t{%1, %0|%0, %1}\";
2918 case 7:
2919 case 8:
2920 return \"movsd\\t{%1, %0|%0, %1}\";
2921
2922 default:
2923 abort();
2924 }
2925 }"
2926 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2927 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2928
2929 (define_insn "*movdf_integer"
2930 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2931 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
2932 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2933 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2934 && (reload_in_progress || reload_completed
2935 || GET_CODE (operands[1]) != CONST_DOUBLE
2936 || memory_operand (operands[0], DFmode))"
2937 "*
2938 {
2939 switch (which_alternative)
2940 {
2941 case 0:
2942 if (REG_P (operands[1])
2943 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2944 return \"fstp\\t%y0\";
2945 else if (STACK_TOP_P (operands[0]))
2946 return \"fld%z1\\t%y1\";
2947 else
2948 return \"fst\\t%y0\";
2949
2950 case 1:
2951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2952 return \"fstp%z0\\t%y0\";
2953 else
2954 return \"fst%z0\\t%y0\";
2955
2956 case 2:
2957 switch (standard_80387_constant_p (operands[1]))
2958 {
2959 case 1:
2960 return \"fldz\";
2961 case 2:
2962 return \"fld1\";
2963 }
2964 abort();
2965
2966 case 3:
2967 case 4:
2968 return \"#\";
2969
2970 case 5:
2971 return \"pxor\\t%0, %0\";
2972 case 6:
2973 if (TARGET_PARTIAL_REG_DEPENDENCY)
2974 return \"movapd\\t{%1, %0|%0, %1}\";
2975 else
2976 return \"movsd\\t{%1, %0|%0, %1}\";
2977 case 7:
2978 case 8:
2979 return \"movsd\\t{%1, %0|%0, %1}\";
2980
2981 default:
2982 abort();
2983 }
2984 }"
2985 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
2986 (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
2987
2988 (define_split
2989 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2990 (match_operand:DF 1 "general_operand" ""))]
2991 "reload_completed
2992 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2993 && ! (ANY_FP_REG_P (operands[0]) ||
2994 (GET_CODE (operands[0]) == SUBREG
2995 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2996 && ! (ANY_FP_REG_P (operands[1]) ||
2997 (GET_CODE (operands[1]) == SUBREG
2998 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2999 [(const_int 0)]
3000 "ix86_split_long_move (operands); DONE;")
3001
3002 (define_insn "*swapdf"
3003 [(set (match_operand:DF 0 "register_operand" "+f")
3004 (match_operand:DF 1 "register_operand" "+f"))
3005 (set (match_dup 1)
3006 (match_dup 0))]
3007 "reload_completed || !TARGET_SSE2"
3008 "*
3009 {
3010 if (STACK_TOP_P (operands[0]))
3011 return \"fxch\\t%1\";
3012 else
3013 return \"fxch\\t%0\";
3014 }"
3015 [(set_attr "type" "fxch")
3016 (set_attr "mode" "DF")])
3017
3018 (define_expand "movxf"
3019 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3020 (match_operand:XF 1 "general_operand" ""))]
3021 "!TARGET_64BIT"
3022 "ix86_expand_move (XFmode, operands); DONE;")
3023
3024 (define_expand "movtf"
3025 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3026 (match_operand:TF 1 "general_operand" ""))]
3027 ""
3028 "ix86_expand_move (TFmode, operands); DONE;")
3029
3030 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3031 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
3032 ;; Pushing using integer instructions is longer except for constants
3033 ;; and direct memory references.
3034 ;; (assuming that any given constant is pushed only once, but this ought to be
3035 ;; handled elsewhere).
3036
3037 (define_insn "*pushxf_nointeger"
3038 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3039 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3040 "optimize_size && !TARGET_64BIT"
3041 "*
3042 {
3043 switch (which_alternative)
3044 {
3045 case 0:
3046 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3047 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3048 operands[2] = stack_pointer_rtx;
3049 operands[3] = GEN_INT (12);
3050 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3051 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
3052 else
3053 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
3054
3055 case 1:
3056 case 2:
3057 return \"#\";
3058
3059 default:
3060 abort ();
3061 }
3062 }"
3063 [(set_attr "type" "multi")
3064 (set_attr "mode" "XF,SI,SI")])
3065
3066 (define_insn "*pushtf_nointeger"
3067 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3068 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
3069 "optimize_size"
3070 "*
3071 {
3072 switch (which_alternative)
3073 {
3074 case 0:
3075 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3076 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3077 operands[2] = stack_pointer_rtx;
3078 operands[3] = GEN_INT (16);
3079 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3080 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
3081 else
3082 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
3083
3084 case 1:
3085 case 2:
3086 return \"#\";
3087
3088 default:
3089 abort ();
3090 }
3091 }"
3092 [(set_attr "type" "multi")
3093 (set_attr "mode" "XF,SI,SI")])
3094
3095 (define_insn "*pushxf_integer"
3096 [(set (match_operand:XF 0 "push_operand" "=<,<")
3097 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
3098 "!optimize_size && !TARGET_64BIT"
3099 "*
3100 {
3101 switch (which_alternative)
3102 {
3103 case 0:
3104 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3105 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3106 operands[2] = stack_pointer_rtx;
3107 operands[3] = GEN_INT (12);
3108 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3109 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
3110 else
3111 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
3112
3113 case 1:
3114 return \"#\";
3115
3116 default:
3117 abort ();
3118 }
3119 }"
3120 [(set_attr "type" "multi")
3121 (set_attr "mode" "XF,SI")])
3122
3123 (define_insn "*pushtf_integer"
3124 [(set (match_operand:TF 0 "push_operand" "=<,<")
3125 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
3126 "!optimize_size"
3127 "*
3128 {
3129 switch (which_alternative)
3130 {
3131 case 0:
3132 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
3133 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
3134 operands[2] = stack_pointer_rtx;
3135 operands[3] = GEN_INT (16);
3136 if (TARGET_64BIT)
3137 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3138 return \"sub{q}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
3139 else
3140 return \"sub{q}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
3141 else
3142 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3143 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
3144 else
3145 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
3146
3147 case 1:
3148 return \"#\";
3149
3150 default:
3151 abort ();
3152 }
3153 }"
3154 [(set_attr "type" "multi")
3155 (set_attr "mode" "XF,SI")])
3156
3157 (define_split
3158 [(set (match_operand 0 "push_operand" "")
3159 (match_operand 1 "general_operand" ""))]
3160 "reload_completed
3161 && (GET_MODE (operands[0]) == XFmode
3162 || GET_MODE (operands[0]) == TFmode
3163 || GET_MODE (operands[0]) == DFmode)
3164 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
3165 [(const_int 0)]
3166 "ix86_split_long_move (operands); DONE;")
3167
3168 (define_split
3169 [(set (match_operand:XF 0 "push_operand" "")
3170 (match_operand:XF 1 "register_operand" ""))]
3171 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3172 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3173 (set (mem:XF (reg:SI 7)) (match_dup 1))])
3174
3175 (define_split
3176 [(set (match_operand:TF 0 "push_operand" "")
3177 (match_operand:TF 1 "register_operand" ""))]
3178 "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3179 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3180 (set (mem:TF (reg:SI 7)) (match_dup 1))])
3181
3182 (define_split
3183 [(set (match_operand:TF 0 "push_operand" "")
3184 (match_operand:TF 1 "register_operand" ""))]
3185 "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
3186 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3187 (set (mem:TF (reg:DI 7)) (match_dup 1))])
3188
3189 ;; Do not use integer registers when optimizing for size
3190 (define_insn "*movxf_nointeger"
3191 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3192 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3193 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3194 && !TARGET_64BIT
3195 && optimize_size
3196 && (reload_in_progress || reload_completed
3197 || GET_CODE (operands[1]) != CONST_DOUBLE
3198 || memory_operand (operands[0], XFmode))"
3199 "*
3200 {
3201 switch (which_alternative)
3202 {
3203 case 0:
3204 if (REG_P (operands[1])
3205 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3206 return \"fstp\\t%y0\";
3207 else if (STACK_TOP_P (operands[0]))
3208 return \"fld%z1\\t%y1\";
3209 else
3210 return \"fst\\t%y0\";
3211
3212 case 1:
3213 /* There is no non-popping store to memory for XFmode. So if
3214 we need one, follow the store with a load. */
3215 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3216 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
3217 else
3218 return \"fstp%z0\\t%y0\";
3219
3220 case 2:
3221 switch (standard_80387_constant_p (operands[1]))
3222 {
3223 case 1:
3224 return \"fldz\";
3225 case 2:
3226 return \"fld1\";
3227 }
3228 break;
3229
3230 case 3: case 4:
3231 return \"#\";
3232 }
3233 abort();
3234 }"
3235 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3236 (set_attr "mode" "XF,XF,XF,SI,SI")])
3237
3238 (define_insn "*movtf_nointeger"
3239 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3240 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3241 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3242 && optimize_size
3243 && (reload_in_progress || reload_completed
3244 || GET_CODE (operands[1]) != CONST_DOUBLE
3245 || memory_operand (operands[0], TFmode))"
3246 "*
3247 {
3248 switch (which_alternative)
3249 {
3250 case 0:
3251 if (REG_P (operands[1])
3252 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3253 return \"fstp\\t%y0\";
3254 else if (STACK_TOP_P (operands[0]))
3255 return \"fld%z1\\t%y1\";
3256 else
3257 return \"fst\\t%y0\";
3258
3259 case 1:
3260 /* There is no non-popping store to memory for XFmode. So if
3261 we need one, follow the store with a load. */
3262 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3263 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
3264 else
3265 return \"fstp%z0\\t%y0\";
3266
3267 case 2:
3268 switch (standard_80387_constant_p (operands[1]))
3269 {
3270 case 1:
3271 return \"fldz\";
3272 case 2:
3273 return \"fld1\";
3274 }
3275 break;
3276
3277 case 3: case 4:
3278 return \"#\";
3279 }
3280 abort();
3281 }"
3282 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3283 (set_attr "mode" "XF,XF,XF,SI,SI")])
3284
3285 (define_insn "*movxf_integer"
3286 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3287 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3288 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3289 && !TARGET_64BIT
3290 && !optimize_size
3291 && (reload_in_progress || reload_completed
3292 || GET_CODE (operands[1]) != CONST_DOUBLE
3293 || memory_operand (operands[0], XFmode))"
3294 "*
3295 {
3296 switch (which_alternative)
3297 {
3298 case 0:
3299 if (REG_P (operands[1])
3300 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3301 return \"fstp\\t%y0\";
3302 else if (STACK_TOP_P (operands[0]))
3303 return \"fld%z1\\t%y1\";
3304 else
3305 return \"fst\\t%y0\";
3306
3307 case 1:
3308 /* There is no non-popping store to memory for XFmode. So if
3309 we need one, follow the store with a load. */
3310 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3311 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
3312 else
3313 return \"fstp%z0\\t%y0\";
3314
3315 case 2:
3316 switch (standard_80387_constant_p (operands[1]))
3317 {
3318 case 1:
3319 return \"fldz\";
3320 case 2:
3321 return \"fld1\";
3322 }
3323 break;
3324
3325 case 3: case 4:
3326 return \"#\";
3327 }
3328 abort();
3329 }"
3330 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3331 (set_attr "mode" "XF,XF,XF,SI,SI")])
3332
3333 (define_insn "*movtf_integer"
3334 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
3335 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
3336 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3337 && !optimize_size
3338 && (reload_in_progress || reload_completed
3339 || GET_CODE (operands[1]) != CONST_DOUBLE
3340 || memory_operand (operands[0], TFmode))"
3341 "*
3342 {
3343 switch (which_alternative)
3344 {
3345 case 0:
3346 if (REG_P (operands[1])
3347 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3348 return \"fstp\\t%y0\";
3349 else if (STACK_TOP_P (operands[0]))
3350 return \"fld%z1\\t%y1\";
3351 else
3352 return \"fst\\t%y0\";
3353
3354 case 1:
3355 /* There is no non-popping store to memory for XFmode. So if
3356 we need one, follow the store with a load. */
3357 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3358 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
3359 else
3360 return \"fstp%z0\\t%y0\";
3361
3362 case 2:
3363 switch (standard_80387_constant_p (operands[1]))
3364 {
3365 case 1:
3366 return \"fldz\";
3367 case 2:
3368 return \"fld1\";
3369 }
3370 break;
3371
3372 case 3: case 4:
3373 return \"#\";
3374 }
3375 abort();
3376 }"
3377 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3378 (set_attr "mode" "XF,XF,XF,SI,SI")])
3379
3380 (define_split
3381 [(set (match_operand 0 "nonimmediate_operand" "")
3382 (match_operand 1 "general_operand" ""))]
3383 "reload_completed
3384 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3385 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3386 && ! (ANY_FP_REG_P (operands[0]) ||
3387 (GET_CODE (operands[0]) == SUBREG
3388 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3389 && ! (ANY_FP_REG_P (operands[1]) ||
3390 (GET_CODE (operands[1]) == SUBREG
3391 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3392 [(const_int 0)]
3393 "ix86_split_long_move (operands); DONE;")
3394
3395 (define_split
3396 [(set (match_operand 0 "register_operand" "")
3397 (match_operand 1 "memory_operand" ""))]
3398 "reload_completed
3399 && GET_CODE (operands[1]) == MEM
3400 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3401 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3402 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3403 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3404 && (!(SSE_REG_P (operands[0]) ||
3405 (GET_CODE (operands[0]) == SUBREG
3406 && SSE_REG_P (SUBREG_REG (operands[0]))))
3407 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3408 && (!(FP_REG_P (operands[0]) ||
3409 (GET_CODE (operands[0]) == SUBREG
3410 && FP_REG_P (SUBREG_REG (operands[0]))))
3411 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3412 [(set (match_dup 0)
3413 (match_dup 1))]
3414 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3415
3416 (define_insn "swapxf"
3417 [(set (match_operand:XF 0 "register_operand" "+f")
3418 (match_operand:XF 1 "register_operand" "+f"))
3419 (set (match_dup 1)
3420 (match_dup 0))]
3421 ""
3422 "*
3423 {
3424 if (STACK_TOP_P (operands[0]))
3425 return \"fxch\\t%1\";
3426 else
3427 return \"fxch\\t%0\";
3428 }"
3429 [(set_attr "type" "fxch")
3430 (set_attr "mode" "XF")])
3431
3432 (define_insn "swaptf"
3433 [(set (match_operand:TF 0 "register_operand" "+f")
3434 (match_operand:TF 1 "register_operand" "+f"))
3435 (set (match_dup 1)
3436 (match_dup 0))]
3437 ""
3438 "*
3439 {
3440 if (STACK_TOP_P (operands[0]))
3441 return \"fxch\\t%1\";
3442 else
3443 return \"fxch\\t%0\";
3444 }"
3445 [(set_attr "type" "fxch")
3446 (set_attr "mode" "XF")])
3447 \f
3448 ;; Zero extension instructions
3449
3450 (define_expand "zero_extendhisi2"
3451 [(set (match_operand:SI 0 "register_operand" "")
3452 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3453 ""
3454 "
3455 {
3456 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3457 {
3458 operands[1] = force_reg (HImode, operands[1]);
3459 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3460 DONE;
3461 }
3462 }")
3463
3464 (define_insn "zero_extendhisi2_and"
3465 [(set (match_operand:SI 0 "register_operand" "=r")
3466 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3467 (clobber (reg:CC 17))]
3468 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3469 "#"
3470 [(set_attr "type" "alu1")
3471 (set_attr "mode" "SI")])
3472
3473 (define_split
3474 [(set (match_operand:SI 0 "register_operand" "")
3475 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3476 (clobber (reg:CC 17))]
3477 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3478 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3479 (clobber (reg:CC 17))])]
3480 "")
3481
3482 (define_insn "*zero_extendhisi2_movzwl"
3483 [(set (match_operand:SI 0 "register_operand" "=r")
3484 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3486 "movz{wl|x}\\t{%1, %0|%0, %1}"
3487 [(set_attr "type" "imovx")
3488 (set_attr "mode" "SI")])
3489
3490 (define_expand "zero_extendqihi2"
3491 [(parallel
3492 [(set (match_operand:HI 0 "register_operand" "")
3493 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3494 (clobber (reg:CC 17))])]
3495 ""
3496 "")
3497
3498 (define_insn "*zero_extendqihi2_and"
3499 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3500 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3501 (clobber (reg:CC 17))]
3502 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3503 "#"
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "HI")])
3506
3507 (define_insn "*zero_extendqihi2_movzbw_and"
3508 [(set (match_operand:HI 0 "register_operand" "=r,r")
3509 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3510 (clobber (reg:CC 17))]
3511 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3512 "#"
3513 [(set_attr "type" "imovx,alu1")
3514 (set_attr "mode" "HI")])
3515
3516 (define_insn "*zero_extendqihi2_movzbw"
3517 [(set (match_operand:HI 0 "register_operand" "=r")
3518 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3519 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3520 "movz{bw|x}\\t{%1, %0|%0, %1}"
3521 [(set_attr "type" "imovx")
3522 (set_attr "mode" "HI")])
3523
3524 ;; For the movzbw case strip only the clobber
3525 (define_split
3526 [(set (match_operand:HI 0 "register_operand" "")
3527 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3528 (clobber (reg:CC 17))]
3529 "reload_completed
3530 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3531 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3532 [(set (match_operand:HI 0 "register_operand" "")
3533 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3534
3535 ;; When source and destination does not overlap, clear destination
3536 ;; first and then do the movb
3537 (define_split
3538 [(set (match_operand:HI 0 "register_operand" "")
3539 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3540 (clobber (reg:CC 17))]
3541 "reload_completed
3542 && ANY_QI_REG_P (operands[0])
3543 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3544 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3545 [(set (match_dup 0) (const_int 0))
3546 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3547 "operands[2] = gen_lowpart (QImode, operands[0]);")
3548
3549 ;; Rest is handled by single and.
3550 (define_split
3551 [(set (match_operand:HI 0 "register_operand" "")
3552 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3553 (clobber (reg:CC 17))]
3554 "reload_completed
3555 && true_regnum (operands[0]) == true_regnum (operands[1])"
3556 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3557 (clobber (reg:CC 17))])]
3558 "")
3559
3560 (define_expand "zero_extendqisi2"
3561 [(parallel
3562 [(set (match_operand:SI 0 "register_operand" "")
3563 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3564 (clobber (reg:CC 17))])]
3565 ""
3566 "")
3567
3568 (define_insn "*zero_extendqisi2_and"
3569 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3570 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3571 (clobber (reg:CC 17))]
3572 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3573 "#"
3574 [(set_attr "type" "alu1")
3575 (set_attr "mode" "SI")])
3576
3577 (define_insn "*zero_extendqisi2_movzbw_and"
3578 [(set (match_operand:SI 0 "register_operand" "=r,r")
3579 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3580 (clobber (reg:CC 17))]
3581 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3582 "#"
3583 [(set_attr "type" "imovx,alu1")
3584 (set_attr "mode" "SI")])
3585
3586 (define_insn "*zero_extendqisi2_movzbw"
3587 [(set (match_operand:SI 0 "register_operand" "=r")
3588 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3589 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3590 "movz{bl|x}\\t{%1, %0|%0, %1}"
3591 [(set_attr "type" "imovx")
3592 (set_attr "mode" "SI")])
3593
3594 ;; For the movzbl case strip only the clobber
3595 (define_split
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3598 (clobber (reg:CC 17))]
3599 "reload_completed
3600 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3601 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3602 [(set (match_dup 0)
3603 (zero_extend:SI (match_dup 1)))])
3604
3605 ;; When source and destination does not overlap, clear destination
3606 ;; first and then do the movb
3607 (define_split
3608 [(set (match_operand:SI 0 "register_operand" "")
3609 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3610 (clobber (reg:CC 17))]
3611 "reload_completed
3612 && ANY_QI_REG_P (operands[0])
3613 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3614 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3615 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3616 [(set (match_dup 0) (const_int 0))
3617 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3618 "operands[2] = gen_lowpart (QImode, operands[0]);")
3619
3620 ;; Rest is handled by single and.
3621 (define_split
3622 [(set (match_operand:SI 0 "register_operand" "")
3623 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3624 (clobber (reg:CC 17))]
3625 "reload_completed
3626 && true_regnum (operands[0]) == true_regnum (operands[1])"
3627 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3628 (clobber (reg:CC 17))])]
3629 "")
3630
3631 ;; %%% Kill me once multi-word ops are sane.
3632 (define_expand "zero_extendsidi2"
3633 [(set (match_operand:DI 0 "register_operand" "=r")
3634 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3635 ""
3636 "if (!TARGET_64BIT)
3637 {
3638 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3639 DONE;
3640 }
3641 ")
3642
3643 (define_insn "zero_extendsidi2_32"
3644 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3645 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3646 (clobber (reg:CC 17))]
3647 "!TARGET_64BIT"
3648 "#"
3649 [(set_attr "mode" "SI")])
3650
3651 (define_insn "zero_extendsidi2_rex64"
3652 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3653 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3654 "TARGET_64BIT"
3655 "@
3656 mov\\t{%k1, %k0|%k0, %k1}
3657 #"
3658 [(set_attr "type" "imovx,imov")
3659 (set_attr "mode" "SI,DI")])
3660
3661 (define_split
3662 [(set (match_operand:DI 0 "memory_operand" "")
3663 (zero_extend:DI (match_dup 0)))]
3664 ""
3665 [(set (match_dup 4) (const_int 0))]
3666 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3667
3668 (define_split
3669 [(set (match_operand:DI 0 "register_operand" "")
3670 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3671 (clobber (reg:CC 17))]
3672 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])
3673 && !TARGET_64BIT"
3674 [(set (match_dup 4) (const_int 0))]
3675 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3676
3677 (define_split
3678 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3679 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3680 (clobber (reg:CC 17))]
3681 "reload_completed && !TARGET_64BIT"
3682 [(set (match_dup 3) (match_dup 1))
3683 (set (match_dup 4) (const_int 0))]
3684 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3685
3686 (define_insn "zero_extendhidi2"
3687 [(set (match_operand:DI 0 "register_operand" "=r,r")
3688 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3689 "TARGET_64BIT"
3690 "@
3691 movz{wl|x}\\t{%1, %k0|%k0, %1}
3692 movz{wq|x}\\t{%1, %0|%0, %1}"
3693 [(set_attr "type" "imovx")
3694 (set_attr "mode" "SI,DI")])
3695
3696 (define_insn "zero_extendqidi2"
3697 [(set (match_operand:DI 0 "register_operand" "=r,r")
3698 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3699 "TARGET_64BIT"
3700 "@
3701 movz{bl|x}\\t{%1, %k0|%k0, %1}
3702 movz{bq|x}\\t{%1, %0|%0, %1}"
3703 [(set_attr "type" "imovx")
3704 (set_attr "mode" "SI,DI")])
3705 \f
3706 ;; Sign extension instructions
3707
3708 (define_expand "extendsidi2"
3709 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3710 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711 (clobber (reg:CC 17))
3712 (clobber (match_scratch:SI 2 ""))])]
3713 ""
3714 "
3715 {
3716 if (TARGET_64BIT)
3717 {
3718 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3719 DONE;
3720 }
3721 }")
3722
3723 (define_insn "*extendsidi2_1"
3724 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3725 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3726 (clobber (reg:CC 17))
3727 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3728 "!TARGET_64BIT"
3729 "#")
3730
3731 (define_insn "extendsidi2_rex64"
3732 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3733 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3734 "TARGET_64BIT"
3735 "@
3736 {cltq|cdqe}
3737 movs{lq|x}\\t{%1,%0|%0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "DI")
3740 (set_attr "prefix_0f" "0")
3741 (set_attr "modrm" "0,1")])
3742
3743 (define_insn "extendhidi2"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3745 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3746 "TARGET_64BIT"
3747 "movs{wq|x}\\t{%1,%0|%0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "DI")])
3750
3751 (define_insn "extendqidi2"
3752 [(set (match_operand:DI 0 "register_operand" "=r")
3753 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3754 "TARGET_64BIT"
3755 "movs{bq|x}\\t{%1,%0|%0, %1}"
3756 [(set_attr "type" "imovx")
3757 (set_attr "mode" "DI")])
3758
3759 ;; Extend to memory case when source register does die.
3760 (define_split
3761 [(set (match_operand:DI 0 "memory_operand" "")
3762 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3763 (clobber (reg:CC 17))
3764 (clobber (match_operand:SI 2 "register_operand" ""))]
3765 "(reload_completed
3766 && dead_or_set_p (insn, operands[1])
3767 && !reg_mentioned_p (operands[1], operands[0]))"
3768 [(set (match_dup 3) (match_dup 1))
3769 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3770 (clobber (reg:CC 17))])
3771 (set (match_dup 4) (match_dup 1))]
3772 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3773
3774 ;; Extend to memory case when source register does not die.
3775 (define_split
3776 [(set (match_operand:DI 0 "memory_operand" "")
3777 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3778 (clobber (reg:CC 17))
3779 (clobber (match_operand:SI 2 "register_operand" ""))]
3780 "reload_completed"
3781 [(const_int 0)]
3782 "
3783 {
3784 split_di (&operands[0], 1, &operands[3], &operands[4]);
3785
3786 emit_move_insn (operands[3], operands[1]);
3787
3788 /* Generate a cltd if possible and doing so it profitable. */
3789 if (true_regnum (operands[1]) == 0
3790 && true_regnum (operands[2]) == 1
3791 && (optimize_size || TARGET_USE_CLTD))
3792 {
3793 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3794 }
3795 else
3796 {
3797 emit_move_insn (operands[2], operands[1]);
3798 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3799 }
3800 emit_move_insn (operands[4], operands[2]);
3801 DONE;
3802 }")
3803
3804 ;; Extend to register case. Optimize case where source and destination
3805 ;; registers match and cases where we can use cltd.
3806 (define_split
3807 [(set (match_operand:DI 0 "register_operand" "")
3808 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3809 (clobber (reg:CC 17))
3810 (clobber (match_scratch:SI 2 ""))]
3811 "reload_completed"
3812 [(const_int 0)]
3813 "
3814 {
3815 split_di (&operands[0], 1, &operands[3], &operands[4]);
3816
3817 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3818 emit_move_insn (operands[3], operands[1]);
3819
3820 /* Generate a cltd if possible and doing so it profitable. */
3821 if (true_regnum (operands[3]) == 0
3822 && (optimize_size || TARGET_USE_CLTD))
3823 {
3824 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3825 DONE;
3826 }
3827
3828 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3829 emit_move_insn (operands[4], operands[1]);
3830
3831 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3832 DONE;
3833 }")
3834
3835 (define_insn "extendhisi2"
3836 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3837 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3838 ""
3839 "*
3840 {
3841 switch (get_attr_prefix_0f (insn))
3842 {
3843 case 0:
3844 return \"{cwtl|cwde}\";
3845 default:
3846 return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
3847 }
3848 }"
3849 [(set_attr "type" "imovx")
3850 (set_attr "mode" "SI")
3851 (set (attr "prefix_0f")
3852 ;; movsx is short decodable while cwtl is vector decoded.
3853 (if_then_else (and (eq_attr "cpu" "!k6")
3854 (eq_attr "alternative" "0"))
3855 (const_string "0")
3856 (const_string "1")))
3857 (set (attr "modrm")
3858 (if_then_else (eq_attr "prefix_0f" "0")
3859 (const_string "0")
3860 (const_string "1")))])
3861
3862 (define_insn "*extendhisi2_zext"
3863 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3864 (zero_extend:DI
3865 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3866 "TARGET_64BIT"
3867 "*
3868 {
3869 switch (get_attr_prefix_0f (insn))
3870 {
3871 case 0:
3872 return \"{cwtl|cwde}\";
3873 default:
3874 return \"movs{wl|x}\\t{%1,%k0|%k0, %1}\";
3875 }
3876 }"
3877 [(set_attr "type" "imovx")
3878 (set_attr "mode" "SI")
3879 (set (attr "prefix_0f")
3880 ;; movsx is short decodable while cwtl is vector decoded.
3881 (if_then_else (and (eq_attr "cpu" "!k6")
3882 (eq_attr "alternative" "0"))
3883 (const_string "0")
3884 (const_string "1")))
3885 (set (attr "modrm")
3886 (if_then_else (eq_attr "prefix_0f" "0")
3887 (const_string "0")
3888 (const_string "1")))])
3889
3890 (define_insn "extendqihi2"
3891 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3892 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3893 ""
3894 "*
3895 {
3896 switch (get_attr_prefix_0f (insn))
3897 {
3898 case 0:
3899 return \"{cbtw|cbw}\";
3900 default:
3901 return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
3902 }
3903 }"
3904 [(set_attr "type" "imovx")
3905 (set_attr "mode" "HI")
3906 (set (attr "prefix_0f")
3907 ;; movsx is short decodable while cwtl is vector decoded.
3908 (if_then_else (and (eq_attr "cpu" "!k6")
3909 (eq_attr "alternative" "0"))
3910 (const_string "0")
3911 (const_string "1")))
3912 (set (attr "modrm")
3913 (if_then_else (eq_attr "prefix_0f" "0")
3914 (const_string "0")
3915 (const_string "1")))])
3916
3917 (define_insn "extendqisi2"
3918 [(set (match_operand:SI 0 "register_operand" "=r")
3919 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3920 ""
3921 "movs{bl|x}\\t{%1,%0|%0, %1}"
3922 [(set_attr "type" "imovx")
3923 (set_attr "mode" "SI")])
3924
3925 (define_insn "*extendqisi2_zext"
3926 [(set (match_operand:DI 0 "register_operand" "=r")
3927 (zero_extend:DI
3928 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3929 "TARGET_64BIT"
3930 "movs{bl|x}\\t{%1,%k0|%k0, %1}"
3931 [(set_attr "type" "imovx")
3932 (set_attr "mode" "SI")])
3933 \f
3934 ;; Conversions between float and double.
3935
3936 ;; These are all no-ops in the model used for the 80387. So just
3937 ;; emit moves.
3938
3939 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3940 (define_insn "*dummy_extendsfdf2"
3941 [(set (match_operand:DF 0 "push_operand" "=<")
3942 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3943 "0"
3944 "#")
3945
3946 (define_split
3947 [(set (match_operand:DF 0 "push_operand" "")
3948 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3949 "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
3950 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3951 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3952
3953 (define_split
3954 [(set (match_operand:DF 0 "push_operand" "")
3955 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3956 "FP_REGNO_P (REGNO (operands[1])) && TARGET_64BIT"
3957 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3958 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3959
3960 (define_insn "*dummy_extendsfxf2"
3961 [(set (match_operand:XF 0 "push_operand" "=<")
3962 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3963 "0"
3964 "#")
3965
3966 (define_split
3967 [(set (match_operand:XF 0 "push_operand" "")
3968 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3969 "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
3970 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3971 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3972
3973 (define_insn "*dummy_extendsftf2"
3974 [(set (match_operand:TF 0 "push_operand" "=<")
3975 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3976 "0"
3977 "#")
3978
3979 (define_split
3980 [(set (match_operand:TF 0 "push_operand" "")
3981 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3982 "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
3983 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3984 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3985
3986 (define_split
3987 [(set (match_operand:TF 0 "push_operand" "")
3988 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3989 "FP_REGNO_P (REGNO (operands[1])) && TARGET_64BIT"
3990 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3991 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3992
3993 (define_insn "*dummy_extenddfxf2"
3994 [(set (match_operand:XF 0 "push_operand" "=<")
3995 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3996 "0"
3997 "#")
3998
3999 (define_split
4000 [(set (match_operand:XF 0 "push_operand" "")
4001 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
4002 "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
4003 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
4004 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4005
4006 (define_insn "*dummy_extenddftf2"
4007 [(set (match_operand:TF 0 "push_operand" "=<")
4008 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
4009 "0"
4010 "#")
4011
4012 (define_split
4013 [(set (match_operand:TF 0 "push_operand" "")
4014 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4015 "FP_REGNO_P (REGNO (operands[1])) && !TARGET_64BIT"
4016 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
4017 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
4018
4019 (define_split
4020 [(set (match_operand:TF 0 "push_operand" "")
4021 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
4022 "FP_REGNO_P (REGNO (operands[1])) && TARGET_64BIT"
4023 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
4024 (set (mem:TF (reg:DI 7)) (float_extend:XF (match_dup 1)))])
4025
4026 (define_expand "extendsfdf2"
4027 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4028 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
4029 "TARGET_80387 || TARGET_SSE2"
4030 "
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 {
4043 switch (which_alternative)
4044 {
4045 case 0:
4046 if (REG_P (operands[1])
4047 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4048 return \"fstp\\t%y0\";
4049 else if (STACK_TOP_P (operands[0]))
4050 return \"fld%z1\\t%y1\";
4051 else
4052 return \"fst\\t%y0\";
4053
4054 case 1:
4055 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4056 return \"fstp%z0\\t%y0\";
4057
4058 else
4059 return \"fst%z0\\t%y0\";
4060 case 2:
4061 return \"cvtss2sd\\t{%1, %0|%0, %1}\";
4062
4063 default:
4064 abort ();
4065 }
4066 }"
4067 [(set_attr "type" "fmov,fmov,sse")
4068 (set_attr "mode" "SF,XF,DF")])
4069
4070 (define_insn "*extendsfdf2_1_sse_only"
4071 [(set (match_operand:DF 0 "register_operand" "=Y")
4072 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
4073 "!TARGET_80387 && TARGET_SSE2
4074 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4075 "cvtss2sd\\t{%1, %0|%0, %1}"
4076 [(set_attr "type" "sse")
4077 (set_attr "mode" "DF")])
4078
4079 (define_expand "extendsfxf2"
4080 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4081 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
4082 "TARGET_80387 && !TARGET_64BIT"
4083 "
4084 {
4085 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4086 operands[1] = force_reg (SFmode, operands[1]);
4087 }")
4088
4089 (define_insn "*extendsfxf2_1"
4090 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4091 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4092 "TARGET_80387 && !TARGET_64BIT
4093 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4094 "*
4095 {
4096 switch (which_alternative)
4097 {
4098 case 0:
4099 if (REG_P (operands[1])
4100 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4101 return \"fstp\\t%y0\";
4102 else if (STACK_TOP_P (operands[0]))
4103 return \"fld%z1\\t%y1\";
4104 else
4105 return \"fst\\t%y0\";
4106
4107 case 1:
4108 /* There is no non-popping store to memory for XFmode. So if
4109 we need one, follow the store with a load. */
4110 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4111 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
4112 else
4113 return \"fstp%z0\\t%y0\";
4114
4115 default:
4116 abort ();
4117 }
4118 }"
4119 [(set_attr "type" "fmov")
4120 (set_attr "mode" "SF,XF")])
4121
4122 (define_expand "extendsftf2"
4123 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4124 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
4125 "TARGET_80387"
4126 "
4127 {
4128 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4129 operands[1] = force_reg (SFmode, operands[1]);
4130 }")
4131
4132 (define_insn "*extendsftf2_1"
4133 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4134 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4135 "TARGET_80387
4136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4137 "*
4138 {
4139 switch (which_alternative)
4140 {
4141 case 0:
4142 if (REG_P (operands[1])
4143 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4144 return \"fstp\\t%y0\";
4145 else if (STACK_TOP_P (operands[0]))
4146 return \"fld%z1\\t%y1\";
4147 else
4148 return \"fst\\t%y0\";
4149
4150 case 1:
4151 /* There is no non-popping store to memory for XFmode. So if
4152 we need one, follow the store with a load. */
4153 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4154 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
4155 else
4156 return \"fstp%z0\\t%y0\";
4157
4158 default:
4159 abort ();
4160 }
4161 }"
4162 [(set_attr "type" "fmov")
4163 (set_attr "mode" "SF,XF")])
4164
4165 (define_expand "extenddfxf2"
4166 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4167 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
4168 "TARGET_80387 && !TARGET_64BIT"
4169 "
4170 {
4171 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4172 operands[1] = force_reg (DFmode, operands[1]);
4173 }")
4174
4175 (define_insn "*extenddfxf2_1"
4176 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4177 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4178 "TARGET_80387 && !TARGET_64BIT
4179 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4180 "*
4181 {
4182 switch (which_alternative)
4183 {
4184 case 0:
4185 if (REG_P (operands[1])
4186 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4187 return \"fstp\\t%y0\";
4188 else if (STACK_TOP_P (operands[0]))
4189 return \"fld%z1\\t%y1\";
4190 else
4191 return \"fst\\t%y0\";
4192
4193 case 1:
4194 /* There is no non-popping store to memory for XFmode. So if
4195 we need one, follow the store with a load. */
4196 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4197 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
4198 else
4199 return \"fstp%z0\\t%y0\";
4200
4201 default:
4202 abort ();
4203 }
4204 }"
4205 [(set_attr "type" "fmov")
4206 (set_attr "mode" "DF,XF")])
4207
4208 (define_expand "extenddftf2"
4209 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4210 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
4211 "TARGET_80387"
4212 "
4213 {
4214 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
4215 operands[1] = force_reg (DFmode, operands[1]);
4216 }")
4217
4218 (define_insn "*extenddftf2_1"
4219 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
4220 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
4221 "TARGET_80387
4222 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4223 "*
4224 {
4225 switch (which_alternative)
4226 {
4227 case 0:
4228 if (REG_P (operands[1])
4229 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4230 return \"fstp\\t%y0\";
4231 else if (STACK_TOP_P (operands[0]))
4232 return \"fld%z1\\t%y1\";
4233 else
4234 return \"fst\\t%y0\";
4235
4236 case 1:
4237 /* There is no non-popping store to memory for XFmode. So if
4238 we need one, follow the store with a load. */
4239 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4240 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
4241 else
4242 return \"fstp%z0\\t%y0\";
4243
4244 default:
4245 abort ();
4246 }
4247 }"
4248 [(set_attr "type" "fmov")
4249 (set_attr "mode" "DF,XF")])
4250
4251 ;; %%% This seems bad bad news.
4252 ;; This cannot output into an f-reg because there is no way to be sure
4253 ;; of truncating in that case. Otherwise this is just like a simple move
4254 ;; insn. So we pretend we can output to a reg in order to get better
4255 ;; register preferencing, but we really use a stack slot.
4256
4257 (define_expand "truncdfsf2"
4258 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4259 (float_truncate:SF
4260 (match_operand:DF 1 "register_operand" "")))
4261 (clobber (match_dup 2))])]
4262 "TARGET_80387 || TARGET_SSE2"
4263 "
4264 if (TARGET_80387)
4265 operands[2] = assign_386_stack_local (SFmode, 0);
4266 else
4267 {
4268 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4269 DONE;
4270 }
4271 ")
4272
4273 (define_insn "*truncdfsf2_1"
4274 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4275 (float_truncate:SF
4276 (match_operand:DF 1 "register_operand" "f,f,f,f")))
4277 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4278 "TARGET_80387 && !TARGET_SSE2"
4279 "*
4280 {
4281 switch (which_alternative)
4282 {
4283 case 0:
4284 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4285 return \"fstp%z0\\t%y0\";
4286 else
4287 return \"fst%z0\\t%y0\";
4288 default:
4289 abort ();
4290 }
4291 }"
4292 [(set_attr "type" "fmov,multi,multi,multi")
4293 (set_attr "mode" "SF,SF,SF,SF")])
4294
4295 (define_insn "*truncdfsf2_1_sse"
4296 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
4297 (float_truncate:SF
4298 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
4299 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
4300 "TARGET_80387 && TARGET_SSE2"
4301 "*
4302 {
4303 switch (which_alternative)
4304 {
4305 case 0:
4306 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4307 return \"fstp%z0\\t%y0\";
4308 else
4309 return \"fst%z0\\t%y0\";
4310 case 4:
4311 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
4312 default:
4313 abort ();
4314 }
4315 }"
4316 [(set_attr "type" "fmov,multi,multi,multi,sse")
4317 (set_attr "mode" "SF,SF,SF,SF,DF")])
4318
4319 (define_insn "*truncdfsf2_2"
4320 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
4321 (float_truncate:SF
4322 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4323 "TARGET_80387 && TARGET_SSE2
4324 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4325 "*
4326 {
4327 switch (which_alternative)
4328 {
4329 case 0:
4330 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
4331 case 1:
4332 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4333 return \"fstp%z0\\t%y0\";
4334 else
4335 return \"fst%z0\\t%y0\";
4336 }
4337 }"
4338 [(set_attr "type" "sse,fmov")
4339 (set_attr "mode" "DF,SF")])
4340
4341 (define_insn "truncdfsf2_3"
4342 [(set (match_operand:SF 0 "memory_operand" "=m")
4343 (float_truncate:SF
4344 (match_operand:DF 1 "register_operand" "f")))]
4345 "TARGET_80387"
4346 "*
4347 {
4348 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4349 return \"fstp%z0\\t%y0\";
4350 else
4351 return \"fst%z0\\t%y0\";
4352 }"
4353 [(set_attr "type" "fmov")
4354 (set_attr "mode" "SF")])
4355
4356 (define_insn "truncdfsf2_sse_only"
4357 [(set (match_operand:SF 0 "register_operand" "=Y")
4358 (float_truncate:SF
4359 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4360 "!TARGET_80387 && TARGET_SSE2"
4361 "cvtsd2ss\\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "sse")
4363 (set_attr "mode" "DF")])
4364
4365 (define_split
4366 [(set (match_operand:SF 0 "memory_operand" "")
4367 (float_truncate:SF
4368 (match_operand:DF 1 "register_operand" "")))
4369 (clobber (match_operand:SF 2 "memory_operand" ""))]
4370 "TARGET_80387"
4371 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4372 "")
4373
4374 (define_split
4375 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4376 (float_truncate:SF
4377 (match_operand:DF 1 "nonimmediate_operand" "")))
4378 (clobber (match_operand 2 "" ""))]
4379 "TARGET_80387 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
4380 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4381 "")
4382
4383 (define_split
4384 [(set (match_operand:SF 0 "register_operand" "")
4385 (float_truncate:SF
4386 (match_operand:DF 1 "register_operand" "")))
4387 (clobber (match_operand:SF 2 "memory_operand" ""))]
4388 "TARGET_80387 && reload_completed
4389 && FP_REG_P (operands[1])"
4390 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4391 (set (match_dup 0) (match_dup 2))]
4392 "")
4393
4394 (define_expand "truncxfsf2"
4395 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4396 (float_truncate:SF
4397 (match_operand:XF 1 "register_operand" "")))
4398 (clobber (match_dup 2))])]
4399 "TARGET_80387 && !TARGET_64BIT"
4400 "operands[2] = assign_386_stack_local (SFmode, 0);")
4401
4402 (define_insn "*truncxfsf2_1"
4403 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4404 (float_truncate:SF
4405 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4406 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4407 "TARGET_80387 && !TARGET_64BIT"
4408 "*
4409 {
4410 switch (which_alternative)
4411 {
4412 case 0:
4413 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4414 return \"fstp%z0\\t%y0\";
4415 else
4416 return \"fst%z0\\t%y0\";
4417 default:
4418 abort();
4419 }
4420 }"
4421 [(set_attr "type" "fmov,multi,multi,multi")
4422 (set_attr "mode" "SF")])
4423
4424 (define_insn "*truncxfsf2_2"
4425 [(set (match_operand:SF 0 "memory_operand" "=m")
4426 (float_truncate:SF
4427 (match_operand:XF 1 "register_operand" "f")))]
4428 "TARGET_80387 && !TARGET_64BIT"
4429 "*
4430 {
4431 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4432 return \"fstp%z0\\t%y0\";
4433 else
4434 return \"fst%z0\\t%y0\";
4435 }"
4436 [(set_attr "type" "fmov")
4437 (set_attr "mode" "SF")])
4438
4439 (define_split
4440 [(set (match_operand:SF 0 "memory_operand" "")
4441 (float_truncate:SF
4442 (match_operand:XF 1 "register_operand" "")))
4443 (clobber (match_operand:SF 2 "memory_operand" ""))]
4444 "TARGET_80387"
4445 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4446 "")
4447
4448 (define_split
4449 [(set (match_operand:SF 0 "register_operand" "")
4450 (float_truncate:SF
4451 (match_operand:XF 1 "register_operand" "")))
4452 (clobber (match_operand:SF 2 "memory_operand" ""))]
4453 "TARGET_80387 && reload_completed"
4454 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4455 (set (match_dup 0) (match_dup 2))]
4456 "")
4457
4458 (define_expand "trunctfsf2"
4459 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4460 (float_truncate:SF
4461 (match_operand:TF 1 "register_operand" "")))
4462 (clobber (match_dup 2))])]
4463 "TARGET_80387"
4464 "operands[2] = assign_386_stack_local (SFmode, 0);")
4465
4466 (define_insn "*trunctfsf2_1"
4467 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4468 (float_truncate:SF
4469 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4470 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4471 "TARGET_80387"
4472 "*
4473 {
4474 switch (which_alternative)
4475 {
4476 case 0:
4477 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4478 return \"fstp%z0\\t%y0\";
4479 else
4480 return \"fst%z0\\t%y0\";
4481 default:
4482 abort();
4483 }
4484 }"
4485 [(set_attr "type" "fmov,multi,multi,multi")
4486 (set_attr "mode" "SF")])
4487
4488 (define_insn "*trunctfsf2_2"
4489 [(set (match_operand:SF 0 "memory_operand" "=m")
4490 (float_truncate:SF
4491 (match_operand:TF 1 "register_operand" "f")))]
4492 "TARGET_80387"
4493 "*
4494 {
4495 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4496 return \"fstp%z0\\t%y0\";
4497 else
4498 return \"fst%z0\\t%y0\";
4499 }"
4500 [(set_attr "type" "fmov")
4501 (set_attr "mode" "SF")])
4502
4503 (define_split
4504 [(set (match_operand:SF 0 "memory_operand" "")
4505 (float_truncate:SF
4506 (match_operand:TF 1 "register_operand" "")))
4507 (clobber (match_operand:SF 2 "memory_operand" ""))]
4508 "TARGET_80387"
4509 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4510 "")
4511
4512 (define_split
4513 [(set (match_operand:SF 0 "register_operand" "")
4514 (float_truncate:SF
4515 (match_operand:TF 1 "register_operand" "")))
4516 (clobber (match_operand:SF 2 "memory_operand" ""))]
4517 "TARGET_80387 && reload_completed"
4518 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4519 (set (match_dup 0) (match_dup 2))]
4520 "")
4521
4522
4523 (define_expand "truncxfdf2"
4524 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4525 (float_truncate:DF
4526 (match_operand:XF 1 "register_operand" "")))
4527 (clobber (match_dup 2))])]
4528 "TARGET_80387 && !TARGET_64BIT"
4529 "operands[2] = assign_386_stack_local (DFmode, 0);")
4530
4531 (define_insn "*truncxfdf2_1"
4532 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4533 (float_truncate:DF
4534 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4535 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4536 "TARGET_80387 && !TARGET_64BIT"
4537 "*
4538 {
4539 switch (which_alternative)
4540 {
4541 case 0:
4542 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4543 return \"fstp%z0\\t%y0\";
4544 else
4545 return \"fst%z0\\t%y0\";
4546 default:
4547 abort();
4548 }
4549 abort ();
4550 }"
4551 [(set_attr "type" "fmov,multi,multi,multi")
4552 (set_attr "mode" "DF")])
4553
4554 (define_insn "*truncxfdf2_2"
4555 [(set (match_operand:DF 0 "memory_operand" "=m")
4556 (float_truncate:DF
4557 (match_operand:XF 1 "register_operand" "f")))]
4558 "TARGET_80387 && !TARGET_64BIT"
4559 "*
4560 {
4561 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4562 return \"fstp%z0\\t%y0\";
4563 else
4564 return \"fst%z0\\t%y0\";
4565 }"
4566 [(set_attr "type" "fmov")
4567 (set_attr "mode" "DF")])
4568
4569 (define_split
4570 [(set (match_operand:DF 0 "memory_operand" "")
4571 (float_truncate:DF
4572 (match_operand:XF 1 "register_operand" "")))
4573 (clobber (match_operand:DF 2 "memory_operand" ""))]
4574 "TARGET_80387"
4575 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4576 "")
4577
4578 (define_split
4579 [(set (match_operand:DF 0 "register_operand" "")
4580 (float_truncate:DF
4581 (match_operand:XF 1 "register_operand" "")))
4582 (clobber (match_operand:DF 2 "memory_operand" ""))]
4583 "TARGET_80387 && reload_completed"
4584 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4585 (set (match_dup 0) (match_dup 2))]
4586 "")
4587
4588 (define_expand "trunctfdf2"
4589 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4590 (float_truncate:DF
4591 (match_operand:TF 1 "register_operand" "")))
4592 (clobber (match_dup 2))])]
4593 "TARGET_80387"
4594 "operands[2] = assign_386_stack_local (DFmode, 0);")
4595
4596 (define_insn "*trunctfdf2_1"
4597 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4598 (float_truncate:DF
4599 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4600 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4601 "TARGET_80387"
4602 "*
4603 {
4604 switch (which_alternative)
4605 {
4606 case 0:
4607 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4608 return \"fstp%z0\\t%y0\";
4609 else
4610 return \"fst%z0\\t%y0\";
4611 default:
4612 abort();
4613 }
4614 abort ();
4615 }"
4616 [(set_attr "type" "fmov,multi,multi,multi")
4617 (set_attr "mode" "DF")])
4618
4619 (define_insn "*trunctfdf2_2"
4620 [(set (match_operand:DF 0 "memory_operand" "=m")
4621 (float_truncate:DF
4622 (match_operand:TF 1 "register_operand" "f")))]
4623 "TARGET_80387"
4624 "*
4625 {
4626 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4627 return \"fstp%z0\\t%y0\";
4628 else
4629 return \"fst%z0\\t%y0\";
4630 }"
4631 [(set_attr "type" "fmov")
4632 (set_attr "mode" "DF")])
4633
4634 (define_split
4635 [(set (match_operand:DF 0 "memory_operand" "")
4636 (float_truncate:DF
4637 (match_operand:TF 1 "register_operand" "")))
4638 (clobber (match_operand:DF 2 "memory_operand" ""))]
4639 "TARGET_80387"
4640 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4641 "")
4642
4643 (define_split
4644 [(set (match_operand:DF 0 "register_operand" "")
4645 (float_truncate:DF
4646 (match_operand:TF 1 "register_operand" "")))
4647 (clobber (match_operand:DF 2 "memory_operand" ""))]
4648 "TARGET_80387 && reload_completed"
4649 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4650 (set (match_dup 0) (match_dup 2))]
4651 "")
4652
4653 \f
4654 ;; %%% Break up all these bad boys.
4655
4656 ;; Signed conversion to DImode.
4657
4658 (define_expand "fix_truncxfdi2"
4659 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4660 (fix:DI (match_operand:XF 1 "register_operand" "")))
4661 (clobber (match_dup 2))
4662 (clobber (match_dup 3))
4663 (clobber (match_scratch:SI 4 ""))
4664 (clobber (match_scratch:XF 5 ""))])]
4665 "TARGET_80387 && !TARGET_64BIT"
4666 "operands[2] = assign_386_stack_local (SImode, 0);
4667 operands[3] = assign_386_stack_local (DImode, 1);")
4668
4669 (define_expand "fix_trunctfdi2"
4670 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4671 (fix:DI (match_operand:TF 1 "register_operand" "")))
4672 (clobber (match_dup 2))
4673 (clobber (match_dup 3))
4674 (clobber (match_scratch:SI 4 ""))
4675 (clobber (match_scratch:TF 5 ""))])]
4676 "TARGET_80387"
4677 "operands[2] = assign_386_stack_local (SImode, 0);
4678 operands[3] = assign_386_stack_local (DImode, 1);")
4679
4680 (define_expand "fix_truncdfdi2"
4681 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4682 (fix:DI (match_operand:DF 1 "register_operand" "")))
4683 (clobber (match_dup 2))
4684 (clobber (match_dup 3))
4685 (clobber (match_scratch:SI 4 ""))
4686 (clobber (match_scratch:DF 5 ""))])]
4687 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4688 "
4689 {
4690 if (TARGET_SSE2)
4691 {
4692 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4693 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4694 if (out != operands[0])
4695 emit_move_insn (operands[0], out);
4696 DONE;
4697 }
4698 else
4699 {
4700 operands[2] = assign_386_stack_local (SImode, 0);
4701 operands[3] = assign_386_stack_local (DImode, 1);
4702 }
4703 }")
4704
4705 (define_expand "fix_truncsfdi2"
4706 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4707 (fix:DI (match_operand:SF 1 "register_operand" "")))
4708 (clobber (match_dup 2))
4709 (clobber (match_dup 3))
4710 (clobber (match_scratch:SI 4 ""))
4711 (clobber (match_scratch:SF 5 ""))])]
4712 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4713 "
4714 {
4715 if (TARGET_SSE2)
4716 {
4717 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4718 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4719 if (out != operands[0])
4720 emit_move_insn (operands[0], out);
4721 DONE;
4722 }
4723 else
4724 {
4725 operands[2] = assign_386_stack_local (SImode, 0);
4726 operands[3] = assign_386_stack_local (DImode, 1);
4727 }
4728 }")
4729
4730 (define_insn "*fix_truncdi_1"
4731 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4732 (fix:DI (match_operand 1 "register_operand" "f,f")))
4733 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4734 (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
4735 (clobber (match_scratch:SI 4 "=&r,&r"))
4736 (clobber (match_scratch 5 "=&f,&f"))]
4737 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4738 && (!TARGET_SSE2 || !TARGET_64BIT
4739 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4740 "* return output_fix_trunc (insn, operands);"
4741 [(set_attr "type" "multi")])
4742
4743 (define_split
4744 [(set (match_operand:DI 0 "register_operand" "")
4745 (fix:DI (match_operand 1 "register_operand" "")))
4746 (clobber (match_operand:SI 2 "memory_operand" ""))
4747 (clobber (match_operand:DI 3 "memory_operand" ""))
4748 (clobber (match_scratch:SI 4 ""))
4749 (clobber (match_scratch 5 ""))]
4750 "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
4751 [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
4752 (clobber (match_dup 2))
4753 (clobber (match_dup 3))
4754 (clobber (match_dup 4))
4755 (clobber (match_dup 5))])
4756 (set (match_dup 0) (match_dup 3))]
4757 "")
4758
4759 ;; When SSE available, it is always faster to use it!
4760 (define_insn "fix_truncsfdi_sse"
4761 [(set (match_operand:DI 0 "register_operand" "=r")
4762 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4763 "TARGET_SSE && TARGET_64BIT"
4764 "cvttss2si{q}\\t{%1, %0|%0, %1}"
4765 [(set_attr "type" "sse")])
4766
4767 (define_insn "fix_truncdfdi_sse"
4768 [(set (match_operand:DI 0 "register_operand" "=r")
4769 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4770 "TARGET_SSE2 && TARGET_64BIT"
4771 "cvttsd2si{q}\\t{%1, %0|%0, %1}"
4772 [(set_attr "type" "sse")])
4773
4774 ;; Signed conversion to SImode.
4775
4776 (define_expand "fix_truncxfsi2"
4777 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4778 (fix:SI (match_operand:XF 1 "register_operand" "")))
4779 (clobber (match_dup 2))
4780 (clobber (match_dup 3))
4781 (clobber (match_scratch:SI 4 ""))])]
4782 "TARGET_80387 && !TARGET_64BIT"
4783 "operands[2] = assign_386_stack_local (SImode, 0);
4784 operands[3] = assign_386_stack_local (SImode, 1);")
4785
4786 (define_expand "fix_trunctfsi2"
4787 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4788 (fix:SI (match_operand:TF 1 "register_operand" "")))
4789 (clobber (match_dup 2))
4790 (clobber (match_dup 3))
4791 (clobber (match_scratch:SI 4 ""))])]
4792 "TARGET_80387"
4793 "operands[2] = assign_386_stack_local (SImode, 0);
4794 operands[3] = assign_386_stack_local (SImode, 1);")
4795
4796 (define_expand "fix_truncdfsi2"
4797 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4798 (fix:SI (match_operand:DF 1 "register_operand" "")))
4799 (clobber (match_dup 2))
4800 (clobber (match_dup 3))
4801 (clobber (match_scratch:SI 4 ""))])]
4802 "TARGET_80387 || TARGET_SSE2"
4803 "
4804 {
4805 if (TARGET_SSE2)
4806 {
4807 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4808 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4809 if (out != operands[0])
4810 emit_move_insn (operands[0], out);
4811 DONE;
4812 }
4813 else
4814 {
4815 operands[2] = assign_386_stack_local (SImode, 0);
4816 operands[3] = assign_386_stack_local (SImode, 1);
4817 }
4818 }")
4819
4820 (define_expand "fix_truncsfsi2"
4821 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4822 (fix:SI (match_operand:SF 1 "register_operand" "")))
4823 (clobber (match_dup 2))
4824 (clobber (match_dup 3))
4825 (clobber (match_scratch:SI 4 ""))])]
4826 "TARGET_80387 || TARGET_SSE"
4827 "
4828 {
4829 if (TARGET_SSE2)
4830 {
4831 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4832 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4833 if (out != operands[0])
4834 emit_move_insn (operands[0], out);
4835 DONE;
4836 }
4837 else
4838 {
4839 operands[2] = assign_386_stack_local (SImode, 0);
4840 operands[3] = assign_386_stack_local (SImode, 1);
4841 }
4842 }")
4843
4844 (define_insn "*fix_truncsi_1"
4845 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4846 (fix:SI (match_operand 1 "register_operand" "f,f")))
4847 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4848 (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
4849 (clobber (match_scratch:SI 4 "=&r,r"))]
4850 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4851 && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4852 "* return output_fix_trunc (insn, operands);"
4853 [(set_attr "type" "multi")])
4854
4855 ;; When SSE available, it is always faster to use it!
4856 (define_insn "fix_truncsfsi_sse"
4857 [(set (match_operand:SI 0 "register_operand" "=r")
4858 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4859 "TARGET_SSE"
4860 "cvttss2si\\t{%1, %0|%0, %1}"
4861 [(set_attr "type" "sse")])
4862
4863 (define_insn "fix_truncdfsi_sse"
4864 [(set (match_operand:SI 0 "register_operand" "=r")
4865 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4866 "TARGET_SSE2"
4867 "cvttsd2si\\t{%1, %0|%0, %1}"
4868 [(set_attr "type" "sse")])
4869
4870 (define_split
4871 [(set (match_operand:SI 0 "register_operand" "")
4872 (fix:SI (match_operand 1 "register_operand" "")))
4873 (clobber (match_operand:SI 2 "memory_operand" ""))
4874 (clobber (match_operand:SI 3 "memory_operand" ""))
4875 (clobber (match_scratch:SI 4 ""))]
4876 "reload_completed"
4877 [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
4878 (clobber (match_dup 2))
4879 (clobber (match_dup 3))
4880 (clobber (match_dup 4))])
4881 (set (match_dup 0) (match_dup 3))]
4882 "")
4883
4884 ;; Signed conversion to HImode.
4885
4886 (define_expand "fix_truncxfhi2"
4887 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4888 (fix:HI (match_operand:XF 1 "register_operand" "")))
4889 (clobber (match_dup 2))
4890 (clobber (match_dup 3))
4891 (clobber (match_scratch:SI 4 ""))])]
4892 "TARGET_80387 && !TARGET_64BIT"
4893 "operands[2] = assign_386_stack_local (SImode, 0);
4894 operands[3] = assign_386_stack_local (HImode, 1);")
4895
4896 (define_expand "fix_trunctfhi2"
4897 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4898 (fix:HI (match_operand:TF 1 "register_operand" "")))
4899 (clobber (match_dup 2))
4900 (clobber (match_dup 3))
4901 (clobber (match_scratch:SI 4 ""))])]
4902 "TARGET_80387"
4903 "operands[2] = assign_386_stack_local (SImode, 0);
4904 operands[3] = assign_386_stack_local (HImode, 1);")
4905
4906 (define_expand "fix_truncdfhi2"
4907 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4908 (fix:HI (match_operand:DF 1 "register_operand" "")))
4909 (clobber (match_dup 2))
4910 (clobber (match_dup 3))
4911 (clobber (match_scratch:SI 4 ""))])]
4912 "TARGET_80387 && !TARGET_SSE2"
4913 "operands[2] = assign_386_stack_local (SImode, 0);
4914 operands[3] = assign_386_stack_local (HImode, 1);")
4915
4916 (define_expand "fix_truncsfhi2"
4917 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4918 (fix:HI (match_operand:SF 1 "register_operand" "")))
4919 (clobber (match_dup 2))
4920 (clobber (match_dup 3))
4921 (clobber (match_scratch:SI 4 ""))])]
4922 "TARGET_80387 && !TARGET_SSE"
4923 "operands[2] = assign_386_stack_local (SImode, 0);
4924 operands[3] = assign_386_stack_local (HImode, 1);")
4925
4926 (define_insn "*fix_trunchi_1"
4927 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4928 (fix:HI (match_operand 1 "register_operand" "f,f")))
4929 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4930 (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
4931 (clobber (match_scratch:SI 4 "=&r,r"))]
4932 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4933 && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4934 "* return output_fix_trunc (insn, operands);"
4935 [(set_attr "type" "multi")])
4936
4937 (define_split
4938 [(set (match_operand:HI 0 "register_operand" "")
4939 (fix:HI (match_operand 1 "register_operand" "")))
4940 (clobber (match_operand:SI 2 "memory_operand" ""))
4941 (clobber (match_operand:HI 3 "memory_operand" ""))
4942 (clobber (match_scratch:SI 4 ""))]
4943 "reload_completed"
4944 [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
4945 (clobber (match_dup 2))
4946 (clobber (match_dup 3))
4947 (clobber (match_dup 4))])
4948 (set (match_dup 0) (match_dup 3))]
4949 "")
4950
4951 ;; %%% Kill these when reload knows how to do it.
4952 (define_split
4953 [(set (match_operand 0 "register_operand" "")
4954 (fix (match_operand 1 "register_operand" "")))]
4955 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1]))
4956 && FP_REG_P (operands[1])"
4957 [(const_int 0)]
4958 "
4959 {
4960 operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]);
4961 operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]);
4962 emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
4963 emit_move_insn (operands[0], operands[2]);
4964 ix86_free_from_memory (GET_MODE (operands[0]));
4965 DONE;
4966 }")
4967
4968 ;; %% Not used yet.
4969 (define_insn "x86_fnstcw_1"
4970 [(set (match_operand:HI 0 "memory_operand" "=m")
4971 (unspec:HI [(reg:HI 18)] 11))]
4972 "TARGET_80387"
4973 "fnstcw\\t%0"
4974 [(set_attr "length" "2")
4975 (set_attr "mode" "HI")
4976 (set_attr "i387" "1")
4977 (set_attr "ppro_uops" "few")])
4978
4979 (define_insn "x86_fldcw_1"
4980 [(set (reg:HI 18)
4981 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
4982 "TARGET_80387"
4983 "fldcw\\t%0"
4984 [(set_attr "length" "2")
4985 (set_attr "mode" "HI")
4986 (set_attr "i387" "1")
4987 (set_attr "athlon_decode" "vector")
4988 (set_attr "ppro_uops" "few")])
4989 \f
4990 ;; Conversion between fixed point and floating point.
4991
4992 ;; Even though we only accept memory inputs, the backend _really_
4993 ;; wants to be able to do this between registers.
4994
4995 (define_insn "floathisf2"
4996 [(set (match_operand:SF 0 "register_operand" "=f,f")
4997 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4998 "TARGET_80387 && !TARGET_SSE"
4999 "@
5000 fild%z1\\t%1
5001 #"
5002 [(set_attr "type" "fmov,multi")
5003 (set_attr "mode" "SF")
5004 (set_attr "fp_int_src" "true")])
5005
5006 (define_expand "floatsisf2"
5007 [(set (match_operand:SF 0 "register_operand" "")
5008 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5009 "TARGET_SSE || TARGET_80387"
5010 "")
5011
5012 (define_insn "*floatsisf2_i387"
5013 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5014 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5015 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
5016 "@
5017 fild%z1\\t%1
5018 #
5019 cvtsi2ss\\t{%1, %0|%0, %1}"
5020 [(set_attr "type" "fmov,multi,sse")
5021 (set_attr "mode" "SF")
5022 (set_attr "fp_int_src" "true")])
5023
5024 (define_insn "*floatsisf2_sse"
5025 [(set (match_operand:SF 0 "register_operand" "=x")
5026 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5027 "TARGET_SSE"
5028 "cvtsi2ss\\t{%1, %0|%0, %1}"
5029 [(set_attr "type" "sse")
5030 (set_attr "mode" "SF")
5031 (set_attr "fp_int_src" "true")])
5032
5033 (define_expand "floatdisf2"
5034 [(set (match_operand:SF 0 "register_operand" "")
5035 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5036 "(TARGET_SSE && TARGET_64BIT) || TARGET_80387"
5037 "")
5038
5039 (define_insn "*floatdisf2_i387"
5040 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
5041 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5042 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5043 "@
5044 fild%z1\\t%1
5045 #
5046 cvtsi2ss{q}\\t{%1, %0|%0, %1}"
5047 [(set_attr "type" "fmov,multi,sse")
5048 (set_attr "mode" "SF")
5049 (set_attr "fp_int_src" "true")])
5050
5051 (define_insn "*floatdisf2_sse"
5052 [(set (match_operand:SF 0 "register_operand" "=x")
5053 (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5054 "TARGET_SSE && TARGET_64BIT"
5055 "cvtsi2ss{q}\\t{%1, %0|%0, %1}"
5056 [(set_attr "type" "sse")
5057 (set_attr "mode" "SF")
5058 (set_attr "fp_int_src" "true")])
5059
5060 (define_insn "floathidf2"
5061 [(set (match_operand:DF 0 "register_operand" "=f,f")
5062 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5063 "TARGET_80387 && !TARGET_SSE2"
5064 "@
5065 fild%z1\\t%1
5066 #"
5067 [(set_attr "type" "fmov,multi")
5068 (set_attr "mode" "DF")
5069 (set_attr "fp_int_src" "true")])
5070
5071 (define_expand "floatsidf2"
5072 [(set (match_operand:DF 0 "register_operand" "")
5073 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5074 ""
5075 "")
5076
5077 (define_insn "*floatsidf2_i387"
5078 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5079 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
5080 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5081 "@
5082 fild%z1\\t%1
5083 #
5084 cvtsi2sd\\t{%1, %0|%0, %1}"
5085 [(set_attr "type" "fmov,multi,sse")
5086 (set_attr "mode" "DF")
5087 (set_attr "fp_int_src" "true")])
5088
5089 (define_insn "*floatsidf2_sse"
5090 [(set (match_operand:DF 0 "register_operand" "=Y")
5091 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
5092 "TARGET_SSE2"
5093 "cvtsi2sd\\t{%1, %0|%0, %1}"
5094 [(set_attr "type" "sse")
5095 (set_attr "mode" "DF")
5096 (set_attr "fp_int_src" "true")])
5097
5098 (define_expand "floatdidf2"
5099 [(set (match_operand:DF 0 "register_operand" "")
5100 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5101 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
5102 "")
5103
5104 (define_insn "*floatdidf2_i387"
5105 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
5106 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
5107 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
5108 "@
5109 fild%z1\\t%1
5110 #
5111 cvtsi2sd{q}\\t{%1, %0|%0, %1}"
5112 [(set_attr "type" "fmov,multi,sse")
5113 (set_attr "mode" "DF")
5114 (set_attr "fp_int_src" "true")])
5115
5116 (define_insn "*floatdidf2_sse"
5117 [(set (match_operand:DF 0 "register_operand" "=Y")
5118 (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
5119 "TARGET_SSE2"
5120 "cvtsi2sd{q}\\t{%1, %0|%0, %1}"
5121 [(set_attr "type" "sse")
5122 (set_attr "mode" "DF")
5123 (set_attr "fp_int_src" "true")])
5124
5125 (define_insn "floathixf2"
5126 [(set (match_operand:XF 0 "register_operand" "=f,f")
5127 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5128 "TARGET_80387 && !TARGET_64BIT"
5129 "@
5130 fild%z1\\t%1
5131 #"
5132 [(set_attr "type" "fmov,multi")
5133 (set_attr "mode" "XF")
5134 (set_attr "fp_int_src" "true")])
5135
5136 (define_insn "floathitf2"
5137 [(set (match_operand:TF 0 "register_operand" "=f,f")
5138 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5139 "TARGET_80387"
5140 "@
5141 fild%z1\\t%1
5142 #"
5143 [(set_attr "type" "fmov,multi")
5144 (set_attr "mode" "XF")
5145 (set_attr "fp_int_src" "true")])
5146
5147 (define_insn "floatsixf2"
5148 [(set (match_operand:XF 0 "register_operand" "=f,f")
5149 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5150 "TARGET_80387 && !TARGET_64BIT"
5151 "@
5152 fild%z1\\t%1
5153 #"
5154 [(set_attr "type" "fmov,multi")
5155 (set_attr "mode" "XF")
5156 (set_attr "fp_int_src" "true")])
5157
5158 (define_insn "floatsitf2"
5159 [(set (match_operand:TF 0 "register_operand" "=f,f")
5160 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5161 "TARGET_80387"
5162 "@
5163 fild%z1\\t%1
5164 #"
5165 [(set_attr "type" "fmov,multi")
5166 (set_attr "mode" "XF")
5167 (set_attr "fp_int_src" "true")])
5168
5169 (define_insn "floatdixf2"
5170 [(set (match_operand:XF 0 "register_operand" "=f,f")
5171 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5172 "TARGET_80387 && !TARGET_64BIT"
5173 "@
5174 fild%z1\\t%1
5175 #"
5176 [(set_attr "type" "fmov,multi")
5177 (set_attr "mode" "XF")
5178 (set_attr "fp_int_src" "true")])
5179
5180 (define_insn "floatditf2"
5181 [(set (match_operand:TF 0 "register_operand" "=f,f")
5182 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5183 "TARGET_80387"
5184 "@
5185 fild%z1\\t%1
5186 #"
5187 [(set_attr "type" "fmov,multi")
5188 (set_attr "mode" "XF")
5189 (set_attr "fp_int_src" "true")])
5190
5191 ;; %%% Kill these when reload knows how to do it.
5192 (define_split
5193 [(set (match_operand 0 "register_operand" "")
5194 (float (match_operand 1 "register_operand" "")))]
5195 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
5196 && FP_REG_P (operands[0])"
5197 [(const_int 0)]
5198 "
5199 {
5200 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5201 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5202 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5203 ix86_free_from_memory (GET_MODE (operands[1]));
5204 DONE;
5205 }")
5206 \f
5207 ;; Add instructions
5208
5209 ;; %%% splits for addsidi3
5210 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5211 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5212 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5213
5214 (define_expand "adddi3"
5215 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5216 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5217 (match_operand:DI 2 "x86_64_general_operand" "")))
5218 (clobber (reg:CC 17))]
5219 ""
5220 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5221
5222 (define_insn "*adddi3_1"
5223 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5224 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5225 (match_operand:DI 2 "general_operand" "roiF,riF")))
5226 (clobber (reg:CC 17))]
5227 "!TARGET_64BIT"
5228 "#")
5229
5230 (define_split
5231 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5232 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5233 (match_operand:DI 2 "general_operand" "")))
5234 (clobber (reg:CC 17))]
5235 "reload_completed && !TARGET_64BIT"
5236 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
5237 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5238 (parallel [(set (match_dup 3)
5239 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5240 (match_dup 4))
5241 (match_dup 5)))
5242 (clobber (reg:CC 17))])]
5243 "split_di (operands+0, 1, operands+0, operands+3);
5244 split_di (operands+1, 1, operands+1, operands+4);
5245 split_di (operands+2, 1, operands+2, operands+5);")
5246
5247 (define_insn "*adddi3_carry_rex64"
5248 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5249 (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
5250 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5251 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5252 (clobber (reg:CC 17))]
5253 "ix86_binary_operator_ok (PLUS, DImode, operands)"
5254 "adc{q}\\t{%2, %0|%0, %2}"
5255 [(set_attr "type" "alu")
5256 (set_attr "pent_pair" "pu")
5257 (set_attr "mode" "DI")
5258 (set_attr "ppro_uops" "few")])
5259
5260 (define_insn "*adddi3_cc_rex64"
5261 [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5262 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
5263 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5264 (plus:DI (match_dup 1) (match_dup 2)))]
5265 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5266 "add{q}\\t{%2, %0|%0, %2}"
5267 [(set_attr "type" "alu")
5268 (set_attr "mode" "DI")])
5269
5270 (define_insn "*addsi3_carry"
5271 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5272 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5273 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5274 (match_operand:SI 2 "general_operand" "ri,rm")))
5275 (clobber (reg:CC 17))]
5276 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5277 "adc{l}\\t{%2, %0|%0, %2}"
5278 [(set_attr "type" "alu")
5279 (set_attr "pent_pair" "pu")
5280 (set_attr "mode" "SI")
5281 (set_attr "ppro_uops" "few")])
5282
5283 (define_insn "*addsi3_carry_zext"
5284 [(set (match_operand:DI 0 "register_operand" "=r")
5285 (zero_extend:DI
5286 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5287 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5288 (match_operand:SI 2 "general_operand" "rim"))))
5289 (clobber (reg:CC 17))]
5290 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5291 "adc{l}\\t{%2, %k0|%k0, %2}"
5292 [(set_attr "type" "alu")
5293 (set_attr "pent_pair" "pu")
5294 (set_attr "mode" "SI")
5295 (set_attr "ppro_uops" "few")])
5296
5297 (define_insn "*addsi3_cc"
5298 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5299 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
5300 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5301 (plus:SI (match_dup 1) (match_dup 2)))]
5302 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5303 "add{l}\\t{%2, %0|%0, %2}"
5304 [(set_attr "type" "alu")
5305 (set_attr "mode" "SI")])
5306
5307 (define_insn "addqi3_cc"
5308 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5309 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
5310 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5311 (plus:QI (match_dup 1) (match_dup 2)))]
5312 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5313 "add{b}\\t{%2, %0|%0, %2}"
5314 [(set_attr "type" "alu")
5315 (set_attr "mode" "QI")])
5316
5317 (define_expand "addsi3"
5318 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5319 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5320 (match_operand:SI 2 "general_operand" "")))
5321 (clobber (reg:CC 17))])]
5322 ""
5323 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5324
5325 (define_insn "*lea_1"
5326 [(set (match_operand:SI 0 "register_operand" "=r")
5327 (match_operand:SI 1 "address_operand" "p"))]
5328 "!TARGET_64BIT"
5329 "lea{l}\\t{%a1, %0|%0, %a1}"
5330 [(set_attr "type" "lea")
5331 (set_attr "mode" "SI")])
5332
5333 (define_insn "*lea_1_rex64"
5334 [(set (match_operand:SI 0 "register_operand" "=r")
5335 (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
5336 "TARGET_64BIT"
5337 "lea{l}\\t{%a1, %0|%0, %a1}"
5338 [(set_attr "type" "lea")
5339 (set_attr "mode" "SI")])
5340
5341 (define_insn "*lea_1_zext"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
5344 "TARGET_64BIT"
5345 "lea{l}\\t{%a1, %k0|%k0, %a1}"
5346 [(set_attr "type" "lea")
5347 (set_attr "mode" "SI")])
5348
5349 (define_insn "*lea_2_rex64"
5350 [(set (match_operand:DI 0 "register_operand" "=r")
5351 (match_operand:DI 1 "address_operand" "p"))]
5352 "TARGET_64BIT"
5353 "lea{q}\\t{%a1, %0|%0, %a1}"
5354 [(set_attr "type" "lea")
5355 (set_attr "mode" "DI")])
5356
5357 ;; The lea patterns for non-Pmodes needs to be matched by several
5358 ;; insns converted to real lea by splitters.
5359
5360 (define_insn_and_split "*lea_general_1"
5361 [(set (match_operand 0 "register_operand" "=r")
5362 (plus (plus (match_operand 1 "register_operand" "r")
5363 (match_operand 2 "register_operand" "r"))
5364 (match_operand 3 "immediate_operand" "i")))]
5365 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5366 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5367 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5368 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5369 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5370 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5371 || GET_MODE (operands[3]) == VOIDmode)"
5372 "#"
5373 "&& reload_completed"
5374 [(const_int 0)]
5375 "
5376 {
5377 rtx pat;
5378 operands[0] = gen_lowpart (SImode, operands[0]);
5379 operands[1] = gen_lowpart (Pmode, operands[1]);
5380 operands[2] = gen_lowpart (Pmode, operands[2]);
5381 operands[3] = gen_lowpart (Pmode, operands[3]);
5382 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5383 operands[3]);
5384 if (Pmode != SImode)
5385 pat = gen_rtx_SUBREG (SImode, pat, 0);
5386 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5387 DONE;
5388 }"
5389 [(set_attr "type" "lea")
5390 (set_attr "mode" "SI")])
5391
5392 (define_insn_and_split "*lea_general_1_zext"
5393 [(set (match_operand:DI 0 "register_operand" "=r")
5394 (zero_extend:DI
5395 (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5396 (match_operand:SI 2 "register_operand" "r"))
5397 (match_operand:SI 3 "immediate_operand" "i"))))]
5398 "TARGET_64BIT"
5399 "#"
5400 "&& reload_completed"
5401 [(set (match_dup 0)
5402 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5403 (match_dup 2))
5404 (match_dup 3)) 0)))]
5405 "
5406 {
5407 operands[1] = gen_lowpart (Pmode, operands[1]);
5408 operands[2] = gen_lowpart (Pmode, operands[2]);
5409 operands[3] = gen_lowpart (Pmode, operands[3]);
5410 }"
5411 [(set_attr "type" "lea")
5412 (set_attr "mode" "SI")])
5413
5414 (define_insn_and_split "*lea_general_2"
5415 [(set (match_operand 0 "register_operand" "=r")
5416 (plus (mult (match_operand 1 "register_operand" "r")
5417 (match_operand 2 "const248_operand" "i"))
5418 (match_operand 3 "nonmemory_operand" "ri")))]
5419 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5420 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5421 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5422 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5423 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5424 || GET_MODE (operands[3]) == VOIDmode)"
5425 "#"
5426 "&& reload_completed"
5427 [(const_int 0)]
5428 "
5429 {
5430 rtx pat;
5431 operands[0] = gen_lowpart (SImode, operands[0]);
5432 operands[1] = gen_lowpart (Pmode, operands[1]);
5433 operands[3] = gen_lowpart (Pmode, operands[3]);
5434 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5435 operands[3]);
5436 if (Pmode != SImode)
5437 pat = gen_rtx_SUBREG (SImode, pat, 0);
5438 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5439 DONE;
5440 }"
5441 [(set_attr "type" "lea")
5442 (set_attr "mode" "SI")])
5443
5444 (define_insn_and_split "*lea_general_2_zext"
5445 [(set (match_operand:DI 0 "register_operand" "=r")
5446 (zero_extend:DI
5447 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5448 (match_operand:SI 2 "const248_operand" "n"))
5449 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5450 "TARGET_64BIT"
5451 "#"
5452 "&& reload_completed"
5453 [(set (match_dup 0)
5454 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5455 (match_dup 2))
5456 (match_dup 3)) 0)))]
5457 "
5458 {
5459 operands[1] = gen_lowpart (Pmode, operands[1]);
5460 operands[3] = gen_lowpart (Pmode, operands[3]);
5461 }"
5462 [(set_attr "type" "lea")
5463 (set_attr "mode" "SI")])
5464
5465 (define_insn_and_split "*lea_general_3"
5466 [(set (match_operand 0 "register_operand" "=r")
5467 (plus (plus (mult (match_operand 1 "register_operand" "r")
5468 (match_operand 2 "const248_operand" "i"))
5469 (match_operand 3 "register_operand" "r"))
5470 (match_operand 4 "immediate_operand" "i")))]
5471 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5472 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5473 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5474 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5475 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5476 "#"
5477 "&& reload_completed"
5478 [(const_int 0)]
5479 "
5480 {
5481 rtx pat;
5482 operands[0] = gen_lowpart (SImode, operands[0]);
5483 operands[1] = gen_lowpart (Pmode, operands[1]);
5484 operands[3] = gen_lowpart (Pmode, operands[3]);
5485 operands[4] = gen_lowpart (Pmode, operands[4]);
5486 pat = gen_rtx_PLUS (Pmode,
5487 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5488 operands[2]),
5489 operands[3]),
5490 operands[4]);
5491 if (Pmode != SImode)
5492 pat = gen_rtx_SUBREG (SImode, pat, 0);
5493 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5494 DONE;
5495 }"
5496 [(set_attr "type" "lea")
5497 (set_attr "mode" "SI")])
5498
5499 (define_insn_and_split "*lea_general_3_zext"
5500 [(set (match_operand:DI 0 "register_operand" "=r")
5501 (zero_extend:DI
5502 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
5503 (match_operand:SI 2 "const248_operand" "n"))
5504 (match_operand:SI 3 "register_operand" "r"))
5505 (match_operand:SI 4 "immediate_operand" "i"))))]
5506 "TARGET_64BIT"
5507 "#"
5508 "&& reload_completed"
5509 [(set (match_dup 0)
5510 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5511 (match_dup 2))
5512 (match_dup 3))
5513 (match_dup 4)) 0)))]
5514 "
5515 {
5516 operands[1] = gen_lowpart (Pmode, operands[1]);
5517 operands[3] = gen_lowpart (Pmode, operands[3]);
5518 operands[4] = gen_lowpart (Pmode, operands[4]);
5519 }"
5520 [(set_attr "type" "lea")
5521 (set_attr "mode" "SI")])
5522
5523 (define_insn "*adddi_1_rex64"
5524 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5525 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5526 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5527 (clobber (reg:CC 17))]
5528 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5529 "*
5530 {
5531 switch (get_attr_type (insn))
5532 {
5533 case TYPE_LEA:
5534 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5535 return \"lea{q}\\t{%a2, %0|%0, %a2}\";
5536
5537 case TYPE_INCDEC:
5538 if (! rtx_equal_p (operands[0], operands[1]))
5539 abort ();
5540 if (operands[2] == const1_rtx)
5541 return \"inc{q}\\t%0\";
5542 else if (operands[2] == constm1_rtx)
5543 return \"dec{q}\\t%0\";
5544 else
5545 abort ();
5546
5547 default:
5548 if (! rtx_equal_p (operands[0], operands[1]))
5549 abort ();
5550
5551 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5552 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5553 if (GET_CODE (operands[2]) == CONST_INT
5554 && (INTVAL (operands[2]) == 128
5555 || (INTVAL (operands[2]) < 0
5556 && INTVAL (operands[2]) != -128)))
5557 {
5558 operands[2] = GEN_INT (-INTVAL (operands[2]));
5559 return \"sub{q}\\t{%2, %0|%0, %2}\";
5560 }
5561 return \"add{q}\\t{%2, %0|%0, %2}\";
5562 }
5563 }"
5564 [(set (attr "type")
5565 (cond [(eq_attr "alternative" "2")
5566 (const_string "lea")
5567 ; Current assemblers are broken and do not allow @GOTOFF in
5568 ; ought but a memory context.
5569 (match_operand:DI 2 "pic_symbolic_operand" "")
5570 (const_string "lea")
5571 (match_operand:DI 2 "incdec_operand" "")
5572 (const_string "incdec")
5573 ]
5574 (const_string "alu")))
5575 (set_attr "mode" "DI")])
5576
5577 ;; Convert lea to the lea pattern to avoid flags dependency.
5578 (define_split
5579 [(set (match_operand:DI 0 "register_operand" "")
5580 (plus:DI (match_operand:DI 1 "register_operand" "")
5581 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5582 (clobber (reg:CC 17))]
5583 "reload_completed && TARGET_64BIT
5584 && true_regnum (operands[0]) != true_regnum (operands[1])"
5585 [(set (match_dup 0)
5586 (plus:DI (match_dup 1)
5587 (match_dup 2)))]
5588 "")
5589
5590 (define_insn "*adddi_2_rex64"
5591 [(set (reg 17)
5592 (compare
5593 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5594 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5595 (const_int 0)))
5596 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5597 (plus:DI (match_dup 1) (match_dup 2)))]
5598 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5599 && ix86_binary_operator_ok (PLUS, DImode, operands)
5600 /* Current assemblers are broken and do not allow @GOTOFF in
5601 ought but a memory context. */
5602 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5603 "*
5604 {
5605 switch (get_attr_type (insn))
5606 {
5607 case TYPE_INCDEC:
5608 if (! rtx_equal_p (operands[0], operands[1]))
5609 abort ();
5610 if (operands[2] == const1_rtx)
5611 return \"inc{q}\\t%0\";
5612 else if (operands[2] == constm1_rtx)
5613 return \"dec{q}\\t%0\";
5614 else
5615 abort ();
5616
5617 default:
5618 if (! rtx_equal_p (operands[0], operands[1]))
5619 abort ();
5620 /* ???? We ought to handle there the 32bit case too
5621 - do we need new constrant? */
5622 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5623 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5624 if (GET_CODE (operands[2]) == CONST_INT
5625 && (INTVAL (operands[2]) == 128
5626 || (INTVAL (operands[2]) < 0
5627 && INTVAL (operands[2]) != -128)))
5628 {
5629 operands[2] = GEN_INT (-INTVAL (operands[2]));
5630 return \"sub{q}\\t{%2, %0|%0, %2}\";
5631 }
5632 return \"add{q}\\t{%2, %0|%0, %2}\";
5633 }
5634 }"
5635 [(set (attr "type")
5636 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5637 (const_string "incdec")
5638 (const_string "alu")))
5639 (set_attr "mode" "DI")])
5640
5641 (define_insn "*adddi_3_rex64"
5642 [(set (reg 17)
5643 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5644 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5645 (clobber (match_scratch:DI 0 "=r"))]
5646 "TARGET_64BIT
5647 && ix86_match_ccmode (insn, CCZmode)
5648 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5649 /* Current assemblers are broken and do not allow @GOTOFF in
5650 ought but a memory context. */
5651 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5652 "*
5653 {
5654 switch (get_attr_type (insn))
5655 {
5656 case TYPE_INCDEC:
5657 if (! rtx_equal_p (operands[0], operands[1]))
5658 abort ();
5659 if (operands[2] == const1_rtx)
5660 return \"inc{q}\\t%0\";
5661 else if (operands[2] == constm1_rtx)
5662 return \"dec{q}\\t%0\";
5663 else
5664 abort ();
5665
5666 default:
5667 if (! rtx_equal_p (operands[0], operands[1]))
5668 abort ();
5669 /* ???? We ought to handle there the 32bit case too
5670 - do we need new constrant? */
5671 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5672 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5673 if (GET_CODE (operands[2]) == CONST_INT
5674 && (INTVAL (operands[2]) == 128
5675 || (INTVAL (operands[2]) < 0
5676 && INTVAL (operands[2]) != -128)))
5677 {
5678 operands[2] = GEN_INT (-INTVAL (operands[2]));
5679 return \"sub{q}\\t{%2, %0|%0, %2}\";
5680 }
5681 return \"add{q}\\t{%2, %0|%0, %2}\";
5682 }
5683 }"
5684 [(set (attr "type")
5685 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5686 (const_string "incdec")
5687 (const_string "alu")))
5688 (set_attr "mode" "DI")])
5689
5690 ; For comparisons against 1, -1 and 128, we may generate better code
5691 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5692 ; is matched then. We can't accept general immediate, because for
5693 ; case of overflows, the result is messed up.
5694 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5695 ; when negated.
5696 ; Also carry flag is reversed compared to cmp, so this converison is valid
5697 ; only for comparisons not depending on it.
5698 (define_insn "*adddi_4_rex64"
5699 [(set (reg 17)
5700 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5701 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5702 (clobber (match_scratch:DI 0 "=rm"))]
5703 "TARGET_64BIT
5704 && ix86_match_ccmode (insn, CCGCmode)"
5705 "*
5706 {
5707 switch (get_attr_type (insn))
5708 {
5709 case TYPE_INCDEC:
5710 if (operands[2] == constm1_rtx)
5711 return \"inc{q}\\t%0\";
5712 else if (operands[2] == const1_rtx)
5713 return \"dec{q}\\t%0\";
5714 else
5715 abort();
5716
5717 default:
5718 if (! rtx_equal_p (operands[0], operands[1]))
5719 abort ();
5720 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5721 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5722 if ((INTVAL (operands[2]) == -128
5723 || (INTVAL (operands[2]) > 0
5724 && INTVAL (operands[2]) != 128)))
5725 return \"sub{q}\\t{%2, %0|%0, %2}\";
5726 operands[2] = GEN_INT (-INTVAL (operands[2]));
5727 return \"add{q}\\t{%2, %0|%0, %2}\";
5728 }
5729 }"
5730 [(set (attr "type")
5731 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5732 (const_string "incdec")
5733 (const_string "alu")))
5734 (set_attr "mode" "DI")])
5735
5736 (define_insn "*adddi_5_rex64"
5737 [(set (reg 17)
5738 (compare
5739 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5740 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5741 (const_int 0)))
5742 (clobber (match_scratch:DI 0 "=r"))]
5743 "TARGET_64BIT
5744 && ix86_match_ccmode (insn, CCGOCmode)
5745 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5746 /* Current assemblers are broken and do not allow @GOTOFF in
5747 ought but a memory context. */
5748 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5749 "*
5750 {
5751 switch (get_attr_type (insn))
5752 {
5753 case TYPE_INCDEC:
5754 if (! rtx_equal_p (operands[0], operands[1]))
5755 abort ();
5756 if (operands[2] == const1_rtx)
5757 return \"inc{q}\\t%0\";
5758 else if (operands[2] == constm1_rtx)
5759 return \"dec{q}\\t%0\";
5760 else
5761 abort();
5762
5763 default:
5764 if (! rtx_equal_p (operands[0], operands[1]))
5765 abort ();
5766 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5767 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5768 if (GET_CODE (operands[2]) == CONST_INT
5769 && (INTVAL (operands[2]) == 128
5770 || (INTVAL (operands[2]) < 0
5771 && INTVAL (operands[2]) != -128)))
5772 {
5773 operands[2] = GEN_INT (-INTVAL (operands[2]));
5774 return \"sub{q}\\t{%2, %0|%0, %2}\";
5775 }
5776 return \"add{q}\\t{%2, %0|%0, %2}\";
5777 }
5778 }"
5779 [(set (attr "type")
5780 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5781 (const_string "incdec")
5782 (const_string "alu")))
5783 (set_attr "mode" "DI")])
5784
5785
5786 (define_insn "*addsi_1"
5787 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5788 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5789 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5790 (clobber (reg:CC 17))]
5791 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5792 "*
5793 {
5794 switch (get_attr_type (insn))
5795 {
5796 case TYPE_LEA:
5797 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5798 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
5799
5800 case TYPE_INCDEC:
5801 if (! rtx_equal_p (operands[0], operands[1]))
5802 abort ();
5803 if (operands[2] == const1_rtx)
5804 return \"inc{l}\\t%0\";
5805 else if (operands[2] == constm1_rtx)
5806 return \"dec{l}\\t%0\";
5807 else
5808 abort();
5809
5810 default:
5811 if (! rtx_equal_p (operands[0], operands[1]))
5812 abort ();
5813
5814 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5815 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5816 if (GET_CODE (operands[2]) == CONST_INT
5817 && (INTVAL (operands[2]) == 128
5818 || (INTVAL (operands[2]) < 0
5819 && INTVAL (operands[2]) != -128)))
5820 {
5821 operands[2] = GEN_INT (-INTVAL (operands[2]));
5822 return \"sub{l}\\t{%2, %0|%0, %2}\";
5823 }
5824 return \"add{l}\\t{%2, %0|%0, %2}\";
5825 }
5826 }"
5827 [(set (attr "type")
5828 (cond [(eq_attr "alternative" "2")
5829 (const_string "lea")
5830 ; Current assemblers are broken and do not allow @GOTOFF in
5831 ; ought but a memory context.
5832 (match_operand:SI 2 "pic_symbolic_operand" "")
5833 (const_string "lea")
5834 (match_operand:SI 2 "incdec_operand" "")
5835 (const_string "incdec")
5836 ]
5837 (const_string "alu")))
5838 (set_attr "mode" "SI")])
5839
5840 ;; Convert lea to the lea pattern to avoid flags dependency.
5841 (define_split
5842 [(set (match_operand 0 "register_operand" "")
5843 (plus (match_operand 1 "register_operand" "")
5844 (match_operand 2 "nonmemory_operand" "")))
5845 (clobber (reg:CC 17))]
5846 "reload_completed
5847 && true_regnum (operands[0]) != true_regnum (operands[1])"
5848 [(const_int 0)]
5849 "
5850 {
5851 rtx pat;
5852 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5853 may confuse gen_lowpart. */
5854 if (GET_MODE (operands[0]) != Pmode)
5855 {
5856 operands[1] = gen_lowpart (Pmode, operands[1]);
5857 operands[2] = gen_lowpart (Pmode, operands[2]);
5858 }
5859 operands[0] = gen_lowpart (SImode, operands[0]);
5860 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5861 if (Pmode != SImode)
5862 pat = gen_rtx_SUBREG (SImode, pat, 0);
5863 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5864 DONE;
5865 }")
5866
5867 ;; It may seem that nonimmediate operand is proper one for operand 1.
5868 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5869 ;; we take care in ix86_binary_operator_ok to not allow two memory
5870 ;; operands so proper swapping will be done in reload. This allow
5871 ;; patterns constructed from addsi_1 to match.
5872 (define_insn "addsi_1_zext"
5873 [(set (match_operand:DI 0 "register_operand" "=r,r")
5874 (zero_extend:DI
5875 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5876 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5877 (clobber (reg:CC 17))]
5878 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5879 "*
5880 {
5881 switch (get_attr_type (insn))
5882 {
5883 case TYPE_LEA:
5884 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5885 return \"lea{l}\\t{%a2, %k0|%k0, %a2}\";
5886
5887 case TYPE_INCDEC:
5888 if (operands[2] == const1_rtx)
5889 return \"inc{l}\\t%k0\";
5890 else if (operands[2] == constm1_rtx)
5891 return \"dec{l}\\t%k0\";
5892 else
5893 abort();
5894
5895 default:
5896 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5897 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5898 if (GET_CODE (operands[2]) == CONST_INT
5899 && (INTVAL (operands[2]) == 128
5900 || (INTVAL (operands[2]) < 0
5901 && INTVAL (operands[2]) != -128)))
5902 {
5903 operands[2] = GEN_INT (-INTVAL (operands[2]));
5904 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5905 }
5906 return \"add{l}\\t{%2, %k0|%k0, %2}\";
5907 }
5908 }"
5909 [(set (attr "type")
5910 (cond [(eq_attr "alternative" "1")
5911 (const_string "lea")
5912 ; Current assemblers are broken and do not allow @GOTOFF in
5913 ; ought but a memory context.
5914 (match_operand:SI 2 "pic_symbolic_operand" "")
5915 (const_string "lea")
5916 (match_operand:SI 2 "incdec_operand" "")
5917 (const_string "incdec")
5918 ]
5919 (const_string "alu")))
5920 (set_attr "mode" "SI")])
5921
5922 ;; Convert lea to the lea pattern to avoid flags dependency.
5923 (define_split
5924 [(set (match_operand:DI 0 "register_operand" "")
5925 (zero_extend:DI
5926 (plus:SI (match_operand:SI 1 "register_operand" "")
5927 (match_operand:SI 2 "nonmemory_operand" ""))))
5928 (clobber (reg:CC 17))]
5929 "reload_completed
5930 && true_regnum (operands[0]) != true_regnum (operands[1])"
5931 [(set (match_dup 0)
5932 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5933 "
5934 {
5935 operands[1] = gen_lowpart (Pmode, operands[1]);
5936 operands[2] = gen_lowpart (Pmode, operands[2]);
5937 }")
5938
5939 (define_insn "*addsi_2"
5940 [(set (reg 17)
5941 (compare
5942 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5943 (match_operand:SI 2 "general_operand" "rmni,rni"))
5944 (const_int 0)))
5945 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5946 (plus:SI (match_dup 1) (match_dup 2)))]
5947 "ix86_match_ccmode (insn, CCGOCmode)
5948 && ix86_binary_operator_ok (PLUS, SImode, operands)
5949 /* Current assemblers are broken and do not allow @GOTOFF in
5950 ought but a memory context. */
5951 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5952 "*
5953 {
5954 switch (get_attr_type (insn))
5955 {
5956 case TYPE_INCDEC:
5957 if (! rtx_equal_p (operands[0], operands[1]))
5958 abort ();
5959 if (operands[2] == const1_rtx)
5960 return \"inc{l}\\t%0\";
5961 else if (operands[2] == constm1_rtx)
5962 return \"dec{l}\\t%0\";
5963 else
5964 abort();
5965
5966 default:
5967 if (! rtx_equal_p (operands[0], operands[1]))
5968 abort ();
5969 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5971 if (GET_CODE (operands[2]) == CONST_INT
5972 && (INTVAL (operands[2]) == 128
5973 || (INTVAL (operands[2]) < 0
5974 && INTVAL (operands[2]) != -128)))
5975 {
5976 operands[2] = GEN_INT (-INTVAL (operands[2]));
5977 return \"sub{l}\\t{%2, %0|%0, %2}\";
5978 }
5979 return \"add{l}\\t{%2, %0|%0, %2}\";
5980 }
5981 }"
5982 [(set (attr "type")
5983 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5984 (const_string "incdec")
5985 (const_string "alu")))
5986 (set_attr "mode" "SI")])
5987
5988 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5989 (define_insn "*addsi_2_zext"
5990 [(set (reg 17)
5991 (compare
5992 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5993 (match_operand:SI 2 "general_operand" "rmni"))
5994 (const_int 0)))
5995 (set (match_operand:DI 0 "register_operand" "=r")
5996 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5997 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5998 && ix86_binary_operator_ok (PLUS, SImode, operands)
5999 /* Current assemblers are broken and do not allow @GOTOFF in
6000 ought but a memory context. */
6001 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6002 "*
6003 {
6004 switch (get_attr_type (insn))
6005 {
6006 case TYPE_INCDEC:
6007 if (operands[2] == const1_rtx)
6008 return \"inc{l}\\t%k0\";
6009 else if (operands[2] == constm1_rtx)
6010 return \"dec{l}\\t%k0\";
6011 else
6012 abort();
6013
6014 default:
6015 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6016 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6017 if (GET_CODE (operands[2]) == CONST_INT
6018 && (INTVAL (operands[2]) == 128
6019 || (INTVAL (operands[2]) < 0
6020 && INTVAL (operands[2]) != -128)))
6021 {
6022 operands[2] = GEN_INT (-INTVAL (operands[2]));
6023 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
6024 }
6025 return \"add{l}\\t{%2, %k0|%k0, %2}\";
6026 }
6027 }"
6028 [(set (attr "type")
6029 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6030 (const_string "incdec")
6031 (const_string "alu")))
6032 (set_attr "mode" "SI")])
6033
6034 (define_insn "*addsi_3"
6035 [(set (reg 17)
6036 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6037 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6038 (clobber (match_scratch:SI 0 "=r"))]
6039 "ix86_match_ccmode (insn, CCZmode)
6040 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6041 /* Current assemblers are broken and do not allow @GOTOFF in
6042 ought but a memory context. */
6043 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6044 "*
6045 {
6046 switch (get_attr_type (insn))
6047 {
6048 case TYPE_INCDEC:
6049 if (! rtx_equal_p (operands[0], operands[1]))
6050 abort ();
6051 if (operands[2] == const1_rtx)
6052 return \"inc{l}\\t%0\";
6053 else if (operands[2] == constm1_rtx)
6054 return \"dec{l}\\t%0\";
6055 else
6056 abort();
6057
6058 default:
6059 if (! rtx_equal_p (operands[0], operands[1]))
6060 abort ();
6061 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6063 if (GET_CODE (operands[2]) == CONST_INT
6064 && (INTVAL (operands[2]) == 128
6065 || (INTVAL (operands[2]) < 0
6066 && INTVAL (operands[2]) != -128)))
6067 {
6068 operands[2] = GEN_INT (-INTVAL (operands[2]));
6069 return \"sub{l}\\t{%2, %0|%0, %2}\";
6070 }
6071 return \"add{l}\\t{%2, %0|%0, %2}\";
6072 }
6073 }"
6074 [(set (attr "type")
6075 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set_attr "mode" "SI")])
6079
6080 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6081 (define_insn "*addsi_3_zext"
6082 [(set (reg 17)
6083 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6084 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6085 (set (match_operand:DI 0 "register_operand" "=r")
6086 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6087 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6088 && ix86_binary_operator_ok (PLUS, SImode, operands)
6089 /* Current assemblers are broken and do not allow @GOTOFF in
6090 ought but a memory context. */
6091 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6092 "*
6093 {
6094 switch (get_attr_type (insn))
6095 {
6096 case TYPE_INCDEC:
6097 if (operands[2] == const1_rtx)
6098 return \"inc{l}\\t%k0\";
6099 else if (operands[2] == constm1_rtx)
6100 return \"dec{l}\\t%k0\";
6101 else
6102 abort();
6103
6104 default:
6105 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6106 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6107 if (GET_CODE (operands[2]) == CONST_INT
6108 && (INTVAL (operands[2]) == 128
6109 || (INTVAL (operands[2]) < 0
6110 && INTVAL (operands[2]) != -128)))
6111 {
6112 operands[2] = GEN_INT (-INTVAL (operands[2]));
6113 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
6114 }
6115 return \"add{l}\\t{%2, %k0|%k0, %2}\";
6116 }
6117 }"
6118 [(set (attr "type")
6119 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6120 (const_string "incdec")
6121 (const_string "alu")))
6122 (set_attr "mode" "SI")])
6123
6124 ; For comparisons agains 1, -1 and 128, we may generate better code
6125 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6126 ; is matched then. We can't accept general immediate, because for
6127 ; case of overflows, the result is messed up.
6128 ; This pattern also don't hold of 0x80000000, since the value overflows
6129 ; when negated.
6130 ; Also carry flag is reversed compared to cmp, so this converison is valid
6131 ; only for comparisons not depending on it.
6132 (define_insn "*addsi_4"
6133 [(set (reg 17)
6134 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6135 (match_operand:SI 2 "const_int_operand" "n")))
6136 (clobber (match_scratch:SI 0 "=rm"))]
6137 "ix86_match_ccmode (insn, CCGCmode)
6138 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6139 "*
6140 {
6141 switch (get_attr_type (insn))
6142 {
6143 case TYPE_INCDEC:
6144 if (operands[2] == constm1_rtx)
6145 return \"inc{l}\\t%0\";
6146 else if (operands[2] == const1_rtx)
6147 return \"dec{l}\\t%0\";
6148 else
6149 abort();
6150
6151 default:
6152 if (! rtx_equal_p (operands[0], operands[1]))
6153 abort ();
6154 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6155 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6156 if ((INTVAL (operands[2]) == -128
6157 || (INTVAL (operands[2]) > 0
6158 && INTVAL (operands[2]) != 128)))
6159 return \"sub{l}\\t{%2, %0|%0, %2}\";
6160 operands[2] = GEN_INT (-INTVAL (operands[2]));
6161 return \"add{l}\\t{%2, %0|%0, %2}\";
6162 }
6163 }"
6164 [(set (attr "type")
6165 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "mode" "SI")])
6169
6170 (define_insn "*addsi_5"
6171 [(set (reg 17)
6172 (compare
6173 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6174 (match_operand:SI 2 "general_operand" "rmni"))
6175 (const_int 0)))
6176 (clobber (match_scratch:SI 0 "=r"))]
6177 "ix86_match_ccmode (insn, CCGOCmode)
6178 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6179 /* Current assemblers are broken and do not allow @GOTOFF in
6180 ought but a memory context. */
6181 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6182 "*
6183 {
6184 switch (get_attr_type (insn))
6185 {
6186 case TYPE_INCDEC:
6187 if (! rtx_equal_p (operands[0], operands[1]))
6188 abort ();
6189 if (operands[2] == const1_rtx)
6190 return \"inc{l}\\t%0\";
6191 else if (operands[2] == constm1_rtx)
6192 return \"dec{l}\\t%0\";
6193 else
6194 abort();
6195
6196 default:
6197 if (! rtx_equal_p (operands[0], operands[1]))
6198 abort ();
6199 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6200 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6201 if (GET_CODE (operands[2]) == CONST_INT
6202 && (INTVAL (operands[2]) == 128
6203 || (INTVAL (operands[2]) < 0
6204 && INTVAL (operands[2]) != -128)))
6205 {
6206 operands[2] = GEN_INT (-INTVAL (operands[2]));
6207 return \"sub{l}\\t{%2, %0|%0, %2}\";
6208 }
6209 return \"add{l}\\t{%2, %0|%0, %2}\";
6210 }
6211 }"
6212 [(set (attr "type")
6213 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6214 (const_string "incdec")
6215 (const_string "alu")))
6216 (set_attr "mode" "SI")])
6217
6218 (define_expand "addhi3"
6219 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6220 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6221 (match_operand:HI 2 "general_operand" "")))
6222 (clobber (reg:CC 17))])]
6223 "TARGET_HIMODE_MATH"
6224 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6225
6226 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6227 ;; type optimizations enabled by define-splits. This is not important
6228 ;; for PII, and in fact harmful because of partial register stalls.
6229
6230 (define_insn "*addhi_1_lea"
6231 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6232 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6233 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6234 (clobber (reg:CC 17))]
6235 "!TARGET_PARTIAL_REG_STALL
6236 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6237 "*
6238 {
6239 switch (get_attr_type (insn))
6240 {
6241 case TYPE_LEA:
6242 return \"#\";
6243 case TYPE_INCDEC:
6244 if (operands[2] == const1_rtx)
6245 return \"inc{w}\\t%0\";
6246 else if (operands[2] == constm1_rtx
6247 || (GET_CODE (operands[2]) == CONST_INT
6248 && INTVAL (operands[2]) == 65535))
6249 return \"dec{w}\\t%0\";
6250 abort();
6251
6252 default:
6253 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6254 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6255 if (GET_CODE (operands[2]) == CONST_INT
6256 && (INTVAL (operands[2]) == 128
6257 || (INTVAL (operands[2]) < 0
6258 && INTVAL (operands[2]) != -128)))
6259 {
6260 operands[2] = GEN_INT (-INTVAL (operands[2]));
6261 return \"sub{w}\\t{%2, %0|%0, %2}\";
6262 }
6263 return \"add{w}\\t{%2, %0|%0, %2}\";
6264 }
6265 }"
6266 [(set (attr "type")
6267 (if_then_else (eq_attr "alternative" "2")
6268 (const_string "lea")
6269 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6270 (const_string "incdec")
6271 (const_string "alu"))))
6272 (set_attr "mode" "HI,HI,SI")])
6273
6274 (define_insn "*addhi_1"
6275 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6276 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6277 (match_operand:HI 2 "general_operand" "ri,rm")))
6278 (clobber (reg:CC 17))]
6279 "TARGET_PARTIAL_REG_STALL
6280 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6281 "*
6282 {
6283 switch (get_attr_type (insn))
6284 {
6285 case TYPE_INCDEC:
6286 if (operands[2] == const1_rtx)
6287 return \"inc{w}\\t%0\";
6288 else if (operands[2] == constm1_rtx
6289 || (GET_CODE (operands[2]) == CONST_INT
6290 && INTVAL (operands[2]) == 65535))
6291 return \"dec{w}\\t%0\";
6292 abort();
6293
6294 default:
6295 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6296 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6297 if (GET_CODE (operands[2]) == CONST_INT
6298 && (INTVAL (operands[2]) == 128
6299 || (INTVAL (operands[2]) < 0
6300 && INTVAL (operands[2]) != -128)))
6301 {
6302 operands[2] = GEN_INT (-INTVAL (operands[2]));
6303 return \"sub{w}\\t{%2, %0|%0, %2}\";
6304 }
6305 return \"add{w}\\t{%2, %0|%0, %2}\";
6306 }
6307 }"
6308 [(set (attr "type")
6309 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set_attr "mode" "HI")])
6313
6314 (define_insn "*addhi_2"
6315 [(set (reg 17)
6316 (compare
6317 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6318 (match_operand:HI 2 "general_operand" "rmni,rni"))
6319 (const_int 0)))
6320 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6321 (plus:HI (match_dup 1) (match_dup 2)))]
6322 "ix86_match_ccmode (insn, CCGOCmode)
6323 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6324 "*
6325 {
6326 switch (get_attr_type (insn))
6327 {
6328 case TYPE_INCDEC:
6329 if (operands[2] == const1_rtx)
6330 return \"inc{w}\\t%0\";
6331 else if (operands[2] == constm1_rtx
6332 || (GET_CODE (operands[2]) == CONST_INT
6333 && INTVAL (operands[2]) == 65535))
6334 return \"dec{w}\\t%0\";
6335 abort();
6336
6337 default:
6338 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6339 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6340 if (GET_CODE (operands[2]) == CONST_INT
6341 && (INTVAL (operands[2]) == 128
6342 || (INTVAL (operands[2]) < 0
6343 && INTVAL (operands[2]) != -128)))
6344 {
6345 operands[2] = GEN_INT (-INTVAL (operands[2]));
6346 return \"sub{w}\\t{%2, %0|%0, %2}\";
6347 }
6348 return \"add{w}\\t{%2, %0|%0, %2}\";
6349 }
6350 }"
6351 [(set (attr "type")
6352 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6353 (const_string "incdec")
6354 (const_string "alu")))
6355 (set_attr "mode" "HI")])
6356
6357 (define_insn "*addhi_3"
6358 [(set (reg 17)
6359 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6360 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6361 (clobber (match_scratch:HI 0 "=r"))]
6362 "ix86_match_ccmode (insn, CCZmode)
6363 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6364 "*
6365 {
6366 switch (get_attr_type (insn))
6367 {
6368 case TYPE_INCDEC:
6369 if (operands[2] == const1_rtx)
6370 return \"inc{w}\\t%0\";
6371 else if (operands[2] == constm1_rtx
6372 || (GET_CODE (operands[2]) == CONST_INT
6373 && INTVAL (operands[2]) == 65535))
6374 return \"dec{w}\\t%0\";
6375 abort();
6376
6377 default:
6378 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6379 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6380 if (GET_CODE (operands[2]) == CONST_INT
6381 && (INTVAL (operands[2]) == 128
6382 || (INTVAL (operands[2]) < 0
6383 && INTVAL (operands[2]) != -128)))
6384 {
6385 operands[2] = GEN_INT (-INTVAL (operands[2]));
6386 return \"sub{w}\\t{%2, %0|%0, %2}\";
6387 }
6388 return \"add{w}\\t{%2, %0|%0, %2}\";
6389 }
6390 }"
6391 [(set (attr "type")
6392 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6393 (const_string "incdec")
6394 (const_string "alu")))
6395 (set_attr "mode" "HI")])
6396
6397 ; See comments above addsi_3_imm for details.
6398 (define_insn "*addhi_4"
6399 [(set (reg 17)
6400 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6401 (match_operand:HI 2 "const_int_operand" "n")))
6402 (clobber (match_scratch:HI 0 "=rm"))]
6403 "ix86_match_ccmode (insn, CCGCmode)
6404 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6405 "*
6406 {
6407 switch (get_attr_type (insn))
6408 {
6409 case TYPE_INCDEC:
6410 if (operands[2] == constm1_rtx
6411 || (GET_CODE (operands[2]) == CONST_INT
6412 && INTVAL (operands[2]) == 65535))
6413 return \"inc{w}\\t%0\";
6414 else if (operands[2] == const1_rtx)
6415 return \"dec{w}\\t%0\";
6416 else
6417 abort();
6418
6419 default:
6420 if (! rtx_equal_p (operands[0], operands[1]))
6421 abort ();
6422 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6423 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6424 if ((INTVAL (operands[2]) == -128
6425 || (INTVAL (operands[2]) > 0
6426 && INTVAL (operands[2]) != 128)))
6427 return \"sub{w}\\t{%2, %0|%0, %2}\";
6428 operands[2] = GEN_INT (-INTVAL (operands[2]));
6429 return \"add{w}\\t{%2, %0|%0, %2}\";
6430 }
6431 }"
6432 [(set (attr "type")
6433 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6434 (const_string "incdec")
6435 (const_string "alu")))
6436 (set_attr "mode" "SI")])
6437
6438
6439 (define_insn "*addhi_5"
6440 [(set (reg 17)
6441 (compare
6442 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6443 (match_operand:HI 2 "general_operand" "rmni"))
6444 (const_int 0)))
6445 (clobber (match_scratch:HI 0 "=r"))]
6446 "ix86_match_ccmode (insn, CCGOCmode)
6447 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6448 "*
6449 {
6450 switch (get_attr_type (insn))
6451 {
6452 case TYPE_INCDEC:
6453 if (operands[2] == const1_rtx)
6454 return \"inc{w}\\t%0\";
6455 else if (operands[2] == constm1_rtx
6456 || (GET_CODE (operands[2]) == CONST_INT
6457 && INTVAL (operands[2]) == 65535))
6458 return \"dec{w}\\t%0\";
6459 abort();
6460
6461 default:
6462 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6463 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6464 if (GET_CODE (operands[2]) == CONST_INT
6465 && (INTVAL (operands[2]) == 128
6466 || (INTVAL (operands[2]) < 0
6467 && INTVAL (operands[2]) != -128)))
6468 {
6469 operands[2] = GEN_INT (-INTVAL (operands[2]));
6470 return \"sub{w}\\t{%2, %0|%0, %2}\";
6471 }
6472 return \"add{w}\\t{%2, %0|%0, %2}\";
6473 }
6474 }"
6475 [(set (attr "type")
6476 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6477 (const_string "incdec")
6478 (const_string "alu")))
6479 (set_attr "mode" "HI")])
6480
6481 (define_expand "addqi3"
6482 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6483 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6484 (match_operand:QI 2 "general_operand" "")))
6485 (clobber (reg:CC 17))])]
6486 "TARGET_QIMODE_MATH"
6487 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6488
6489 ;; %%% Potential partial reg stall on alternative 2. What to do?
6490 (define_insn "*addqi_1_lea"
6491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6492 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6493 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6494 (clobber (reg:CC 17))]
6495 "!TARGET_PARTIAL_REG_STALL
6496 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6497 "*
6498 {
6499 int widen = (which_alternative == 2);
6500 switch (get_attr_type (insn))
6501 {
6502 case TYPE_LEA:
6503 return \"#\";
6504 case TYPE_INCDEC:
6505 if (operands[2] == const1_rtx)
6506 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
6507 else if (operands[2] == constm1_rtx
6508 || (GET_CODE (operands[2]) == CONST_INT
6509 && INTVAL (operands[2]) == 255))
6510 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
6511 abort();
6512
6513 default:
6514 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6515 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6516 if (GET_CODE (operands[2]) == CONST_INT
6517 && (INTVAL (operands[2]) == 128
6518 || (INTVAL (operands[2]) < 0
6519 && INTVAL (operands[2]) != -128)))
6520 {
6521 operands[2] = GEN_INT (-INTVAL (operands[2]));
6522 if (widen)
6523 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
6524 else
6525 return \"sub{b}\\t{%2, %0|%0, %2}\";
6526 }
6527 if (widen)
6528 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
6529 else
6530 return \"add{b}\\t{%2, %0|%0, %2}\";
6531 }
6532 }"
6533 [(set (attr "type")
6534 (if_then_else (eq_attr "alternative" "3")
6535 (const_string "lea")
6536 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6537 (const_string "incdec")
6538 (const_string "alu"))))
6539 (set_attr "mode" "QI,QI,SI,SI")])
6540
6541 (define_insn "*addqi_1"
6542 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6543 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6544 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6545 (clobber (reg:CC 17))]
6546 "TARGET_PARTIAL_REG_STALL
6547 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6548 "*
6549 {
6550 int widen = (which_alternative == 2);
6551 switch (get_attr_type (insn))
6552 {
6553 case TYPE_INCDEC:
6554 if (operands[2] == const1_rtx)
6555 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
6556 else if (operands[2] == constm1_rtx
6557 || (GET_CODE (operands[2]) == CONST_INT
6558 && INTVAL (operands[2]) == 255))
6559 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
6560 abort();
6561
6562 default:
6563 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6564 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6565 if (GET_CODE (operands[2]) == CONST_INT
6566 && (INTVAL (operands[2]) == 128
6567 || (INTVAL (operands[2]) < 0
6568 && INTVAL (operands[2]) != -128)))
6569 {
6570 operands[2] = GEN_INT (-INTVAL (operands[2]));
6571 if (widen)
6572 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
6573 else
6574 return \"sub{b}\\t{%2, %0|%0, %2}\";
6575 }
6576 if (widen)
6577 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
6578 else
6579 return \"add{b}\\t{%2, %0|%0, %2}\";
6580 }
6581 }"
6582 [(set (attr "type")
6583 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6584 (const_string "incdec")
6585 (const_string "alu")))
6586 (set_attr "mode" "QI,QI,SI")])
6587
6588 (define_insn "*addqi_2"
6589 [(set (reg 17)
6590 (compare
6591 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6592 (match_operand:QI 2 "general_operand" "qmni,qni"))
6593 (const_int 0)))
6594 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6595 (plus:QI (match_dup 1) (match_dup 2)))]
6596 "ix86_match_ccmode (insn, CCGOCmode)
6597 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6598 "*
6599 {
6600 switch (get_attr_type (insn))
6601 {
6602 case TYPE_INCDEC:
6603 if (operands[2] == const1_rtx)
6604 return \"inc{b}\\t%0\";
6605 else if (operands[2] == constm1_rtx
6606 || (GET_CODE (operands[2]) == CONST_INT
6607 && INTVAL (operands[2]) == 255))
6608 return \"dec{b}\\t%0\";
6609 abort();
6610
6611 default:
6612 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6613 if (GET_CODE (operands[2]) == CONST_INT
6614 && INTVAL (operands[2]) < 0)
6615 {
6616 operands[2] = GEN_INT (-INTVAL (operands[2]));
6617 return \"sub{b}\\t{%2, %0|%0, %2}\";
6618 }
6619 return \"add{b}\\t{%2, %0|%0, %2}\";
6620 }
6621 }"
6622 [(set (attr "type")
6623 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6624 (const_string "incdec")
6625 (const_string "alu")))
6626 (set_attr "mode" "QI")])
6627
6628 (define_insn "*addqi_3"
6629 [(set (reg 17)
6630 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6631 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6632 (clobber (match_scratch:QI 0 "=q"))]
6633 "ix86_match_ccmode (insn, CCZmode)
6634 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6635 "*
6636 {
6637 switch (get_attr_type (insn))
6638 {
6639 case TYPE_INCDEC:
6640 if (operands[2] == const1_rtx)
6641 return \"inc{b}\\t%0\";
6642 else if (operands[2] == constm1_rtx
6643 || (GET_CODE (operands[2]) == CONST_INT
6644 && INTVAL (operands[2]) == 255))
6645 return \"dec{b}\\t%0\";
6646 abort();
6647
6648 default:
6649 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6650 if (GET_CODE (operands[2]) == CONST_INT
6651 && INTVAL (operands[2]) < 0)
6652 {
6653 operands[2] = GEN_INT (-INTVAL (operands[2]));
6654 return \"sub{b}\\t{%2, %0|%0, %2}\";
6655 }
6656 return \"add{b}\\t{%2, %0|%0, %2}\";
6657 }
6658 }"
6659 [(set (attr "type")
6660 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6661 (const_string "incdec")
6662 (const_string "alu")))
6663 (set_attr "mode" "QI")])
6664
6665 ; See comments above addsi_3_imm for details.
6666 (define_insn "*addqi_4"
6667 [(set (reg 17)
6668 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6669 (match_operand:QI 2 "const_int_operand" "n")))
6670 (clobber (match_scratch:QI 0 "=qm"))]
6671 "ix86_match_ccmode (insn, CCGCmode)
6672 && (INTVAL (operands[2]) & 0xff) != 0x80"
6673 "*
6674 {
6675 switch (get_attr_type (insn))
6676 {
6677 case TYPE_INCDEC:
6678 if (operands[2] == constm1_rtx
6679 || (GET_CODE (operands[2]) == CONST_INT
6680 && INTVAL (operands[2]) == 255))
6681 return \"inc{b}\\t%0\";
6682 else if (operands[2] == const1_rtx)
6683 return \"dec{b}\\t%0\";
6684 else
6685 abort();
6686
6687 default:
6688 if (! rtx_equal_p (operands[0], operands[1]))
6689 abort ();
6690 if (INTVAL (operands[2]) < 0)
6691 {
6692 operands[2] = GEN_INT (-INTVAL (operands[2]));
6693 return \"add{b}\\t{%2, %0|%0, %2}\";
6694 }
6695 return \"sub{b}\\t{%2, %0|%0, %2}\";
6696 }
6697 }"
6698 [(set (attr "type")
6699 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6700 (const_string "incdec")
6701 (const_string "alu")))
6702 (set_attr "mode" "QI")])
6703
6704
6705 (define_insn "*addqi_5"
6706 [(set (reg 17)
6707 (compare
6708 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6709 (match_operand:QI 2 "general_operand" "qmni"))
6710 (const_int 0)))
6711 (clobber (match_scratch:QI 0 "=q"))]
6712 "ix86_match_ccmode (insn, CCGOCmode)
6713 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6714 "*
6715 {
6716 switch (get_attr_type (insn))
6717 {
6718 case TYPE_INCDEC:
6719 if (operands[2] == const1_rtx)
6720 return \"inc{b}\\t%0\";
6721 else if (operands[2] == constm1_rtx
6722 || (GET_CODE (operands[2]) == CONST_INT
6723 && INTVAL (operands[2]) == 255))
6724 return \"dec{b}\\t%0\";
6725 abort();
6726
6727 default:
6728 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6729 if (GET_CODE (operands[2]) == CONST_INT
6730 && INTVAL (operands[2]) < 0)
6731 {
6732 operands[2] = GEN_INT (-INTVAL (operands[2]));
6733 return \"sub{b}\\t{%2, %0|%0, %2}\";
6734 }
6735 return \"add{b}\\t{%2, %0|%0, %2}\";
6736 }
6737 }"
6738 [(set (attr "type")
6739 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6740 (const_string "incdec")
6741 (const_string "alu")))
6742 (set_attr "mode" "QI")])
6743
6744
6745 (define_insn "addqi_ext_1"
6746 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6747 (const_int 8)
6748 (const_int 8))
6749 (plus:SI
6750 (zero_extract:SI
6751 (match_operand 1 "ext_register_operand" "0")
6752 (const_int 8)
6753 (const_int 8))
6754 (match_operand:QI 2 "general_operand" "qmn")))
6755 (clobber (reg:CC 17))]
6756 "!TARGET_64BIT"
6757 "*
6758 {
6759 switch (get_attr_type (insn))
6760 {
6761 case TYPE_INCDEC:
6762 if (operands[2] == const1_rtx)
6763 return \"inc{b}\\t%h0\";
6764 else if (operands[2] == constm1_rtx
6765 || (GET_CODE (operands[2]) == CONST_INT
6766 && INTVAL (operands[2]) == 255))
6767 return \"dec{b}\\t%h0\";
6768 abort();
6769
6770 default:
6771 return \"add{b}\\t{%2, %h0|%h0, %2}\";
6772 }
6773 }"
6774 [(set (attr "type")
6775 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6776 (const_string "incdec")
6777 (const_string "alu")))
6778 (set_attr "mode" "QI")])
6779
6780 (define_insn "*addqi_ext_1_rex64"
6781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6782 (const_int 8)
6783 (const_int 8))
6784 (plus:SI
6785 (zero_extract:SI
6786 (match_operand 1 "ext_register_operand" "0")
6787 (const_int 8)
6788 (const_int 8))
6789 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6790 (clobber (reg:CC 17))]
6791 "TARGET_64BIT"
6792 "*
6793 {
6794 switch (get_attr_type (insn))
6795 {
6796 case TYPE_INCDEC:
6797 if (operands[2] == const1_rtx)
6798 return \"inc{b}\\t%h0\";
6799 else if (operands[2] == constm1_rtx
6800 || (GET_CODE (operands[2]) == CONST_INT
6801 && INTVAL (operands[2]) == 255))
6802 return \"dec{b}\\t%h0\";
6803 abort();
6804
6805 default:
6806 return \"add{b}\\t{%2, %h0|%h0, %2}\";
6807 }
6808 }"
6809 [(set (attr "type")
6810 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6811 (const_string "incdec")
6812 (const_string "alu")))
6813 (set_attr "mode" "QI")])
6814
6815 (define_insn "*addqi_ext_2"
6816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6817 (const_int 8)
6818 (const_int 8))
6819 (plus:SI
6820 (zero_extract:SI
6821 (match_operand 1 "ext_register_operand" "%0")
6822 (const_int 8)
6823 (const_int 8))
6824 (zero_extract:SI
6825 (match_operand 2 "ext_register_operand" "Q")
6826 (const_int 8)
6827 (const_int 8))))
6828 (clobber (reg:CC 17))]
6829 ""
6830 "add{b}\\t{%h2, %h0|%h0, %h2}"
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "QI")])
6833
6834 ;; The patterns that match these are at the end of this file.
6835
6836 (define_expand "addxf3"
6837 [(set (match_operand:XF 0 "register_operand" "")
6838 (plus:XF (match_operand:XF 1 "register_operand" "")
6839 (match_operand:XF 2 "register_operand" "")))]
6840 "TARGET_80387 && !TARGET_64BIT"
6841 "")
6842
6843 (define_expand "addtf3"
6844 [(set (match_operand:TF 0 "register_operand" "")
6845 (plus:TF (match_operand:TF 1 "register_operand" "")
6846 (match_operand:TF 2 "register_operand" "")))]
6847 "TARGET_80387"
6848 "")
6849
6850 (define_expand "adddf3"
6851 [(set (match_operand:DF 0 "register_operand" "")
6852 (plus:DF (match_operand:DF 1 "register_operand" "")
6853 (match_operand:DF 2 "nonimmediate_operand" "")))]
6854 "TARGET_80387 || TARGET_SSE2"
6855 "")
6856
6857 (define_expand "addsf3"
6858 [(set (match_operand:SF 0 "register_operand" "")
6859 (plus:SF (match_operand:SF 1 "register_operand" "")
6860 (match_operand:SF 2 "nonimmediate_operand" "")))]
6861 "TARGET_80387 || TARGET_SSE"
6862 "")
6863 \f
6864 ;; Subtract instructions
6865
6866 ;; %%% splits for subsidi3
6867
6868 (define_expand "subdi3"
6869 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6870 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6871 (match_operand:DI 2 "x86_64_general_operand" "")))
6872 (clobber (reg:CC 17))])]
6873 ""
6874 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6875
6876 (define_insn "*subdi3_1"
6877 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6878 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6879 (match_operand:DI 2 "general_operand" "roiF,riF")))
6880 (clobber (reg:CC 17))]
6881 "!TARGET_64BIT"
6882 "#")
6883
6884 (define_split
6885 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6886 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6887 (match_operand:DI 2 "general_operand" "")))
6888 (clobber (reg:CC 17))]
6889 "reload_completed && !TARGET_64BIT"
6890 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6891 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6892 (parallel [(set (match_dup 3)
6893 (minus:SI (match_dup 4)
6894 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6895 (match_dup 5))))
6896 (clobber (reg:CC 17))])]
6897 "split_di (operands+0, 1, operands+0, operands+3);
6898 split_di (operands+1, 1, operands+1, operands+4);
6899 split_di (operands+2, 1, operands+2, operands+5);")
6900
6901 (define_insn "subdi3_carry_rex64"
6902 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6903 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6904 (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
6905 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6906 (clobber (reg:CC 17))]
6907 "ix86_binary_operator_ok (MINUS, DImode, operands)"
6908 "sbb{q}\\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "pent_pair" "pu")
6911 (set_attr "ppro_uops" "few")
6912 (set_attr "mode" "DI")])
6913
6914 (define_insn "*subdi_1_rex64"
6915 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6916 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6917 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6918 (clobber (reg:CC 17))]
6919 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6920 "sub{q}\\t{%2, %0|%0, %2}"
6921 [(set_attr "type" "alu")
6922 (set_attr "mode" "DI")])
6923
6924 (define_insn "*subdi_2_rex64"
6925 [(set (reg 17)
6926 (compare
6927 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6928 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6929 (const_int 0)))
6930 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6931 (minus:DI (match_dup 1) (match_dup 2)))]
6932 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6933 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6934 "sub{q}\\t{%2, %0|%0, %2}"
6935 [(set_attr "type" "alu")
6936 (set_attr "mode" "DI")])
6937
6938 (define_insn "*subdi_3_rex63"
6939 [(set (reg 17)
6940 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6941 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6942 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6943 (minus:DI (match_dup 1) (match_dup 2)))]
6944 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6945 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6946 "sub{q}\\t{%2, %0|%0, %2}"
6947 [(set_attr "type" "alu")
6948 (set_attr "mode" "DI")])
6949
6950
6951 (define_insn "subsi3_carry"
6952 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6953 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6954 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6955 (match_operand:SI 2 "general_operand" "ri,rm"))))
6956 (clobber (reg:CC 17))]
6957 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6958 "sbb{l}\\t{%2, %0|%0, %2}"
6959 [(set_attr "type" "alu")
6960 (set_attr "pent_pair" "pu")
6961 (set_attr "ppro_uops" "few")
6962 (set_attr "mode" "SI")])
6963
6964 (define_insn "subsi3_carry_zext"
6965 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6966 (zero_extend:DI
6967 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6968 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6969 (match_operand:SI 2 "general_operand" "ri,rm")))))
6970 (clobber (reg:CC 17))]
6971 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6972 "sbb{l}\\t{%2, %k0|%k0, %2}"
6973 [(set_attr "type" "alu")
6974 (set_attr "pent_pair" "pu")
6975 (set_attr "ppro_uops" "few")
6976 (set_attr "mode" "SI")])
6977
6978 (define_expand "subsi3"
6979 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6980 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6981 (match_operand:SI 2 "general_operand" "")))
6982 (clobber (reg:CC 17))])]
6983 ""
6984 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6985
6986 (define_insn "*subsi_1"
6987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6988 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6989 (match_operand:SI 2 "general_operand" "ri,rm")))
6990 (clobber (reg:CC 17))]
6991 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6992 "sub{l}\\t{%2, %0|%0, %2}"
6993 [(set_attr "type" "alu")
6994 (set_attr "mode" "SI")])
6995
6996 (define_insn "*subsi_1_zext"
6997 [(set (match_operand:DI 0 "register_operand" "=r")
6998 (zero_extend:DI
6999 (minus:SI (match_operand:SI 1 "register_operand" "0")
7000 (match_operand:SI 2 "general_operand" "rim"))))
7001 (clobber (reg:CC 17))]
7002 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7003 "sub{l}\\t{%2, %k0|%k0, %2}"
7004 [(set_attr "type" "alu")
7005 (set_attr "mode" "SI")])
7006
7007 (define_insn "*subsi_2"
7008 [(set (reg 17)
7009 (compare
7010 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7011 (match_operand:SI 2 "general_operand" "ri,rm"))
7012 (const_int 0)))
7013 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7014 (minus:SI (match_dup 1) (match_dup 2)))]
7015 "ix86_match_ccmode (insn, CCGOCmode)
7016 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7017 "sub{l}\\t{%2, %0|%0, %2}"
7018 [(set_attr "type" "alu")
7019 (set_attr "mode" "SI")])
7020
7021 (define_insn "*subsi_2_zext"
7022 [(set (reg 17)
7023 (compare
7024 (minus:SI (match_operand:SI 1 "register_operand" "0")
7025 (match_operand:SI 2 "general_operand" "rim"))
7026 (const_int 0)))
7027 (set (match_operand:DI 0 "register_operand" "=r")
7028 (zero_extend:DI
7029 (minus:SI (match_dup 1)
7030 (match_dup 2))))]
7031 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7032 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7033 "sub{l}\\t{%2, %k0|%k0, %2}"
7034 [(set_attr "type" "alu")
7035 (set_attr "mode" "SI")])
7036
7037 (define_insn "*subsi_3"
7038 [(set (reg 17)
7039 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7040 (match_operand:SI 2 "general_operand" "ri,rm")))
7041 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7042 (minus:SI (match_dup 1) (match_dup 2)))]
7043 "ix86_match_ccmode (insn, CCmode)
7044 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7045 "sub{l}\\t{%2, %0|%0, %2}"
7046 [(set_attr "type" "alu")
7047 (set_attr "mode" "SI")])
7048
7049 (define_insn "*subsi_3_zext"
7050 [(set (reg 17)
7051 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7052 (match_operand:SI 2 "general_operand" "rim")))
7053 (set (match_operand:DI 0 "register_operand" "=r")
7054 (zero_extend:DI
7055 (minus:SI (match_dup 1)
7056 (match_dup 2))))]
7057 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7058 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7059 "sub{q}\\t{%2, %0|%0, %2}"
7060 [(set_attr "type" "alu")
7061 (set_attr "mode" "DI")])
7062
7063 (define_expand "subhi3"
7064 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7065 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7066 (match_operand:HI 2 "general_operand" "")))
7067 (clobber (reg:CC 17))])]
7068 "TARGET_HIMODE_MATH"
7069 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7070
7071 (define_insn "*subhi_1"
7072 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7073 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7074 (match_operand:HI 2 "general_operand" "ri,rm")))
7075 (clobber (reg:CC 17))]
7076 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7077 "sub{w}\\t{%2, %0|%0, %2}"
7078 [(set_attr "type" "alu")
7079 (set_attr "mode" "HI")])
7080
7081 (define_insn "*subhi_2"
7082 [(set (reg 17)
7083 (compare
7084 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7085 (match_operand:HI 2 "general_operand" "ri,rm"))
7086 (const_int 0)))
7087 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7088 (minus:HI (match_dup 1) (match_dup 2)))]
7089 "ix86_match_ccmode (insn, CCGOCmode)
7090 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7091 "sub{w}\\t{%2, %0|%0, %2}"
7092 [(set_attr "type" "alu")
7093 (set_attr "mode" "HI")])
7094
7095 (define_insn "*subhi_3"
7096 [(set (reg 17)
7097 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7098 (match_operand:HI 2 "general_operand" "ri,rm")))
7099 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7100 (minus:HI (match_dup 1) (match_dup 2)))]
7101 "ix86_match_ccmode (insn, CCmode)
7102 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7103 "sub{w}\\t{%2, %0|%0, %2}"
7104 [(set_attr "type" "alu")
7105 (set_attr "mode" "HI")])
7106
7107 (define_expand "subqi3"
7108 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7109 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7110 (match_operand:QI 2 "general_operand" "")))
7111 (clobber (reg:CC 17))])]
7112 "TARGET_QIMODE_MATH"
7113 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7114
7115 (define_insn "*subqi_1"
7116 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7117 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7118 (match_operand:QI 2 "general_operand" "qn,qmn")))
7119 (clobber (reg:CC 17))]
7120 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7121 "sub{b}\\t{%2, %0|%0, %2}"
7122 [(set_attr "type" "alu")
7123 (set_attr "mode" "QI")])
7124
7125 (define_insn "*subqi_2"
7126 [(set (reg 17)
7127 (compare
7128 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7129 (match_operand:QI 2 "general_operand" "qi,qm"))
7130 (const_int 0)))
7131 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7132 (minus:HI (match_dup 1) (match_dup 2)))]
7133 "ix86_match_ccmode (insn, CCGOCmode)
7134 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7135 "sub{b}\\t{%2, %0|%0, %2}"
7136 [(set_attr "type" "alu")
7137 (set_attr "mode" "QI")])
7138
7139 (define_insn "*subqi_3"
7140 [(set (reg 17)
7141 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7142 (match_operand:QI 2 "general_operand" "qi,qm")))
7143 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7144 (minus:HI (match_dup 1) (match_dup 2)))]
7145 "ix86_match_ccmode (insn, CCmode)
7146 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7147 "sub{b}\\t{%2, %0|%0, %2}"
7148 [(set_attr "type" "alu")
7149 (set_attr "mode" "QI")])
7150
7151 ;; The patterns that match these are at the end of this file.
7152
7153 (define_expand "subxf3"
7154 [(set (match_operand:XF 0 "register_operand" "")
7155 (minus:XF (match_operand:XF 1 "register_operand" "")
7156 (match_operand:XF 2 "register_operand" "")))]
7157 "TARGET_80387 && !TARGET_64BIT"
7158 "")
7159
7160 (define_expand "subtf3"
7161 [(set (match_operand:TF 0 "register_operand" "")
7162 (minus:TF (match_operand:TF 1 "register_operand" "")
7163 (match_operand:TF 2 "register_operand" "")))]
7164 "TARGET_80387"
7165 "")
7166
7167 (define_expand "subdf3"
7168 [(set (match_operand:DF 0 "register_operand" "")
7169 (minus:DF (match_operand:DF 1 "register_operand" "")
7170 (match_operand:DF 2 "nonimmediate_operand" "")))]
7171 "TARGET_80387 || TARGET_SSE2"
7172 "")
7173
7174 (define_expand "subsf3"
7175 [(set (match_operand:SF 0 "register_operand" "")
7176 (minus:SF (match_operand:SF 1 "register_operand" "")
7177 (match_operand:SF 2 "nonimmediate_operand" "")))]
7178 "TARGET_80387 || TARGET_SSE"
7179 "")
7180 \f
7181 ;; Multiply instructions
7182
7183 (define_expand "muldi3"
7184 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7185 (mult:DI (match_operand:DI 1 "register_operand" "")
7186 (match_operand:DI 2 "x86_64_general_operand" "")))
7187 (clobber (reg:CC 17))])]
7188 "TARGET_64BIT"
7189 "")
7190
7191 (define_insn "*muldi3_1_rex64"
7192 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7193 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
7194 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7195 (clobber (reg:CC 17))]
7196 "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
7197 && TARGET_64BIT"
7198 "@
7199 imul{q}\\t{%2, %1, %0|%0, %1, %2}
7200 imul{q}\\t{%2, %1, %0|%0, %1, %2}
7201 imul{q}\\t{%2, %0|%0, %2}"
7202 [(set_attr "type" "imul")
7203 (set_attr "prefix_0f" "0,0,1")
7204 (set_attr "mode" "DI")])
7205
7206 (define_expand "mulsi3"
7207 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7208 (mult:SI (match_operand:SI 1 "register_operand" "")
7209 (match_operand:SI 2 "general_operand" "")))
7210 (clobber (reg:CC 17))])]
7211 ""
7212 "")
7213
7214 (define_insn "*mulsi3_1"
7215 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7216 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7217 (match_operand:SI 2 "general_operand" "K,i,mr")))
7218 (clobber (reg:CC 17))]
7219 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7220 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7221 ; there are two ways of writing the exact same machine instruction
7222 ; in assembly language. One, for example, is:
7223 ;
7224 ; imul $12, %eax
7225 ;
7226 ; while the other is:
7227 ;
7228 ; imul $12, %eax, %eax
7229 ;
7230 ; The first is simply short-hand for the latter. But, some assemblers,
7231 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7232 "@
7233 imul{l}\\t{%2, %1, %0|%0, %1, %2}
7234 imul{l}\\t{%2, %1, %0|%0, %1, %2}
7235 imul{l}\\t{%2, %0|%0, %2}"
7236 [(set_attr "type" "imul")
7237 (set_attr "prefix_0f" "0,0,1")
7238 (set_attr "mode" "SI")])
7239
7240 (define_insn "*mulsi3_1_zext"
7241 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7242 (zero_extend:DI
7243 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
7244 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7245 (clobber (reg:CC 17))]
7246 "TARGET_64BIT
7247 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7248 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
7249 ; there are two ways of writing the exact same machine instruction
7250 ; in assembly language. One, for example, is:
7251 ;
7252 ; imul $12, %eax
7253 ;
7254 ; while the other is:
7255 ;
7256 ; imul $12, %eax, %eax
7257 ;
7258 ; The first is simply short-hand for the latter. But, some assemblers,
7259 ; like the SCO OSR5 COFF assembler, don't handle the first form.
7260 "@
7261 imul{l}\\t{%2, %1, %k0|%k0, %1, %2}
7262 imul{l}\\t{%2, %1, %k0|%k0, %1, %2}
7263 imul{l}\\t{%2, %k0|%k0, %2}"
7264 [(set_attr "type" "imul")
7265 (set_attr "prefix_0f" "0,0,1")
7266 (set_attr "mode" "SI")])
7267
7268 (define_expand "mulhi3"
7269 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7270 (mult:HI (match_operand:HI 1 "register_operand" "")
7271 (match_operand:HI 2 "general_operand" "")))
7272 (clobber (reg:CC 17))])]
7273 "TARGET_HIMODE_MATH"
7274 "")
7275
7276 (define_insn "*mulhi3_1"
7277 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7278 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
7279 (match_operand:HI 2 "general_operand" "K,i,mr")))
7280 (clobber (reg:CC 17))]
7281 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7282 ; %%% There was a note about "Assembler has weird restrictions",
7283 ; concerning alternative 1 when op1 == op0. True?
7284 "@
7285 imul{w}\\t{%2, %1, %0|%0, %1, %2}
7286 imul{w}\\t{%2, %1, %0|%0, %1, %2}
7287 imul{w}\\t{%2, %0|%0, %2}"
7288 [(set_attr "type" "imul")
7289 (set_attr "prefix_0f" "0,0,1")
7290 (set_attr "mode" "HI")])
7291
7292 (define_insn "mulqi3"
7293 [(set (match_operand:QI 0 "register_operand" "=a")
7294 (mult:QI (match_operand:QI 1 "register_operand" "%0")
7295 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7296 (clobber (reg:CC 17))]
7297 "TARGET_QIMODE_MATH"
7298 "mul{b}\\t%2"
7299 [(set_attr "type" "imul")
7300 (set_attr "length_immediate" "0")
7301 (set_attr "mode" "QI")])
7302
7303 (define_insn "umulqihi3"
7304 [(set (match_operand:HI 0 "register_operand" "=a")
7305 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7306 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7307 (clobber (reg:CC 17))]
7308 "TARGET_QIMODE_MATH"
7309 "mul{b}\\t%2"
7310 [(set_attr "type" "imul")
7311 (set_attr "length_immediate" "0")
7312 (set_attr "mode" "QI")])
7313
7314 (define_insn "mulqihi3"
7315 [(set (match_operand:HI 0 "register_operand" "=a")
7316 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
7317 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7318 (clobber (reg:CC 17))]
7319 "TARGET_QIMODE_MATH"
7320 "imul{b}\\t%2"
7321 [(set_attr "type" "imul")
7322 (set_attr "length_immediate" "0")
7323 (set_attr "mode" "QI")])
7324
7325 (define_insn "umulditi3"
7326 [(set (match_operand:TI 0 "register_operand" "=A")
7327 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7328 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7329 (clobber (reg:CC 17))]
7330 "TARGET_64BIT"
7331 "mul{q}\\t%2"
7332 [(set_attr "type" "imul")
7333 (set_attr "ppro_uops" "few")
7334 (set_attr "length_immediate" "0")
7335 (set_attr "mode" "DI")])
7336
7337 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7338 (define_insn "umulsidi3"
7339 [(set (match_operand:DI 0 "register_operand" "=A")
7340 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7341 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7342 (clobber (reg:CC 17))]
7343 "!TARGET_64BIT"
7344 "mul{l}\\t%2"
7345 [(set_attr "type" "imul")
7346 (set_attr "ppro_uops" "few")
7347 (set_attr "length_immediate" "0")
7348 (set_attr "mode" "SI")])
7349
7350 (define_insn "mulditi3"
7351 [(set (match_operand:TI 0 "register_operand" "=A")
7352 (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
7353 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7354 (clobber (reg:CC 17))]
7355 "TARGET_64BIT"
7356 "imul{q}\\t%2"
7357 [(set_attr "type" "imul")
7358 (set_attr "length_immediate" "0")
7359 (set_attr "mode" "DI")])
7360
7361 (define_insn "mulsidi3"
7362 [(set (match_operand:DI 0 "register_operand" "=A")
7363 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7364 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7365 (clobber (reg:CC 17))]
7366 "!TARGET_64BIT"
7367 "imul{l}\\t%2"
7368 [(set_attr "type" "imul")
7369 (set_attr "length_immediate" "0")
7370 (set_attr "mode" "SI")])
7371
7372 (define_insn "*umuldi3_highpart_rex64"
7373 [(set (match_operand:DI 0 "register_operand" "=d")
7374 (truncate:DI
7375 (lshiftrt:TI
7376 (mult:TI (zero_extend:TI
7377 (match_operand:DI 1 "register_operand" "%a"))
7378 (zero_extend:TI
7379 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7380 (const_int 64))))
7381 (clobber (match_scratch:DI 3 "=a"))
7382 (clobber (reg:CC 17))]
7383 "TARGET_64BIT"
7384 "mul{q}\\t%2"
7385 [(set_attr "type" "imul")
7386 (set_attr "ppro_uops" "few")
7387 (set_attr "length_immediate" "0")
7388 (set_attr "mode" "DI")])
7389
7390 (define_insn "umulsi3_highpart"
7391 [(set (match_operand:SI 0 "register_operand" "=d")
7392 (truncate:SI
7393 (lshiftrt:DI
7394 (mult:DI (zero_extend:DI
7395 (match_operand:SI 1 "register_operand" "%a"))
7396 (zero_extend:DI
7397 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7398 (const_int 32))))
7399 (clobber (match_scratch:SI 3 "=a"))
7400 (clobber (reg:CC 17))]
7401 ""
7402 "mul{l}\\t%2"
7403 [(set_attr "type" "imul")
7404 (set_attr "ppro_uops" "few")
7405 (set_attr "length_immediate" "0")
7406 (set_attr "mode" "SI")])
7407
7408 (define_insn "*umulsi3_highpart_zext"
7409 [(set (match_operand:DI 0 "register_operand" "=d")
7410 (zero_extend:DI (truncate:SI
7411 (lshiftrt:DI
7412 (mult:DI (zero_extend:DI
7413 (match_operand:SI 1 "register_operand" "%a"))
7414 (zero_extend:DI
7415 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7416 (const_int 32)))))
7417 (clobber (match_scratch:SI 3 "=a"))
7418 (clobber (reg:CC 17))]
7419 "TARGET_64BIT"
7420 "mul{l}\\t%2"
7421 [(set_attr "type" "imul")
7422 (set_attr "ppro_uops" "few")
7423 (set_attr "length_immediate" "0")
7424 (set_attr "mode" "SI")])
7425
7426 (define_insn "*smuldi3_highpart_rex64"
7427 [(set (match_operand:DI 0 "register_operand" "=d")
7428 (truncate:DI
7429 (lshiftrt:TI
7430 (mult:TI (sign_extend:TI
7431 (match_operand:DI 1 "register_operand" "%a"))
7432 (sign_extend:TI
7433 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7434 (const_int 64))))
7435 (clobber (match_scratch:DI 3 "=a"))
7436 (clobber (reg:CC 17))]
7437 "TARGET_64BIT"
7438 "imul{q}\\t%2"
7439 [(set_attr "type" "imul")
7440 (set_attr "ppro_uops" "few")
7441 (set_attr "mode" "DI")])
7442
7443 (define_insn "smulsi3_highpart"
7444 [(set (match_operand:SI 0 "register_operand" "=d")
7445 (truncate:SI
7446 (lshiftrt:DI
7447 (mult:DI (sign_extend:DI
7448 (match_operand:SI 1 "register_operand" "%a"))
7449 (sign_extend:DI
7450 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7451 (const_int 32))))
7452 (clobber (match_scratch:SI 3 "=a"))
7453 (clobber (reg:CC 17))]
7454 ""
7455 "imul{l}\\t%2"
7456 [(set_attr "type" "imul")
7457 (set_attr "ppro_uops" "few")
7458 (set_attr "mode" "SI")])
7459
7460 (define_insn "*smulsi3_highpart_zext"
7461 [(set (match_operand:DI 0 "register_operand" "=d")
7462 (zero_extend:DI (truncate:SI
7463 (lshiftrt:DI
7464 (mult:DI (sign_extend:DI
7465 (match_operand:SI 1 "register_operand" "%a"))
7466 (sign_extend:DI
7467 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7468 (const_int 32)))))
7469 (clobber (match_scratch:SI 3 "=a"))
7470 (clobber (reg:CC 17))]
7471 "TARGET_64BIT"
7472 "imul{l}\\t%2"
7473 [(set_attr "type" "imul")
7474 (set_attr "ppro_uops" "few")
7475 (set_attr "mode" "SI")])
7476
7477 ;; The patterns that match these are at the end of this file.
7478
7479 (define_expand "mulxf3"
7480 [(set (match_operand:XF 0 "register_operand" "")
7481 (mult:XF (match_operand:XF 1 "register_operand" "")
7482 (match_operand:XF 2 "register_operand" "")))]
7483 "TARGET_80387 && !TARGET_64BIT"
7484 "")
7485
7486 (define_expand "multf3"
7487 [(set (match_operand:TF 0 "register_operand" "")
7488 (mult:TF (match_operand:TF 1 "register_operand" "")
7489 (match_operand:TF 2 "register_operand" "")))]
7490 "TARGET_80387"
7491 "")
7492
7493 (define_expand "muldf3"
7494 [(set (match_operand:DF 0 "register_operand" "")
7495 (mult:DF (match_operand:DF 1 "register_operand" "")
7496 (match_operand:DF 2 "nonimmediate_operand" "")))]
7497 "TARGET_80387 || TARGET_SSE2"
7498 "")
7499
7500 (define_expand "mulsf3"
7501 [(set (match_operand:SF 0 "register_operand" "")
7502 (mult:SF (match_operand:SF 1 "register_operand" "")
7503 (match_operand:SF 2 "nonimmediate_operand" "")))]
7504 "TARGET_80387 || TARGET_SSE"
7505 "")
7506 \f
7507 ;; Divide instructions
7508
7509 (define_insn "divqi3"
7510 [(set (match_operand:QI 0 "register_operand" "=a")
7511 (div:QI (match_operand:HI 1 "register_operand" "0")
7512 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7513 (clobber (reg:CC 17))]
7514 "TARGET_QIMODE_MATH"
7515 "idiv{b}\\t%2"
7516 [(set_attr "type" "idiv")
7517 (set_attr "mode" "QI")
7518 (set_attr "ppro_uops" "few")])
7519
7520 (define_insn "udivqi3"
7521 [(set (match_operand:QI 0 "register_operand" "=a")
7522 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7523 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7524 (clobber (reg:CC 17))]
7525 "TARGET_QIMODE_MATH"
7526 "div{b}\\t%2"
7527 [(set_attr "type" "idiv")
7528 (set_attr "mode" "QI")
7529 (set_attr "ppro_uops" "few")])
7530
7531 ;; The patterns that match these are at the end of this file.
7532
7533 (define_expand "divxf3"
7534 [(set (match_operand:XF 0 "register_operand" "")
7535 (div:XF (match_operand:XF 1 "register_operand" "")
7536 (match_operand:XF 2 "register_operand" "")))]
7537 "TARGET_80387 && !TARGET_64BIT"
7538 "")
7539
7540 (define_expand "divtf3"
7541 [(set (match_operand:TF 0 "register_operand" "")
7542 (div:TF (match_operand:TF 1 "register_operand" "")
7543 (match_operand:TF 2 "register_operand" "")))]
7544 "TARGET_80387"
7545 "")
7546
7547 (define_expand "divdf3"
7548 [(set (match_operand:DF 0 "register_operand" "")
7549 (div:DF (match_operand:DF 1 "register_operand" "")
7550 (match_operand:DF 2 "nonimmediate_operand" "")))]
7551 "TARGET_80387 || TARGET_SSE2"
7552 "")
7553
7554 (define_expand "divsf3"
7555 [(set (match_operand:SF 0 "register_operand" "")
7556 (div:SF (match_operand:SF 1 "register_operand" "")
7557 (match_operand:SF 2 "nonimmediate_operand" "")))]
7558 "TARGET_80387 || TARGET_SSE"
7559 "")
7560 \f
7561 ;; Remainder instructions.
7562
7563 (define_expand "divmoddi4"
7564 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7565 (div:DI (match_operand:DI 1 "register_operand" "")
7566 (match_operand:DI 2 "nonimmediate_operand" "")))
7567 (set (match_operand:DI 3 "register_operand" "")
7568 (mod:DI (match_dup 1) (match_dup 2)))
7569 (clobber (reg:CC 17))])]
7570 "TARGET_64BIT"
7571 "")
7572
7573 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7574 ;; Penalize eax case sligthly because it results in worse scheduling
7575 ;; of code.
7576 (define_insn "*divmoddi4_nocltd_rex64"
7577 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7578 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7579 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7580 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7581 (mod:DI (match_dup 2) (match_dup 3)))
7582 (clobber (reg:CC 17))]
7583 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7584 "#"
7585 [(set_attr "type" "multi")])
7586
7587 (define_insn "*divmoddi4_cltd_rex64"
7588 [(set (match_operand:DI 0 "register_operand" "=a")
7589 (div:DI (match_operand:DI 2 "register_operand" "a")
7590 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7591 (set (match_operand:DI 1 "register_operand" "=&d")
7592 (mod:DI (match_dup 2) (match_dup 3)))
7593 (clobber (reg:CC 17))]
7594 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7595 "#"
7596 [(set_attr "type" "multi")])
7597
7598 (define_insn "*divmoddi_noext_rex64"
7599 [(set (match_operand:DI 0 "register_operand" "=a")
7600 (div:DI (match_operand:DI 1 "register_operand" "0")
7601 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7602 (set (match_operand:DI 3 "register_operand" "=d")
7603 (mod:DI (match_dup 1) (match_dup 2)))
7604 (use (match_operand:DI 4 "register_operand" "3"))
7605 (clobber (reg:CC 17))]
7606 "TARGET_64BIT"
7607 "idiv{q}\\t%2"
7608 [(set_attr "type" "idiv")
7609 (set_attr "mode" "DI")
7610 (set_attr "ppro_uops" "few")])
7611
7612 (define_split
7613 [(set (match_operand:DI 0 "register_operand" "")
7614 (div:DI (match_operand:DI 1 "register_operand" "")
7615 (match_operand:DI 2 "nonimmediate_operand" "")))
7616 (set (match_operand:DI 3 "register_operand" "")
7617 (mod:DI (match_dup 1) (match_dup 2)))
7618 (clobber (reg:CC 17))]
7619 "TARGET_64BIT && reload_completed"
7620 [(parallel [(set (match_dup 3)
7621 (ashiftrt:DI (match_dup 4) (const_int 63)))
7622 (clobber (reg:CC 17))])
7623 (parallel [(set (match_dup 0)
7624 (div:DI (reg:DI 0) (match_dup 2)))
7625 (set (match_dup 3)
7626 (mod:DI (reg:DI 0) (match_dup 2)))
7627 (use (match_dup 3))
7628 (clobber (reg:CC 17))])]
7629 "
7630 {
7631 /* Avoid use of cltd in favour of a mov+shift. */
7632 if (!TARGET_USE_CLTD && !optimize_size)
7633 {
7634 if (true_regnum (operands[1]))
7635 emit_move_insn (operands[0], operands[1]);
7636 else
7637 emit_move_insn (operands[3], operands[1]);
7638 operands[4] = operands[3];
7639 }
7640 else
7641 {
7642 if (true_regnum (operands[1]))
7643 abort();
7644 operands[4] = operands[1];
7645 }
7646 }")
7647
7648
7649 (define_expand "divmodsi4"
7650 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7651 (div:SI (match_operand:SI 1 "register_operand" "")
7652 (match_operand:SI 2 "nonimmediate_operand" "")))
7653 (set (match_operand:SI 3 "register_operand" "")
7654 (mod:SI (match_dup 1) (match_dup 2)))
7655 (clobber (reg:CC 17))])]
7656 ""
7657 "")
7658
7659 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7660 ;; Penalize eax case sligthly because it results in worse scheduling
7661 ;; of code.
7662 (define_insn "*divmodsi4_nocltd"
7663 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7664 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7665 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7666 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7667 (mod:SI (match_dup 2) (match_dup 3)))
7668 (clobber (reg:CC 17))]
7669 "!optimize_size && !TARGET_USE_CLTD"
7670 "#"
7671 [(set_attr "type" "multi")])
7672
7673 (define_insn "*divmodsi4_cltd"
7674 [(set (match_operand:SI 0 "register_operand" "=a")
7675 (div:SI (match_operand:SI 2 "register_operand" "a")
7676 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7677 (set (match_operand:SI 1 "register_operand" "=&d")
7678 (mod:SI (match_dup 2) (match_dup 3)))
7679 (clobber (reg:CC 17))]
7680 "optimize_size || TARGET_USE_CLTD"
7681 "#"
7682 [(set_attr "type" "multi")])
7683
7684 (define_insn "*divmodsi_noext"
7685 [(set (match_operand:SI 0 "register_operand" "=a")
7686 (div:SI (match_operand:SI 1 "register_operand" "0")
7687 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7688 (set (match_operand:SI 3 "register_operand" "=d")
7689 (mod:SI (match_dup 1) (match_dup 2)))
7690 (use (match_operand:SI 4 "register_operand" "3"))
7691 (clobber (reg:CC 17))]
7692 ""
7693 "idiv{l}\\t%2"
7694 [(set_attr "type" "idiv")
7695 (set_attr "mode" "SI")
7696 (set_attr "ppro_uops" "few")])
7697
7698 (define_split
7699 [(set (match_operand:SI 0 "register_operand" "")
7700 (div:SI (match_operand:SI 1 "register_operand" "")
7701 (match_operand:SI 2 "nonimmediate_operand" "")))
7702 (set (match_operand:SI 3 "register_operand" "")
7703 (mod:SI (match_dup 1) (match_dup 2)))
7704 (clobber (reg:CC 17))]
7705 "reload_completed"
7706 [(parallel [(set (match_dup 3)
7707 (ashiftrt:SI (match_dup 4) (const_int 31)))
7708 (clobber (reg:CC 17))])
7709 (parallel [(set (match_dup 0)
7710 (div:SI (reg:SI 0) (match_dup 2)))
7711 (set (match_dup 3)
7712 (mod:SI (reg:SI 0) (match_dup 2)))
7713 (use (match_dup 3))
7714 (clobber (reg:CC 17))])]
7715 "
7716 {
7717 /* Avoid use of cltd in favour of a mov+shift. */
7718 if (!TARGET_USE_CLTD && !optimize_size)
7719 {
7720 if (true_regnum (operands[1]))
7721 emit_move_insn (operands[0], operands[1]);
7722 else
7723 emit_move_insn (operands[3], operands[1]);
7724 operands[4] = operands[3];
7725 }
7726 else
7727 {
7728 if (true_regnum (operands[1]))
7729 abort();
7730 operands[4] = operands[1];
7731 }
7732 }")
7733 ;; %%% Split me.
7734 (define_insn "divmodhi4"
7735 [(set (match_operand:HI 0 "register_operand" "=a")
7736 (div:HI (match_operand:HI 1 "register_operand" "0")
7737 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7738 (set (match_operand:HI 3 "register_operand" "=&d")
7739 (mod:HI (match_dup 1) (match_dup 2)))
7740 (clobber (reg:CC 17))]
7741 "TARGET_HIMODE_MATH"
7742 "cwtd\;idiv{w}\\t%2"
7743 [(set_attr "type" "multi")
7744 (set_attr "length_immediate" "0")
7745 (set_attr "mode" "SI")])
7746
7747 (define_insn "udivmoddi4"
7748 [(set (match_operand:DI 0 "register_operand" "=a")
7749 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7750 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7751 (set (match_operand:DI 3 "register_operand" "=&d")
7752 (umod:DI (match_dup 1) (match_dup 2)))
7753 (clobber (reg:CC 17))]
7754 "TARGET_64BIT"
7755 "xor{q}\\t%3, %3\;div{q}\\t%2"
7756 [(set_attr "type" "multi")
7757 (set_attr "length_immediate" "0")
7758 (set_attr "mode" "DI")])
7759
7760 (define_insn "*udivmoddi4_noext"
7761 [(set (match_operand:DI 0 "register_operand" "=a")
7762 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7763 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7764 (set (match_operand:DI 3 "register_operand" "=d")
7765 (umod:DI (match_dup 1) (match_dup 2)))
7766 (use (match_dup 3))
7767 (clobber (reg:CC 17))]
7768 "TARGET_64BIT"
7769 "div{q}\\t%2"
7770 [(set_attr "type" "idiv")
7771 (set_attr "ppro_uops" "few")
7772 (set_attr "mode" "DI")])
7773
7774 (define_split
7775 [(set (match_operand:DI 0 "register_operand" "")
7776 (udiv:DI (match_operand:DI 1 "register_operand" "")
7777 (match_operand:DI 2 "nonimmediate_operand" "")))
7778 (set (match_operand:DI 3 "register_operand" "")
7779 (umod:DI (match_dup 1) (match_dup 2)))
7780 (clobber (reg:CC 17))]
7781 "reload_completed && TARGET_64BIT"
7782 [(set (match_dup 3) (const_int 0))
7783 (parallel [(set (match_dup 0)
7784 (udiv:DI (match_dup 1) (match_dup 2)))
7785 (set (match_dup 3)
7786 (umod:DI (match_dup 1) (match_dup 2)))
7787 (use (match_dup 3))
7788 (clobber (reg:CC 17))])]
7789 "")
7790
7791 (define_insn "udivmodsi4"
7792 [(set (match_operand:SI 0 "register_operand" "=a")
7793 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7794 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7795 (set (match_operand:SI 3 "register_operand" "=&d")
7796 (umod:SI (match_dup 1) (match_dup 2)))
7797 (clobber (reg:CC 17))]
7798 ""
7799 "xor{l}\\t%3, %3\;div{l}\\t%2"
7800 [(set_attr "type" "multi")
7801 (set_attr "length_immediate" "0")
7802 (set_attr "mode" "SI")])
7803
7804 (define_insn "*udivmodsi4_noext"
7805 [(set (match_operand:SI 0 "register_operand" "=a")
7806 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7807 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7808 (set (match_operand:SI 3 "register_operand" "=d")
7809 (umod:SI (match_dup 1) (match_dup 2)))
7810 (use (match_dup 3))
7811 (clobber (reg:CC 17))]
7812 ""
7813 "div{l}\\t%2"
7814 [(set_attr "type" "idiv")
7815 (set_attr "ppro_uops" "few")
7816 (set_attr "mode" "SI")])
7817
7818 (define_split
7819 [(set (match_operand:SI 0 "register_operand" "")
7820 (udiv:SI (match_operand:SI 1 "register_operand" "")
7821 (match_operand:SI 2 "nonimmediate_operand" "")))
7822 (set (match_operand:SI 3 "register_operand" "")
7823 (umod:SI (match_dup 1) (match_dup 2)))
7824 (clobber (reg:CC 17))]
7825 "reload_completed"
7826 [(set (match_dup 3) (const_int 0))
7827 (parallel [(set (match_dup 0)
7828 (udiv:SI (match_dup 1) (match_dup 2)))
7829 (set (match_dup 3)
7830 (umod:SI (match_dup 1) (match_dup 2)))
7831 (use (match_dup 3))
7832 (clobber (reg:CC 17))])]
7833 "")
7834
7835 (define_expand "udivmodhi4"
7836 [(set (match_dup 4) (const_int 0))
7837 (parallel [(set (match_operand:HI 0 "register_operand" "")
7838 (udiv:HI (match_operand:HI 1 "register_operand" "")
7839 (match_operand:HI 2 "nonimmediate_operand" "")))
7840 (set (match_operand:HI 3 "register_operand" "")
7841 (umod:HI (match_dup 1) (match_dup 2)))
7842 (use (match_dup 4))
7843 (clobber (reg:CC 17))])]
7844 "TARGET_HIMODE_MATH"
7845 "operands[4] = gen_reg_rtx (HImode);")
7846
7847 (define_insn "*udivmodhi_noext"
7848 [(set (match_operand:HI 0 "register_operand" "=a")
7849 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7850 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7851 (set (match_operand:HI 3 "register_operand" "=d")
7852 (umod:HI (match_dup 1) (match_dup 2)))
7853 (use (match_operand:HI 4 "register_operand" "3"))
7854 (clobber (reg:CC 17))]
7855 ""
7856 "div{w}\\t%2"
7857 [(set_attr "type" "idiv")
7858 (set_attr "mode" "HI")
7859 (set_attr "ppro_uops" "few")])
7860
7861 ;; We can not use div/idiv for double division, because it causes
7862 ;; "division by zero" on the overflow and that's not what we expect
7863 ;; from truncate. Because true (non truncating) double division is
7864 ;; never generated, we can't create this insn anyway.
7865 ;
7866 ;(define_insn ""
7867 ; [(set (match_operand:SI 0 "register_operand" "=a")
7868 ; (truncate:SI
7869 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7870 ; (zero_extend:DI
7871 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7872 ; (set (match_operand:SI 3 "register_operand" "=d")
7873 ; (truncate:SI
7874 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7875 ; (clobber (reg:CC 17))]
7876 ; ""
7877 ; "div{l}\\t{%2, %0|%0, %2}"
7878 ; [(set_attr "type" "idiv")
7879 ; (set_attr "ppro_uops" "few")])
7880 \f
7881 ;;- Logical AND instructions
7882
7883 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7884 ;; Note that this excludes ah.
7885
7886 (define_insn "*testdi_1_rex64"
7887 [(set (reg 17)
7888 (compare
7889 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
7890 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
7891 (const_int 0)))]
7892 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7893 "@
7894 test{l}\\t{%k1, %k0|%k0, %k1}
7895 test{l}\\t{%k1, %k0|%k0, %k1}
7896 test{q}\\t{%1, %0|%0, %1}
7897 test{q}\\t{%1, %0|%0, %1}
7898 test{q}\\t{%1, %0|%0, %1}"
7899 [(set_attr "type" "test")
7900 (set_attr "modrm" "0,1,0,1,1")
7901 (set_attr "mode" "SI,SI,DI,DI,DI")
7902 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7903
7904 (define_insn "testsi_1"
7905 [(set (reg 17)
7906 (compare
7907 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
7908 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
7909 (const_int 0)))]
7910 "ix86_match_ccmode (insn, CCNOmode)"
7911 "test{l}\\t{%1, %0|%0, %1}"
7912 [(set_attr "type" "test")
7913 (set_attr "modrm" "0,1,1")
7914 (set_attr "mode" "SI")
7915 (set_attr "pent_pair" "uv,np,uv")])
7916
7917 (define_expand "testsi_ccno_1"
7918 [(set (reg:CCNO 17)
7919 (compare:CCNO
7920 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7921 (match_operand:SI 1 "nonmemory_operand" ""))
7922 (const_int 0)))]
7923 ""
7924 "")
7925
7926 (define_insn "*testhi_1"
7927 [(set (reg 17)
7928 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
7929 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
7930 (const_int 0)))]
7931 "ix86_match_ccmode (insn, CCNOmode)"
7932 "test{w}\\t{%1, %0|%0, %1}"
7933 [(set_attr "type" "test")
7934 (set_attr "modrm" "0,1,1")
7935 (set_attr "mode" "HI")
7936 (set_attr "pent_pair" "uv,np,uv")])
7937
7938 (define_expand "testqi_ccz_1"
7939 [(set (reg:CCZ 17)
7940 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7941 (match_operand:QI 1 "nonmemory_operand" ""))
7942 (const_int 0)))]
7943 ""
7944 "")
7945
7946 (define_insn "*testqi_1"
7947 [(set (reg 17)
7948 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
7949 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
7950 (const_int 0)))]
7951 "ix86_match_ccmode (insn, CCNOmode)"
7952 "*
7953 {
7954 if (which_alternative == 3)
7955 {
7956 if (GET_CODE (operands[1]) == CONST_INT
7957 && (INTVAL (operands[1]) & 0xffffff00))
7958 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7959 return \"test{l}\\t{%1, %k0|%k0, %1}\";
7960 }
7961 return \"test{b}\\t{%1, %0|%0, %1}\";
7962 }"
7963 [(set_attr "type" "test")
7964 (set_attr "modrm" "0,1,1,1")
7965 (set_attr "mode" "QI,QI,QI,SI")
7966 (set_attr "pent_pair" "uv,np,uv,np")])
7967
7968 (define_expand "testqi_ext_ccno_0"
7969 [(set (reg:CCNO 17)
7970 (compare:CCNO
7971 (and:SI
7972 (zero_extract:SI
7973 (match_operand 0 "ext_register_operand" "")
7974 (const_int 8)
7975 (const_int 8))
7976 (match_operand 1 "const_int_operand" ""))
7977 (const_int 0)))]
7978 ""
7979 "")
7980
7981 (define_insn "*testqi_ext_0"
7982 [(set (reg 17)
7983 (compare
7984 (and:SI
7985 (zero_extract:SI
7986 (match_operand 0 "ext_register_operand" "Q")
7987 (const_int 8)
7988 (const_int 8))
7989 (match_operand 1 "const_int_operand" "n"))
7990 (const_int 0)))]
7991 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
7992 && ix86_match_ccmode (insn, CCNOmode)"
7993 "test{b}\\t{%1, %h0|%h0, %1}"
7994 [(set_attr "type" "test")
7995 (set_attr "mode" "QI")
7996 (set_attr "length_immediate" "1")
7997 (set_attr "pent_pair" "np")])
7998
7999 (define_insn "*testqi_ext_1"
8000 [(set (reg 17)
8001 (compare
8002 (and:SI
8003 (zero_extract:SI
8004 (match_operand 0 "ext_register_operand" "Q")
8005 (const_int 8)
8006 (const_int 8))
8007 (zero_extend:SI
8008 (match_operand:QI 1 "nonimmediate_operand" "Qm")))
8009 (const_int 0)))]
8010 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8011 "test{b}\\t{%1, %h0|%h0, %1}"
8012 [(set_attr "type" "test")
8013 (set_attr "mode" "QI")])
8014
8015 (define_insn "*testqi_ext_1_rex64"
8016 [(set (reg 17)
8017 (compare
8018 (and:SI
8019 (zero_extract:SI
8020 (match_operand 0 "ext_register_operand" "Q")
8021 (const_int 8)
8022 (const_int 8))
8023 (zero_extend:SI
8024 (match_operand:QI 1 "ext_register_operand" "Q")))
8025 (const_int 0)))]
8026 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8027 "test{b}\\t{%1, %h0|%h0, %1}"
8028 [(set_attr "type" "test")
8029 (set_attr "mode" "QI")])
8030
8031 (define_insn "*testqi_ext_2"
8032 [(set (reg 17)
8033 (compare
8034 (and:SI
8035 (zero_extract:SI
8036 (match_operand 0 "ext_register_operand" "Q")
8037 (const_int 8)
8038 (const_int 8))
8039 (zero_extract:SI
8040 (match_operand 1 "ext_register_operand" "Q")
8041 (const_int 8)
8042 (const_int 8)))
8043 (const_int 0)))]
8044 "ix86_match_ccmode (insn, CCNOmode)"
8045 "test{b}\\t{%h1, %h0|%h0, %h1}"
8046 [(set_attr "type" "test")
8047 (set_attr "mode" "QI")])
8048
8049 ;; Combine likes to form bit extractions for some tests. Humor it.
8050 (define_insn "*testqi_ext_3"
8051 [(set (reg 17)
8052 (compare (zero_extract:SI
8053 (match_operand 0 "nonimmediate_operand" "rm")
8054 (match_operand:SI 1 "const_int_operand" "")
8055 (match_operand:SI 2 "const_int_operand" ""))
8056 (const_int 0)))]
8057 "ix86_match_ccmode (insn, CCNOmode)
8058 && (GET_MODE (operands[0]) == SImode
8059 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8060 || GET_MODE (operands[0]) == HImode
8061 || GET_MODE (operands[0]) == QImode)"
8062 "#")
8063
8064 (define_insn "*testqi_ext_3_rex64"
8065 [(set (reg 17)
8066 (compare (zero_extract:DI
8067 (match_operand 0 "nonimmediate_operand" "rm")
8068 (match_operand:DI 1 "const_int_operand" "")
8069 (match_operand:DI 2 "const_int_operand" ""))
8070 (const_int 0)))]
8071 "ix86_match_ccmode (insn, CCNOmode)
8072 && TARGET_64BIT
8073 && (GET_MODE (operands[0]) == SImode
8074 || GET_MODE (operands[0]) == DImode
8075 || GET_MODE (operands[0]) == HImode
8076 || GET_MODE (operands[0]) == QImode)"
8077 "#")
8078
8079 (define_split
8080 [(set (reg 17)
8081 (compare (zero_extract
8082 (match_operand 0 "nonimmediate_operand" "rm")
8083 (match_operand 1 "const_int_operand" "")
8084 (match_operand 2 "const_int_operand" ""))
8085 (const_int 0)))]
8086 "ix86_match_ccmode (insn, CCNOmode)"
8087 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8088 "
8089 {
8090 HOST_WIDE_INT len = INTVAL (operands[1]);
8091 HOST_WIDE_INT pos = INTVAL (operands[2]);
8092 HOST_WIDE_INT mask;
8093 enum machine_mode mode;
8094
8095 mode = GET_MODE (operands[0]);
8096 if (GET_CODE (operands[0]) == MEM)
8097 {
8098 /* ??? Combine likes to put non-volatile mem extractions in QImode
8099 no matter the size of the test. So find a mode that works. */
8100 if (! MEM_VOLATILE_P (operands[0]))
8101 {
8102 mode = smallest_mode_for_size (pos + len, MODE_INT);
8103 operands[0] = change_address (operands[0], mode, NULL_RTX);
8104 }
8105 }
8106 else if (mode == HImode && pos + len <= 8)
8107 {
8108 /* Small HImode tests can be converted to QImode. */
8109 mode = QImode;
8110 operands[0] = gen_lowpart (QImode, operands[0]);
8111 }
8112
8113 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8114 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8115
8116 operands[3] = gen_rtx_AND (mode, operands[0],
8117 GEN_INT (trunc_int_for_mode (mask, mode)));
8118 }")
8119
8120 ;; %%% This used to optimize known byte-wide and operations to memory,
8121 ;; and sometimes to QImode registers. If this is considered useful,
8122 ;; it should be done with splitters.
8123
8124 (define_expand "anddi3"
8125 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8126 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8127 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8128 (clobber (reg:CC 17))]
8129 "TARGET_64BIT"
8130 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8131
8132 (define_insn "*anddi_1_rex64"
8133 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8134 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8135 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8136 (clobber (reg:CC 17))]
8137 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8138 "*
8139 {
8140 switch (get_attr_type (insn))
8141 {
8142 case TYPE_IMOVX:
8143 {
8144 enum machine_mode mode;
8145
8146 if (GET_CODE (operands[2]) != CONST_INT)
8147 abort ();
8148 if (INTVAL (operands[2]) == 0xff)
8149 mode = QImode;
8150 else if (INTVAL (operands[2]) == 0xffff)
8151 mode = HImode;
8152 else
8153 abort ();
8154
8155 operands[1] = gen_lowpart (mode, operands[1]);
8156 if (mode == QImode)
8157 return \"movz{bq|x}\\t{%1,%0|%0, %1}\";
8158 else
8159 return \"movz{wq|x}\\t{%1,%0|%0, %1}\";
8160 }
8161
8162 default:
8163 if (! rtx_equal_p (operands[0], operands[1]))
8164 abort ();
8165 if (get_attr_mode (insn) == MODE_SI)
8166 return \"and{l}\\t{%k2, %k0|%k0, %k2}\";
8167 else
8168 return \"and{q}\\t{%2, %0|%0, %2}\";
8169 }
8170 }"
8171 [(set_attr "type" "alu,alu,alu,imovx")
8172 (set_attr "length_immediate" "*,*,*,0")
8173 (set_attr "mode" "SI,DI,DI,DI")])
8174
8175 (define_insn "*anddi_2"
8176 [(set (reg 17)
8177 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8178 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8179 (const_int 0)))
8180 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8181 (and:DI (match_dup 1) (match_dup 2)))]
8182 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183 && ix86_binary_operator_ok (AND, DImode, operands)"
8184 "@
8185 and{l}\\t{%k2, %k0|%k0, %k2}
8186 and{q}\\t{%2, %0|%0, %2}
8187 and{q}\\t{%2, %0|%0, %2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "mode" "SI,DI,DI")])
8190
8191 (define_expand "andsi3"
8192 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8193 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8194 (match_operand:SI 2 "general_operand" "")))
8195 (clobber (reg:CC 17))]
8196 ""
8197 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8198
8199 (define_insn "*andsi_1"
8200 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8201 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8202 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8203 (clobber (reg:CC 17))]
8204 "ix86_binary_operator_ok (AND, SImode, operands)"
8205 "*
8206 {
8207 switch (get_attr_type (insn))
8208 {
8209 case TYPE_IMOVX:
8210 {
8211 enum machine_mode mode;
8212
8213 if (GET_CODE (operands[2]) != CONST_INT)
8214 abort ();
8215 if (INTVAL (operands[2]) == 0xff)
8216 mode = QImode;
8217 else if (INTVAL (operands[2]) == 0xffff)
8218 mode = HImode;
8219 else
8220 abort ();
8221
8222 operands[1] = gen_lowpart (mode, operands[1]);
8223 if (mode == QImode)
8224 return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
8225 else
8226 return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
8227 }
8228
8229 default:
8230 if (! rtx_equal_p (operands[0], operands[1]))
8231 abort ();
8232 return \"and{l}\\t{%2, %0|%0, %2}\";
8233 }
8234 }"
8235 [(set_attr "type" "alu,alu,imovx")
8236 (set_attr "length_immediate" "*,*,0")
8237 (set_attr "mode" "SI")])
8238
8239 (define_split
8240 [(set (match_operand 0 "register_operand" "")
8241 (and (match_dup 0)
8242 (const_int -65536)))
8243 (clobber (reg:CC 17))]
8244 "optimize_size
8245 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode
8246 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))"
8247 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8248 "operands[1] = gen_lowpart (HImode, operands[0]);")
8249
8250 (define_split
8251 [(set (match_operand 0 "q_regs_operand" "")
8252 (and (match_dup 0)
8253 (const_int -256)))
8254 (clobber (reg:CC 17))]
8255 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
8256 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode
8257 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))"
8258 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8259 "operands[1] = gen_lowpart (QImode, operands[0]);")
8260
8261 (define_split
8262 [(set (match_operand 0 "register_operand" "")
8263 (and (match_dup 0)
8264 (const_int -65281)))
8265 (clobber (reg:CC 17))]
8266 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
8267 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode
8268 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
8269 && (! reload_completed || ANY_QI_REG_P (operands[0]))"
8270 [(parallel [(set (zero_extract:SI (match_dup 0)
8271 (const_int 8)
8272 (const_int 8))
8273 (xor:SI
8274 (zero_extract:SI (match_dup 0)
8275 (const_int 8)
8276 (const_int 8))
8277 (zero_extract:SI (match_dup 0)
8278 (const_int 8)
8279 (const_int 8))))
8280 (clobber (reg:CC 17))])]
8281 "operands[0] = gen_lowpart (SImode, operands[0]);")
8282
8283 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8284 (define_insn "*andsi_1_zext"
8285 [(set (match_operand:DI 0 "register_operand" "=r")
8286 (zero_extend:DI
8287 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288 (match_operand:SI 2 "general_operand" "rim"))))
8289 (clobber (reg:CC 17))]
8290 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8291 "and{l}\\t{%2, %k0|%k0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "SI")])
8294
8295 (define_insn "*andsi_2"
8296 [(set (reg 17)
8297 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8298 (match_operand:SI 2 "general_operand" "rim,ri"))
8299 (const_int 0)))
8300 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8301 (and:SI (match_dup 1) (match_dup 2)))]
8302 "ix86_match_ccmode (insn, CCNOmode)
8303 && ix86_binary_operator_ok (AND, SImode, operands)"
8304 "and{l}\\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "SI")])
8307
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*andsi_2_zext"
8310 [(set (reg 17)
8311 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312 (match_operand:SI 2 "general_operand" "rim"))
8313 (const_int 0)))
8314 (set (match_operand:DI 0 "register_operand" "=r")
8315 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8316 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8317 && ix86_binary_operator_ok (AND, SImode, operands)"
8318 "and{l}\\t{%2, %k0|%k0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "SI")])
8321
8322 (define_expand "andhi3"
8323 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325 (match_operand:HI 2 "general_operand" "")))
8326 (clobber (reg:CC 17))]
8327 "TARGET_HIMODE_MATH"
8328 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8329
8330 (define_insn "*andhi_1"
8331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8332 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8333 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8334 (clobber (reg:CC 17))]
8335 "ix86_binary_operator_ok (AND, HImode, operands)"
8336 "*
8337 {
8338 switch (get_attr_type (insn))
8339 {
8340 case TYPE_IMOVX:
8341 if (GET_CODE (operands[2]) != CONST_INT)
8342 abort ();
8343 if (INTVAL (operands[2]) == 0xff)
8344 return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
8345 abort ();
8346
8347 default:
8348 if (! rtx_equal_p (operands[0], operands[1]))
8349 abort ();
8350
8351 return \"and{w}\\t{%2, %0|%0, %2}\";
8352 }
8353 }"
8354 [(set_attr "type" "alu,alu,imovx")
8355 (set_attr "length_immediate" "*,*,0")
8356 (set_attr "mode" "HI,HI,SI")])
8357
8358 (define_insn "*andhi_2"
8359 [(set (reg 17)
8360 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8361 (match_operand:HI 2 "general_operand" "rim,ri"))
8362 (const_int 0)))
8363 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8364 (and:HI (match_dup 1) (match_dup 2)))]
8365 "ix86_match_ccmode (insn, CCNOmode)
8366 && ix86_binary_operator_ok (AND, HImode, operands)"
8367 "and{w}\\t{%2, %0|%0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "mode" "HI")])
8370
8371 (define_expand "andqi3"
8372 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8373 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8374 (match_operand:QI 2 "general_operand" "")))
8375 (clobber (reg:CC 17))]
8376 "TARGET_QIMODE_MATH"
8377 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8378
8379 ;; %%% Potential partial reg stall on alternative 2. What to do?
8380 (define_insn "*andqi_1"
8381 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8382 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8384 (clobber (reg:CC 17))]
8385 "ix86_binary_operator_ok (AND, QImode, operands)"
8386 "@
8387 and{b}\\t{%2, %0|%0, %2}
8388 and{b}\\t{%2, %0|%0, %2}
8389 and{l}\\t{%k2, %k0|%k0, %k2}"
8390 [(set_attr "type" "alu")
8391 (set_attr "mode" "QI,QI,SI")])
8392
8393 (define_insn "*andqi_1_slp"
8394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8395 (and:QI (match_dup 0)
8396 (match_operand:QI 1 "general_operand" "qi,qmi")))
8397 (clobber (reg:CC 17))]
8398 ""
8399 "and{b}\\t{%1, %0|%0, %1}"
8400 [(set_attr "type" "alu1")
8401 (set_attr "mode" "QI")])
8402
8403 (define_insn "*andqi_2"
8404 [(set (reg 17)
8405 (compare (and:QI
8406 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8407 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8408 (const_int 0)))
8409 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8410 (and:QI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, QImode, operands)"
8413 "*
8414 {
8415 if (which_alternative == 2)
8416 {
8417 if (GET_CODE (operands[2]) == CONST_INT
8418 && (INTVAL (operands[2]) & 0xffffff00))
8419 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8420 return \"and{l}\\t{%2, %k0|%k0, %2}\";
8421 }
8422 return \"and{b}\\t{%2, %0|%0, %2}\";
8423 }"
8424 [(set_attr "type" "alu")
8425 (set_attr "mode" "QI,QI,SI")])
8426
8427 (define_insn "*andqi_2_slp"
8428 [(set (reg 17)
8429 (compare (and:QI
8430 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8431 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8432 (const_int 0)))
8433 (set (strict_low_part (match_dup 0))
8434 (and:QI (match_dup 0) (match_dup 1)))]
8435 "ix86_match_ccmode (insn, CCNOmode)"
8436 "and{b}\\t{%1, %0|%0, %1}"
8437 [(set_attr "type" "alu1")
8438 (set_attr "mode" "QI")])
8439
8440 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8441 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8442 ;; for a QImode operand, which of course failed.
8443
8444 (define_insn "andqi_ext_0"
8445 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8446 (const_int 8)
8447 (const_int 8))
8448 (and:SI
8449 (zero_extract:SI
8450 (match_operand 1 "ext_register_operand" "0")
8451 (const_int 8)
8452 (const_int 8))
8453 (match_operand 2 "const_int_operand" "n")))
8454 (clobber (reg:CC 17))]
8455 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8456 "and{b}\\t{%2, %h0|%h0, %2}"
8457 [(set_attr "type" "alu")
8458 (set_attr "length_immediate" "1")
8459 (set_attr "mode" "QI")])
8460
8461 ;; Generated by peephole translating test to and. This shows up
8462 ;; often in fp comparisons.
8463
8464 (define_insn "*andqi_ext_0_cc"
8465 [(set (reg 17)
8466 (compare
8467 (and:SI
8468 (zero_extract:SI
8469 (match_operand 1 "ext_register_operand" "0")
8470 (const_int 8)
8471 (const_int 8))
8472 (match_operand 2 "const_int_operand" "n"))
8473 (const_int 0)))
8474 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 (const_int 8)
8476 (const_int 8))
8477 (and:SI
8478 (zero_extract:SI
8479 (match_dup 1)
8480 (const_int 8)
8481 (const_int 8))
8482 (match_dup 2)))]
8483 "ix86_match_ccmode (insn, CCNOmode)
8484 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
8485 "and{b}\\t{%2, %h0|%h0, %2}"
8486 [(set_attr "type" "alu")
8487 (set_attr "length_immediate" "1")
8488 (set_attr "mode" "QI")])
8489
8490 (define_insn "*andqi_ext_1"
8491 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8492 (const_int 8)
8493 (const_int 8))
8494 (and:SI
8495 (zero_extract:SI
8496 (match_operand 1 "ext_register_operand" "0")
8497 (const_int 8)
8498 (const_int 8))
8499 (zero_extend:SI
8500 (match_operand:QI 2 "general_operand" "Qm"))))
8501 (clobber (reg:CC 17))]
8502 "!TARGET_64BIT"
8503 "and{b}\\t{%2, %h0|%h0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "length_immediate" "0")
8506 (set_attr "mode" "QI")])
8507
8508 (define_insn "*andqi_ext_1_rex64"
8509 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8510 (const_int 8)
8511 (const_int 8))
8512 (and:SI
8513 (zero_extract:SI
8514 (match_operand 1 "ext_register_operand" "0")
8515 (const_int 8)
8516 (const_int 8))
8517 (zero_extend:SI
8518 (match_operand:QI 2 "ext_register_operand" "Q"))))
8519 (clobber (reg:CC 17))]
8520 "TARGET_64BIT"
8521 "and{b}\\t{%2, %h0|%h0, %2}"
8522 [(set_attr "type" "alu")
8523 (set_attr "length_immediate" "0")
8524 (set_attr "mode" "QI")])
8525
8526 (define_insn "*andqi_ext_2"
8527 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8528 (const_int 8)
8529 (const_int 8))
8530 (and:SI
8531 (zero_extract:SI
8532 (match_operand 1 "ext_register_operand" "%0")
8533 (const_int 8)
8534 (const_int 8))
8535 (zero_extract:SI
8536 (match_operand 2 "ext_register_operand" "Q")
8537 (const_int 8)
8538 (const_int 8))))
8539 (clobber (reg:CC 17))]
8540 ""
8541 "and{b}\\t{%h2, %h0|%h0, %h2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "length_immediate" "0")
8544 (set_attr "mode" "QI")])
8545 \f
8546 ;; Logical inclusive OR instructions
8547
8548 ;; %%% This used to optimize known byte-wide and operations to memory.
8549 ;; If this is considered useful, it should be done with splitters.
8550
8551 (define_expand "iordi3"
8552 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8553 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8554 (match_operand:DI 2 "x86_64_general_operand" "")))
8555 (clobber (reg:CC 17))]
8556 "TARGET_64BIT"
8557 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8558
8559 (define_insn "*iordi_1_rex64"
8560 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8561 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8562 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8563 (clobber (reg:CC 17))]
8564 "TARGET_64BIT
8565 && ix86_binary_operator_ok (IOR, DImode, operands)"
8566 "or{q}\\t{%2, %0|%0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "DI")])
8569
8570 (define_insn "*iordi_2_rex64"
8571 [(set (reg 17)
8572 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8574 (const_int 0)))
8575 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8576 (ior:DI (match_dup 1) (match_dup 2)))]
8577 "TARGET_64BIT
8578 && ix86_match_ccmode (insn, CCNOmode)
8579 && ix86_binary_operator_ok (IOR, DImode, operands)"
8580 "or{q}\\t{%2, %0|%0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "DI")])
8583
8584 (define_insn "*iordi_3_rex64"
8585 [(set (reg 17)
8586 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8587 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8588 (const_int 0)))
8589 (clobber (match_scratch:DI 0 "=r"))]
8590 "TARGET_64BIT
8591 && ix86_match_ccmode (insn, CCNOmode)
8592 && ix86_binary_operator_ok (IOR, DImode, operands)"
8593 "or{q}\\t{%2, %0|%0, %2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "mode" "DI")])
8596
8597
8598 (define_expand "iorsi3"
8599 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8600 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8601 (match_operand:SI 2 "general_operand" "")))
8602 (clobber (reg:CC 17))]
8603 ""
8604 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8605
8606 (define_insn "*iorsi_1"
8607 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8608 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:SI 2 "general_operand" "ri,rmi")))
8610 (clobber (reg:CC 17))]
8611 "ix86_binary_operator_ok (IOR, SImode, operands)"
8612 "or{l}\\t{%2, %0|%0, %2}"
8613 [(set_attr "type" "alu")
8614 (set_attr "mode" "SI")])
8615
8616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8617 (define_insn "*iorsi_1_zext"
8618 [(set (match_operand:DI 0 "register_operand" "=rm")
8619 (zero_extend:DI
8620 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8621 (match_operand:SI 2 "general_operand" "rim"))))
8622 (clobber (reg:CC 17))]
8623 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8624 "or{l}\\t{%2, %k0|%k0, %2}"
8625 [(set_attr "type" "alu")
8626 (set_attr "mode" "SI")])
8627
8628 (define_insn "*iorsi_1_zext_imm"
8629 [(set (match_operand:DI 0 "register_operand" "=rm")
8630 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8631 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8632 (clobber (reg:CC 17))]
8633 "TARGET_64BIT"
8634 "or{l}\\t{%2, %k0|%k0, %2}"
8635 [(set_attr "type" "alu")
8636 (set_attr "mode" "SI")])
8637
8638 (define_insn "*iorsi_2"
8639 [(set (reg 17)
8640 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8641 (match_operand:SI 2 "general_operand" "rim,ri"))
8642 (const_int 0)))
8643 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8644 (ior:SI (match_dup 1) (match_dup 2)))]
8645 "ix86_match_ccmode (insn, CCNOmode)
8646 && ix86_binary_operator_ok (IOR, SImode, operands)"
8647 "or{l}\\t{%2, %0|%0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "SI")])
8650
8651 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8652 ;; ??? Special case for immediate operand is missing - it is tricky.
8653 (define_insn "*iorsi_2_zext"
8654 [(set (reg 17)
8655 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8656 (match_operand:SI 2 "general_operand" "rim"))
8657 (const_int 0)))
8658 (set (match_operand:DI 0 "register_operand" "=r")
8659 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8660 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8661 && ix86_binary_operator_ok (IOR, SImode, operands)"
8662 "or{l}\\t{%2, %k0|%k0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "mode" "SI")])
8665
8666 (define_insn "*iorsi_2_zext_imm"
8667 [(set (reg 17)
8668 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8670 (const_int 0)))
8671 (set (match_operand:DI 0 "register_operand" "=r")
8672 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8673 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674 && ix86_binary_operator_ok (IOR, SImode, operands)"
8675 "or{l}\\t{%2, %k0|%k0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "SI")])
8678
8679 (define_insn "*iorsi_3"
8680 [(set (reg 17)
8681 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682 (match_operand:SI 2 "general_operand" "rim"))
8683 (const_int 0)))
8684 (clobber (match_scratch:SI 0 "=r"))]
8685 "ix86_match_ccmode (insn, CCNOmode)
8686 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8687 "or{l}\\t{%2, %0|%0, %2}"
8688 [(set_attr "type" "alu")
8689 (set_attr "mode" "SI")])
8690
8691 (define_expand "iorhi3"
8692 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8693 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8694 (match_operand:HI 2 "general_operand" "")))
8695 (clobber (reg:CC 17))]
8696 "TARGET_HIMODE_MATH"
8697 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8698
8699 (define_insn "*iorhi_1"
8700 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8701 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8702 (match_operand:HI 2 "general_operand" "rmi,ri")))
8703 (clobber (reg:CC 17))]
8704 "ix86_binary_operator_ok (IOR, HImode, operands)"
8705 "or{w}\\t{%2, %0|%0, %2}"
8706 [(set_attr "type" "alu")
8707 (set_attr "mode" "HI")])
8708
8709 (define_insn "*iorhi_2"
8710 [(set (reg 17)
8711 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8712 (match_operand:HI 2 "general_operand" "rim,ri"))
8713 (const_int 0)))
8714 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8715 (ior:HI (match_dup 1) (match_dup 2)))]
8716 "ix86_match_ccmode (insn, CCNOmode)
8717 && ix86_binary_operator_ok (IOR, HImode, operands)"
8718 "or{w}\\t{%2, %0|%0, %2}"
8719 [(set_attr "type" "alu")
8720 (set_attr "mode" "HI")])
8721
8722 (define_insn "*iorhi_3"
8723 [(set (reg 17)
8724 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8725 (match_operand:HI 2 "general_operand" "rim"))
8726 (const_int 0)))
8727 (clobber (match_scratch:HI 0 "=r"))]
8728 "ix86_match_ccmode (insn, CCNOmode)
8729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8730 "or{w}\\t{%2, %0|%0, %2}"
8731 [(set_attr "type" "alu")
8732 (set_attr "mode" "HI")])
8733
8734 (define_expand "iorqi3"
8735 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8736 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8737 (match_operand:QI 2 "general_operand" "")))
8738 (clobber (reg:CC 17))]
8739 "TARGET_QIMODE_MATH"
8740 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8741
8742 ;; %%% Potential partial reg stall on alternative 2. What to do?
8743 (define_insn "*iorqi_1"
8744 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8745 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8746 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8747 (clobber (reg:CC 17))]
8748 "ix86_binary_operator_ok (IOR, QImode, operands)"
8749 "@
8750 or{b}\\t{%2, %0|%0, %2}
8751 or{b}\\t{%2, %0|%0, %2}
8752 or{l}\\t{%k2, %k0|%k0, %k2}"
8753 [(set_attr "type" "alu")
8754 (set_attr "mode" "QI,QI,SI")])
8755
8756 (define_insn "*iorqi_1_slp"
8757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8758 (ior:QI (match_dup 0)
8759 (match_operand:QI 1 "general_operand" "qmi,qi")))
8760 (clobber (reg:CC 17))]
8761 ""
8762 "or{b}\\t{%1, %0|%0, %1}"
8763 [(set_attr "type" "alu1")
8764 (set_attr "mode" "QI")])
8765
8766 (define_insn "*iorqi_2"
8767 [(set (reg 17)
8768 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8769 (match_operand:QI 2 "general_operand" "qim,qi"))
8770 (const_int 0)))
8771 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8772 (ior:QI (match_dup 1) (match_dup 2)))]
8773 "ix86_match_ccmode (insn, CCNOmode)
8774 && ix86_binary_operator_ok (IOR, QImode, operands)"
8775 "or{b}\\t{%2, %0|%0, %2}"
8776 [(set_attr "type" "alu")
8777 (set_attr "mode" "QI")])
8778
8779 (define_insn "*iorqi_2_slp"
8780 [(set (reg 17)
8781 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8782 (match_operand:QI 1 "general_operand" "qim,qi"))
8783 (const_int 0)))
8784 (set (strict_low_part (match_dup 0))
8785 (ior:QI (match_dup 0) (match_dup 1)))]
8786 "ix86_match_ccmode (insn, CCNOmode)"
8787 "or{b}\\t{%1, %0|%0, %1}"
8788 [(set_attr "type" "alu1")
8789 (set_attr "mode" "QI")])
8790
8791 (define_insn "*iorqi_3"
8792 [(set (reg 17)
8793 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8794 (match_operand:QI 2 "general_operand" "qim"))
8795 (const_int 0)))
8796 (clobber (match_scratch:QI 0 "=q"))]
8797 "ix86_match_ccmode (insn, CCNOmode)
8798 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8799 "or{b}\\t{%2, %0|%0, %2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "mode" "QI")])
8802
8803 \f
8804 ;; Logical XOR instructions
8805
8806 ;; %%% This used to optimize known byte-wide and operations to memory.
8807 ;; If this is considered useful, it should be done with splitters.
8808
8809 (define_expand "xordi3"
8810 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8811 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8812 (match_operand:DI 2 "x86_64_general_operand" "")))
8813 (clobber (reg:CC 17))]
8814 "TARGET_64BIT"
8815 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8816
8817 (define_insn "*xordi_1_rex64"
8818 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8819 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8820 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8821 (clobber (reg:CC 17))]
8822 "TARGET_64BIT
8823 && ix86_binary_operator_ok (XOR, DImode, operands)"
8824 "@
8825 xor{q}\\t{%2, %0|%0, %2}
8826 xor{q}\\t{%2, %0|%0, %2}"
8827 [(set_attr "type" "alu")
8828 (set_attr "mode" "DI,DI")])
8829
8830 (define_insn "*xordi_2_rex64"
8831 [(set (reg 17)
8832 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8833 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8834 (const_int 0)))
8835 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8836 (xor:DI (match_dup 1) (match_dup 2)))]
8837 "TARGET_64BIT
8838 && ix86_match_ccmode (insn, CCNOmode)
8839 && ix86_binary_operator_ok (XOR, DImode, operands)"
8840 "@
8841 xor{q}\\t{%2, %0|%0, %2}
8842 xor{q}\\t{%2, %0|%0, %2}"
8843 [(set_attr "type" "alu")
8844 (set_attr "mode" "DI,DI")])
8845
8846 (define_insn "*xordi_3_rex64"
8847 [(set (reg 17)
8848 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8849 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8850 (const_int 0)))
8851 (clobber (match_scratch:DI 0 "=r"))]
8852 "TARGET_64BIT
8853 && ix86_match_ccmode (insn, CCNOmode)
8854 && ix86_binary_operator_ok (XOR, DImode, operands)"
8855 "xor{q}\\t{%2, %0|%0, %2}"
8856 [(set_attr "type" "alu")
8857 (set_attr "mode" "DI")])
8858
8859 (define_expand "xorsi3"
8860 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8861 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8862 (match_operand:SI 2 "general_operand" "")))
8863 (clobber (reg:CC 17))]
8864 ""
8865 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8866
8867 (define_insn "*xorsi_1"
8868 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8869 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8870 (match_operand:SI 2 "general_operand" "ri,rm")))
8871 (clobber (reg:CC 17))]
8872 "ix86_binary_operator_ok (XOR, SImode, operands)"
8873 "xor{l}\\t{%2, %0|%0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "mode" "SI")])
8876
8877 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8878 ;; Add speccase for immediates
8879 (define_insn "*xorsi_1_zext"
8880 [(set (match_operand:DI 0 "register_operand" "=r")
8881 (zero_extend:DI
8882 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8883 (match_operand:SI 2 "general_operand" "rim"))))
8884 (clobber (reg:CC 17))]
8885 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8886 "xor{l}\\t{%2, %k0|%k0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "SI")])
8889
8890 (define_insn "*xorsi_1_zext_imm"
8891 [(set (match_operand:DI 0 "register_operand" "=r")
8892 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8893 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8894 (clobber (reg:CC 17))]
8895 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8896 "xor{l}\\t{%2, %k0|%k0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "SI")])
8899
8900 (define_insn "*xorsi_2"
8901 [(set (reg 17)
8902 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8903 (match_operand:SI 2 "general_operand" "rim,ri"))
8904 (const_int 0)))
8905 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8906 (xor:SI (match_dup 1) (match_dup 2)))]
8907 "ix86_match_ccmode (insn, CCNOmode)
8908 && ix86_binary_operator_ok (XOR, SImode, operands)"
8909 "xor{l}\\t{%2, %0|%0, %2}"
8910 [(set_attr "type" "alu")
8911 (set_attr "mode" "SI")])
8912
8913 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8914 ;; ??? Special case for immediate operand is missing - it is tricky.
8915 (define_insn "*xorsi_2_zext"
8916 [(set (reg 17)
8917 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8918 (match_operand:SI 2 "general_operand" "rim"))
8919 (const_int 0)))
8920 (set (match_operand:DI 0 "register_operand" "=r")
8921 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8922 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8923 && ix86_binary_operator_ok (XOR, SImode, operands)"
8924 "xor{l}\\t{%2, %k0|%k0, %2}"
8925 [(set_attr "type" "alu")
8926 (set_attr "mode" "SI")])
8927
8928 (define_insn "*xorsi_2_zext_imm"
8929 [(set (reg 17)
8930 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8931 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8932 (const_int 0)))
8933 (set (match_operand:DI 0 "register_operand" "=r")
8934 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8935 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8936 && ix86_binary_operator_ok (XOR, SImode, operands)"
8937 "xor{l}\\t{%2, %k0|%k0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "mode" "SI")])
8940
8941 (define_insn "*xorsi_3"
8942 [(set (reg 17)
8943 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8944 (match_operand:SI 2 "general_operand" "rim"))
8945 (const_int 0)))
8946 (clobber (match_scratch:SI 0 "=r"))]
8947 "ix86_match_ccmode (insn, CCNOmode)
8948 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8949 "xor{l}\\t{%2, %0|%0, %2}"
8950 [(set_attr "type" "alu")
8951 (set_attr "mode" "SI")])
8952
8953 (define_expand "xorhi3"
8954 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8955 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8956 (match_operand:HI 2 "general_operand" "")))
8957 (clobber (reg:CC 17))]
8958 "TARGET_HIMODE_MATH"
8959 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8960
8961 (define_insn "*xorhi_1"
8962 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8963 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8964 (match_operand:HI 2 "general_operand" "rmi,ri")))
8965 (clobber (reg:CC 17))]
8966 "ix86_binary_operator_ok (XOR, HImode, operands)"
8967 "xor{w}\\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "HI")])
8970
8971 (define_insn "*xorhi_2"
8972 [(set (reg 17)
8973 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8974 (match_operand:HI 2 "general_operand" "rim,ri"))
8975 (const_int 0)))
8976 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8977 (xor:HI (match_dup 1) (match_dup 2)))]
8978 "ix86_match_ccmode (insn, CCNOmode)
8979 && ix86_binary_operator_ok (XOR, HImode, operands)"
8980 "xor{w}\\t{%2, %0|%0, %2}"
8981 [(set_attr "type" "alu")
8982 (set_attr "mode" "HI")])
8983
8984 (define_insn "*xorhi_3"
8985 [(set (reg 17)
8986 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8987 (match_operand:HI 2 "general_operand" "rim"))
8988 (const_int 0)))
8989 (clobber (match_scratch:HI 0 "=r"))]
8990 "ix86_match_ccmode (insn, CCNOmode)
8991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8992 "xor{w}\\t{%2, %0|%0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "HI")])
8995
8996 (define_expand "xorqi3"
8997 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8998 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8999 (match_operand:QI 2 "general_operand" "")))
9000 (clobber (reg:CC 17))]
9001 "TARGET_QIMODE_MATH"
9002 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9003
9004 ;; %%% Potential partial reg stall on alternative 2. What to do?
9005 (define_insn "*xorqi_1"
9006 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9007 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9008 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9009 (clobber (reg:CC 17))]
9010 "ix86_binary_operator_ok (XOR, QImode, operands)"
9011 "@
9012 xor{b}\\t{%2, %0|%0, %2}
9013 xor{b}\\t{%2, %0|%0, %2}
9014 xor{l}\\t{%k2, %k0|%k0, %k2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "QI,QI,SI")])
9017
9018 (define_insn "*xorqi_ext_1"
9019 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9020 (const_int 8)
9021 (const_int 8))
9022 (xor:SI
9023 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9024 (const_int 8)
9025 (const_int 8))
9026 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9027 (const_int 8)
9028 (const_int 8))))
9029 (clobber (reg:CC 17))]
9030 ""
9031 "xor{b}\\t{%h2, %h0|%h0, %h2}"
9032 [(set_attr "type" "alu")
9033 (set_attr "length_immediate" "0")
9034 (set_attr "mode" "QI")])
9035
9036 (define_insn "*xorqi_cc_1"
9037 [(set (reg 17)
9038 (compare
9039 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9040 (match_operand:QI 2 "general_operand" "qim,qi"))
9041 (const_int 0)))
9042 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9043 (xor:QI (match_dup 1) (match_dup 2)))]
9044 "ix86_match_ccmode (insn, CCNOmode)
9045 && ix86_binary_operator_ok (XOR, QImode, operands)"
9046 "xor{b}\\t{%2, %0|%0, %2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "QI")])
9049
9050 (define_insn "*xorqi_cc_2"
9051 [(set (reg 17)
9052 (compare
9053 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9054 (match_operand:QI 2 "general_operand" "qim"))
9055 (const_int 0)))
9056 (clobber (match_scratch:QI 0 "=q"))]
9057 "ix86_match_ccmode (insn, CCNOmode)
9058 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9059 "xor{b}\\t{%2, %0|%0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "QI")])
9062
9063 (define_insn "*xorqi_cc_ext_1"
9064 [(set (reg 17)
9065 (compare
9066 (xor:SI
9067 (zero_extract:SI
9068 (match_operand 1 "ext_register_operand" "0")
9069 (const_int 8)
9070 (const_int 8))
9071 (match_operand:QI 2 "general_operand" "qmn"))
9072 (const_int 0)))
9073 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9074 (const_int 8)
9075 (const_int 8))
9076 (xor:SI
9077 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9078 (match_dup 2)))]
9079 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9080 "xor{b}\\t{%2, %h0|%h0, %2}"
9081 [(set_attr "type" "alu")
9082 (set_attr "mode" "QI")])
9083
9084 (define_insn "*xorqi_cc_ext_1_rex64"
9085 [(set (reg 17)
9086 (compare
9087 (xor:SI
9088 (zero_extract:SI
9089 (match_operand 1 "ext_register_operand" "0")
9090 (const_int 8)
9091 (const_int 8))
9092 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9093 (const_int 0)))
9094 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9095 (const_int 8)
9096 (const_int 8))
9097 (xor:SI
9098 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9099 (match_dup 2)))]
9100 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9101 "xor{b}\\t{%2, %h0|%h0, %2}"
9102 [(set_attr "type" "alu")
9103 (set_attr "mode" "QI")])
9104
9105 (define_expand "xorqi_cc_ext_1"
9106 [(parallel [
9107 (set (reg:CCNO 17)
9108 (compare:CCNO
9109 (xor:SI
9110 (zero_extract:SI
9111 (match_operand 1 "ext_register_operand" "")
9112 (const_int 8)
9113 (const_int 8))
9114 (match_operand:QI 2 "general_operand" ""))
9115 (const_int 0)))
9116 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9117 (const_int 8)
9118 (const_int 8))
9119 (xor:SI
9120 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9121 (match_dup 2)))])]
9122 ""
9123 "")
9124 \f
9125 ;; Negation instructions
9126
9127 (define_expand "negdi2"
9128 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9129 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9130 (clobber (reg:CC 17))])]
9131 ""
9132 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9133
9134 (define_insn "*negdi2_1"
9135 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9136 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9137 (clobber (reg:CC 17))]
9138 "!TARGET_64BIT
9139 && ix86_unary_operator_ok (NEG, DImode, operands)"
9140 "#")
9141
9142 (define_split
9143 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9144 (neg:DI (match_operand:DI 1 "general_operand" "")))
9145 (clobber (reg:CC 17))]
9146 "reload_completed
9147 && !TARGET_64BIT"
9148 [(parallel
9149 [(set (reg:CCZ 17)
9150 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9151 (set (match_dup 0) (neg:SI (match_dup 2)))])
9152 (parallel
9153 [(set (match_dup 1)
9154 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9155 (match_dup 3))
9156 (const_int 0)))
9157 (clobber (reg:CC 17))])
9158 (parallel
9159 [(set (match_dup 1)
9160 (neg:SI (match_dup 1)))
9161 (clobber (reg:CC 17))])]
9162 "split_di (operands+1, 1, operands+2, operands+3);
9163 split_di (operands+0, 1, operands+0, operands+1);")
9164
9165 (define_insn "*negdi2_1_rex64"
9166 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9167 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9168 (clobber (reg:CC 17))]
9169 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9170 "neg{q}\\t%0"
9171 [(set_attr "type" "negnot")
9172 (set_attr "mode" "DI")])
9173
9174 ;; The problem with neg is that it does not perform (compare x 0),
9175 ;; it really performs (compare 0 x), which leaves us with the zero
9176 ;; flag being the only useful item.
9177
9178 (define_insn "*negdi2_cmpz_rex64"
9179 [(set (reg:CCZ 17)
9180 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9181 (const_int 0)))
9182 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9183 (neg:DI (match_dup 1)))]
9184 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9185 "neg{q}\\t%0"
9186 [(set_attr "type" "negnot")
9187 (set_attr "mode" "DI")])
9188
9189
9190 (define_expand "negsi2"
9191 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9192 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9193 (clobber (reg:CC 17))])]
9194 ""
9195 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9196
9197 (define_insn "*negsi2_1"
9198 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9199 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9200 (clobber (reg:CC 17))]
9201 "ix86_unary_operator_ok (NEG, SImode, operands)"
9202 "neg{l}\\t%0"
9203 [(set_attr "type" "negnot")
9204 (set_attr "mode" "SI")])
9205
9206 ;; Combine is quite creative about this pattern.
9207 (define_insn "*negsi2_1_zext"
9208 [(set (match_operand:DI 0 "register_operand" "=r")
9209 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9210 (const_int 32)))
9211 (const_int 32)))
9212 (clobber (reg:CC 17))]
9213 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9214 "neg{l}\\t%k0"
9215 [(set_attr "type" "negnot")
9216 (set_attr "mode" "SI")])
9217
9218 ;; The problem with neg is that it does not perform (compare x 0),
9219 ;; it really performs (compare 0 x), which leaves us with the zero
9220 ;; flag being the only useful item.
9221
9222 (define_insn "*negsi2_cmpz"
9223 [(set (reg:CCZ 17)
9224 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9225 (const_int 0)))
9226 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9227 (neg:SI (match_dup 1)))]
9228 "ix86_unary_operator_ok (NEG, SImode, operands)"
9229 "neg{l}\\t%0"
9230 [(set_attr "type" "negnot")
9231 (set_attr "mode" "SI")])
9232
9233 (define_insn "*negsi2_cmpz_zext"
9234 [(set (reg:CCZ 17)
9235 (compare:CCZ (lshiftrt:DI
9236 (neg:DI (ashift:DI
9237 (match_operand:DI 1 "register_operand" "0")
9238 (const_int 32)))
9239 (const_int 32))
9240 (const_int 0)))
9241 (set (match_operand:DI 0 "register_operand" "=r")
9242 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9243 (const_int 32)))
9244 (const_int 32)))]
9245 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9246 "neg{l}\\t%k0"
9247 [(set_attr "type" "negnot")
9248 (set_attr "mode" "SI")])
9249
9250 (define_expand "neghi2"
9251 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9252 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9253 (clobber (reg:CC 17))])]
9254 "TARGET_HIMODE_MATH"
9255 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9256
9257 (define_insn "*neghi2_1"
9258 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9259 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9260 (clobber (reg:CC 17))]
9261 "ix86_unary_operator_ok (NEG, HImode, operands)"
9262 "neg{w}\\t%0"
9263 [(set_attr "type" "negnot")
9264 (set_attr "mode" "HI")])
9265
9266 (define_insn "*neghi2_cmpz"
9267 [(set (reg:CCZ 17)
9268 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9269 (const_int 0)))
9270 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9271 (neg:HI (match_dup 1)))]
9272 "ix86_unary_operator_ok (NEG, HImode, operands)"
9273 "neg{w}\\t%0"
9274 [(set_attr "type" "negnot")
9275 (set_attr "mode" "HI")])
9276
9277 (define_expand "negqi2"
9278 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9279 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9280 (clobber (reg:CC 17))])]
9281 "TARGET_QIMODE_MATH"
9282 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9283
9284 (define_insn "*negqi2_1"
9285 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9286 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9287 (clobber (reg:CC 17))]
9288 "ix86_unary_operator_ok (NEG, QImode, operands)"
9289 "neg{b}\\t%0"
9290 [(set_attr "type" "negnot")
9291 (set_attr "mode" "QI")])
9292
9293 (define_insn "*negqi2_cmpz"
9294 [(set (reg:CCZ 17)
9295 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9296 (const_int 0)))
9297 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9298 (neg:QI (match_dup 1)))]
9299 "ix86_unary_operator_ok (NEG, QImode, operands)"
9300 "neg{b}\\t%0"
9301 [(set_attr "type" "negnot")
9302 (set_attr "mode" "QI")])
9303
9304 ;; Changing of sign for FP values is doable using integer unit too.
9305
9306 (define_expand "negsf2"
9307 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9308 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9309 (clobber (reg:CC 17))])]
9310 "TARGET_80387"
9311 "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9312
9313 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9314 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9315 ;; to itself.
9316 (define_insn "*negsf2_if"
9317 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9318 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9319 (clobber (reg:CC 17))]
9320 "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9321 "#")
9322
9323 (define_split
9324 [(set (match_operand:SF 0 "register_operand" "")
9325 (neg:SF (match_operand:SF 1 "register_operand" "")))
9326 (clobber (reg:CC 17))]
9327 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9328 [(set (match_dup 0)
9329 (neg:SF (match_dup 1)))]
9330 "")
9331
9332 (define_split
9333 [(set (match_operand:SF 0 "register_operand" "")
9334 (neg:SF (match_operand:SF 1 "register_operand" "")))
9335 (clobber (reg:CC 17))]
9336 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9337 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9338 (clobber (reg:CC 17))])]
9339 "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9340 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9341
9342 (define_split
9343 [(set (match_operand 0 "memory_operand" "")
9344 (neg (match_operand 1 "memory_operand" "")))
9345 (clobber (reg:CC 17))]
9346 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9347 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9348 (clobber (reg:CC 17))])]
9349 "
9350 {
9351 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9352
9353 /* XFmode's size is 12, but only 10 bytes are used. */
9354 if (size == 12)
9355 size = 10;
9356 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
9357 operands[0] = adj_offsettable_operand (operands[0], size - 1);
9358 operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
9359 }")
9360
9361 (define_expand "negdf2"
9362 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9363 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9364 (clobber (reg:CC 17))])]
9365 "TARGET_80387"
9366 "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9367
9368 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9369 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9370 ;; to itself.
9371 (define_insn "*negdf2_if"
9372 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9373 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9374 (clobber (reg:CC 17))]
9375 "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9376 "#")
9377
9378 (define_split
9379 [(set (match_operand:DF 0 "register_operand" "")
9380 (neg:DF (match_operand:DF 1 "register_operand" "")))
9381 (clobber (reg:CC 17))]
9382 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9383 [(set (match_dup 0)
9384 (neg:DF (match_dup 1)))]
9385 "")
9386
9387 (define_split
9388 [(set (match_operand:DF 0 "register_operand" "")
9389 (neg:DF (match_operand:DF 1 "register_operand" "")))
9390 (clobber (reg:CC 17))]
9391 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9392 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9393 (clobber (reg:CC 17))])]
9394 "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
9395 split_di (operands+0, 1, operands+2, operands+3);")
9396
9397 (define_expand "negxf2"
9398 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9399 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9400 (clobber (reg:CC 17))])]
9401 "TARGET_80387 && !TARGET_64BIT"
9402 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9403
9404 (define_expand "negtf2"
9405 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9406 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9407 (clobber (reg:CC 17))])]
9408 "TARGET_80387"
9409 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
9410
9411 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9412 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9413 ;; to itself.
9414 (define_insn "*negxf2_if"
9415 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9416 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9417 (clobber (reg:CC 17))]
9418 "TARGET_80387 && !TARGET_64BIT
9419 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9420 "#")
9421
9422 (define_split
9423 [(set (match_operand:XF 0 "register_operand" "")
9424 (neg:XF (match_operand:XF 1 "register_operand" "")))
9425 (clobber (reg:CC 17))]
9426 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9427 [(set (match_dup 0)
9428 (neg:XF (match_dup 1)))]
9429 "")
9430
9431 (define_split
9432 [(set (match_operand:XF 0 "register_operand" "")
9433 (neg:XF (match_operand:XF 1 "register_operand" "")))
9434 (clobber (reg:CC 17))]
9435 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9436 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9437 (clobber (reg:CC 17))])]
9438 "operands[1] = GEN_INT (0x8000);
9439 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
9440
9441 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9442 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9443 ;; to itself.
9444 (define_insn "*negtf2_if"
9445 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9446 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9447 (clobber (reg:CC 17))]
9448 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
9449 "#")
9450
9451 (define_split
9452 [(set (match_operand:TF 0 "register_operand" "")
9453 (neg:TF (match_operand:TF 1 "register_operand" "")))
9454 (clobber (reg:CC 17))]
9455 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9456 [(set (match_dup 0)
9457 (neg:TF (match_dup 1)))]
9458 "")
9459
9460 (define_split
9461 [(set (match_operand:TF 0 "register_operand" "")
9462 (neg:TF (match_operand:TF 1 "register_operand" "")))
9463 (clobber (reg:CC 17))]
9464 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9465 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9466 (clobber (reg:CC 17))])]
9467 "operands[1] = GEN_INT (0x8000);
9468 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
9469
9470 ;; Conditionize these after reload. If they matches before reload, we
9471 ;; lose the clobber and ability to use integer instructions.
9472
9473 (define_insn "*negsf2_1"
9474 [(set (match_operand:SF 0 "register_operand" "=f")
9475 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9476 "TARGET_80387 && reload_completed"
9477 "fchs"
9478 [(set_attr "type" "fsgn")
9479 (set_attr "mode" "SF")
9480 (set_attr "ppro_uops" "few")])
9481
9482 (define_insn "*negdf2_1"
9483 [(set (match_operand:DF 0 "register_operand" "=f")
9484 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9485 "TARGET_80387 && reload_completed"
9486 "fchs"
9487 [(set_attr "type" "fsgn")
9488 (set_attr "mode" "DF")
9489 (set_attr "ppro_uops" "few")])
9490
9491 (define_insn "*negextendsfdf2"
9492 [(set (match_operand:DF 0 "register_operand" "=f")
9493 (neg:DF (float_extend:DF
9494 (match_operand:SF 1 "register_operand" "0"))))]
9495 "TARGET_80387"
9496 "fchs"
9497 [(set_attr "type" "fsgn")
9498 (set_attr "mode" "DF")
9499 (set_attr "ppro_uops" "few")])
9500
9501 (define_insn "*negxf2_1"
9502 [(set (match_operand:XF 0 "register_operand" "=f")
9503 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9504 "TARGET_80387 && !TARGET_64BIT && reload_completed"
9505 "fchs"
9506 [(set_attr "type" "fsgn")
9507 (set_attr "mode" "XF")
9508 (set_attr "ppro_uops" "few")])
9509
9510 (define_insn "*negextenddfxf2"
9511 [(set (match_operand:XF 0 "register_operand" "=f")
9512 (neg:XF (float_extend:XF
9513 (match_operand:DF 1 "register_operand" "0"))))]
9514 "TARGET_80387 && !TARGET_64BIT"
9515 "fchs"
9516 [(set_attr "type" "fsgn")
9517 (set_attr "mode" "XF")
9518 (set_attr "ppro_uops" "few")])
9519
9520 (define_insn "*negextendsfxf2"
9521 [(set (match_operand:XF 0 "register_operand" "=f")
9522 (neg:XF (float_extend:XF
9523 (match_operand:SF 1 "register_operand" "0"))))]
9524 "TARGET_80387 && !TARGET_64BIT"
9525 "fchs"
9526 [(set_attr "type" "fsgn")
9527 (set_attr "mode" "XF")
9528 (set_attr "ppro_uops" "few")])
9529
9530 (define_insn "*negtf2_1"
9531 [(set (match_operand:TF 0 "register_operand" "=f")
9532 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
9533 "TARGET_80387 && reload_completed"
9534 "fchs"
9535 [(set_attr "type" "fsgn")
9536 (set_attr "mode" "XF")
9537 (set_attr "ppro_uops" "few")])
9538
9539 (define_insn "*negextenddftf2"
9540 [(set (match_operand:TF 0 "register_operand" "=f")
9541 (neg:TF (float_extend:TF
9542 (match_operand:DF 1 "register_operand" "0"))))]
9543 "TARGET_80387"
9544 "fchs"
9545 [(set_attr "type" "fsgn")
9546 (set_attr "mode" "XF")
9547 (set_attr "ppro_uops" "few")])
9548
9549 (define_insn "*negextendsftf2"
9550 [(set (match_operand:TF 0 "register_operand" "=f")
9551 (neg:TF (float_extend:TF
9552 (match_operand:SF 1 "register_operand" "0"))))]
9553 "TARGET_80387"
9554 "fchs"
9555 [(set_attr "type" "fsgn")
9556 (set_attr "mode" "XF")
9557 (set_attr "ppro_uops" "few")])
9558 \f
9559 ;; Absolute value instructions
9560
9561 (define_expand "abssf2"
9562 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9563 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9564 (clobber (reg:CC 17))])]
9565 "TARGET_80387"
9566 "if (TARGET_SSE)
9567 {
9568 /* In case operand is in memory, we will not use SSE. */
9569 if (memory_operand (operands[0], VOIDmode)
9570 && rtx_equal_p (operands[0], operands[1]))
9571 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9572 else
9573 {
9574 /* Using SSE is tricky, since we need bitwise negation of -0
9575 in register. */
9576 rtx reg = gen_reg_rtx (SFmode);
9577 emit_move_insn (reg, gen_lowpart (SFmode, GEN_INT (0x80000000)));
9578 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9579 }
9580 DONE;
9581 }
9582 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9583
9584 (define_insn "abssf2_memory"
9585 [(set (match_operand:SF 0 "memory_operand" "=m")
9586 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9587 (clobber (reg:CC 17))]
9588 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9589 "#")
9590
9591 (define_insn "abssf2_ifs"
9592 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,r#xf")
9593 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
9594 (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*X#x,*X#x"))
9595 (clobber (reg:CC 17))]
9596 "TARGET_SSE"
9597 "#")
9598
9599 (define_split
9600 [(set (match_operand:SF 0 "memory_operand" "")
9601 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9602 (use (match_operand:SF 2 "" ""))
9603 (clobber (reg:CC 17))]
9604 ""
9605 [(parallel [(set (match_dup 0)
9606 (abs:SF (match_dup 1)))
9607 (clobber (reg:CC 17))])])
9608
9609 (define_split
9610 [(set (match_operand:SF 0 "register_operand" "")
9611 (abs:SF (match_operand:SF 1 "register_operand" "")))
9612 (use (match_operand:SF 2 "" ""))
9613 (clobber (reg:CC 17))]
9614 "reload_completed && !SSE_REG_P (operands[0])"
9615 [(parallel [(set (match_dup 0)
9616 (abs:SF (match_dup 1)))
9617 (clobber (reg:CC 17))])])
9618
9619 (define_split
9620 [(set (match_operand:SF 0 "register_operand" "")
9621 (abs:SF (match_operand:SF 1 "register_operand" "")))
9622 (use (match_operand:SF 2 "register_operand" ""))
9623 (clobber (reg:CC 17))]
9624 "reload_completed && SSE_REG_P (operands[0])"
9625 [(set (subreg:TI (match_dup 0) 0)
9626 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9627 (subreg:TI (match_dup 1) 0)))])
9628
9629 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9630 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9631 ;; to itself.
9632 (define_insn "*abssf2_if"
9633 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9634 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9635 (clobber (reg:CC 17))]
9636 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9637 "#")
9638
9639 (define_split
9640 [(set (match_operand:SF 0 "register_operand" "")
9641 (abs:SF (match_operand:SF 1 "register_operand" "")))
9642 (clobber (reg:CC 17))]
9643 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
9644 [(set (match_dup 0)
9645 (abs:SF (match_dup 1)))]
9646 "")
9647
9648 (define_split
9649 [(set (match_operand:SF 0 "register_operand" "")
9650 (abs:SF (match_operand:SF 1 "register_operand" "")))
9651 (clobber (reg:CC 17))]
9652 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9653 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9654 (clobber (reg:CC 17))])]
9655 "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
9656 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
9657
9658 (define_split
9659 [(set (match_operand 0 "memory_operand" "")
9660 (abs (match_operand 1 "memory_operand" "")))
9661 (clobber (reg:CC 17))]
9662 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9663 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9664 (clobber (reg:CC 17))])]
9665 "
9666 {
9667 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9668
9669 /* XFmode's size is 12, but only 10 bytes are used. */
9670 if (size == 12)
9671 size = 10;
9672 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
9673 operands[0] = adj_offsettable_operand (operands[0], size - 1);
9674 operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
9675 }")
9676
9677 (define_expand "absdf2"
9678 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9679 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9680 (clobber (reg:CC 17))])]
9681 "TARGET_80387"
9682 "if (TARGET_SSE2)
9683 {
9684 /* In case operand is in memory, we will not use SSE. */
9685 if (memory_operand (operands[0], VOIDmode)
9686 && rtx_equal_p (operands[0], operands[1]))
9687 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9688 else
9689 {
9690 /* Using SSE is tricky, since we need bitwise negation of -0
9691 in register. */
9692 rtx reg = gen_reg_rtx (DFmode);
9693 #if HOST_BITS_PER_WIDE_INT >= 64
9694 rtx imm = GEN_INT (0x80000000);
9695 #else
9696 rtx imm = immed_double_const (0, 0x80000000, DImode);
9697 #endif
9698 emit_move_insn (reg, gen_lowpart (DFmode, imm));
9699 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9700 }
9701 DONE;
9702 }
9703 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9704
9705 (define_insn "absdf2_memory"
9706 [(set (match_operand:DF 0 "memory_operand" "=m")
9707 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9708 (clobber (reg:CC 17))]
9709 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9710 "#")
9711
9712 (define_insn "absdf2_ifs"
9713 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,f#Yr,r#Yf")
9714 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
9715 (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*X#Y,*X#Y"))
9716 (clobber (reg:CC 17))]
9717 "TARGET_SSE2"
9718 "#")
9719
9720 (define_split
9721 [(set (match_operand:DF 0 "memory_operand" "")
9722 (abs:DF (match_operand:DF 1 "memory_operand" "")))
9723 (use (match_operand:DF 2 "" ""))
9724 (clobber (reg:CC 17))]
9725 ""
9726 [(parallel [(set (match_dup 0)
9727 (abs:DF (match_dup 1)))
9728 (clobber (reg:CC 17))])])
9729
9730 (define_split
9731 [(set (match_operand:DF 0 "register_operand" "")
9732 (abs:DF (match_operand:DF 1 "register_operand" "")))
9733 (use (match_operand:DF 2 "" ""))
9734 (clobber (reg:CC 17))]
9735 "reload_completed && !SSE_REG_P (operands[0])"
9736 [(parallel [(set (match_dup 0)
9737 (abs:DF (match_dup 1)))
9738 (clobber (reg:CC 17))])])
9739
9740 (define_split
9741 [(set (match_operand:DF 0 "register_operand" "")
9742 (abs:DF (match_operand:DF 1 "register_operand" "")))
9743 (use (match_operand:DF 2 "register_operand" ""))
9744 (clobber (reg:CC 17))]
9745 "reload_completed && SSE_REG_P (operands[0])"
9746 [(set (subreg:TI (match_dup 0) 0)
9747 (and:TI (not:TI (subreg:TI (match_dup 2) 0))
9748 (subreg:TI (match_dup 1) 0)))])
9749
9750
9751 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9752 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9753 ;; to itself.
9754 (define_insn "*absdf2_if"
9755 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9756 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9757 (clobber (reg:CC 17))]
9758 "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
9759 "#")
9760
9761 (define_split
9762 [(set (match_operand:DF 0 "register_operand" "")
9763 (abs:DF (match_operand:DF 1 "register_operand" "")))
9764 (clobber (reg:CC 17))]
9765 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9766 [(set (match_dup 0)
9767 (abs:DF (match_dup 1)))]
9768 "")
9769
9770 (define_split
9771 [(set (match_operand:DF 0 "register_operand" "")
9772 (abs:DF (match_operand:DF 1 "register_operand" "")))
9773 (clobber (reg:CC 17))]
9774 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9775 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
9776 (clobber (reg:CC 17))])]
9777 "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
9778 split_di (operands+0, 1, operands+2, operands+3);")
9779
9780 (define_expand "absxf2"
9781 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9782 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9783 (clobber (reg:CC 17))])]
9784 "TARGET_80387 && !TARGET_64BIT"
9785 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
9786
9787 (define_expand "abstf2"
9788 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
9789 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
9790 (clobber (reg:CC 17))])]
9791 "TARGET_80387"
9792 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
9793
9794 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9795 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9796 ;; to itself.
9797 (define_insn "*absxf2_if"
9798 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9799 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9800 (clobber (reg:CC 17))]
9801 "TARGET_80387 && !TARGET_64BIT
9802 && ix86_unary_operator_ok (ABS, XFmode, operands)"
9803 "#")
9804
9805 (define_split
9806 [(set (match_operand:XF 0 "register_operand" "")
9807 (abs:XF (match_operand:XF 1 "register_operand" "")))
9808 (clobber (reg:CC 17))]
9809 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9810 [(set (match_dup 0)
9811 (abs:XF (match_dup 1)))]
9812 "")
9813
9814 (define_split
9815 [(set (match_operand:XF 0 "register_operand" "")
9816 (abs:XF (match_operand:XF 1 "register_operand" "")))
9817 (clobber (reg:CC 17))]
9818 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9819 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9820 (clobber (reg:CC 17))])]
9821 "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
9822 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
9823
9824 (define_insn "*abstf2_if"
9825 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
9826 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
9827 (clobber (reg:CC 17))]
9828 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
9829 "#")
9830
9831 (define_split
9832 [(set (match_operand:TF 0 "register_operand" "")
9833 (abs:TF (match_operand:TF 1 "register_operand" "")))
9834 (clobber (reg:CC 17))]
9835 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
9836 [(set (match_dup 0)
9837 (abs:TF (match_dup 1)))]
9838 "")
9839
9840 (define_split
9841 [(set (match_operand:TF 0 "register_operand" "")
9842 (abs:TF (match_operand:TF 1 "register_operand" "")))
9843 (clobber (reg:CC 17))]
9844 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
9845 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9846 (clobber (reg:CC 17))])]
9847 "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
9848 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
9849
9850 (define_insn "*abssf2_1"
9851 [(set (match_operand:SF 0 "register_operand" "=f")
9852 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9853 "TARGET_80387 && reload_completed"
9854 "fabs"
9855 [(set_attr "type" "fsgn")
9856 (set_attr "mode" "SF")])
9857
9858 (define_insn "*absdf2_1"
9859 [(set (match_operand:DF 0 "register_operand" "=f")
9860 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9861 "TARGET_80387 && reload_completed"
9862 "fabs"
9863 [(set_attr "type" "fsgn")
9864 (set_attr "mode" "DF")])
9865
9866 (define_insn "*absextendsfdf2"
9867 [(set (match_operand:DF 0 "register_operand" "=f")
9868 (abs:DF (float_extend:DF
9869 (match_operand:SF 1 "register_operand" "0"))))]
9870 "TARGET_80387"
9871 "fabs"
9872 [(set_attr "type" "fsgn")
9873 (set_attr "mode" "DF")])
9874
9875 (define_insn "*absxf2_1"
9876 [(set (match_operand:XF 0 "register_operand" "=f")
9877 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9878 "TARGET_80387 && !TARGET_64BIT && reload_completed"
9879 "fabs"
9880 [(set_attr "type" "fsgn")
9881 (set_attr "mode" "DF")])
9882
9883 (define_insn "*absextenddfxf2"
9884 [(set (match_operand:XF 0 "register_operand" "=f")
9885 (abs:XF (float_extend:XF
9886 (match_operand:DF 1 "register_operand" "0"))))]
9887 "TARGET_80387 && !TARGET_64BIT"
9888 "fabs"
9889 [(set_attr "type" "fsgn")
9890 (set_attr "mode" "XF")])
9891
9892 (define_insn "*absextendsfxf2"
9893 [(set (match_operand:XF 0 "register_operand" "=f")
9894 (abs:XF (float_extend:XF
9895 (match_operand:SF 1 "register_operand" "0"))))]
9896 "TARGET_80387 && !TARGET_64BIT"
9897 "fabs"
9898 [(set_attr "type" "fsgn")
9899 (set_attr "mode" "XF")])
9900
9901 (define_insn "*abstf2_1"
9902 [(set (match_operand:TF 0 "register_operand" "=f")
9903 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
9904 "TARGET_80387 && reload_completed"
9905 "fabs"
9906 [(set_attr "type" "fsgn")
9907 (set_attr "mode" "DF")])
9908
9909 (define_insn "*absextenddftf2"
9910 [(set (match_operand:TF 0 "register_operand" "=f")
9911 (abs:TF (float_extend:TF
9912 (match_operand:DF 1 "register_operand" "0"))))]
9913 "TARGET_80387"
9914 "fabs"
9915 [(set_attr "type" "fsgn")
9916 (set_attr "mode" "XF")])
9917
9918 (define_insn "*absextendsftf2"
9919 [(set (match_operand:TF 0 "register_operand" "=f")
9920 (abs:TF (float_extend:TF
9921 (match_operand:SF 1 "register_operand" "0"))))]
9922 "TARGET_80387"
9923 "fabs"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "XF")])
9926 \f
9927 ;; One complement instructions
9928
9929 (define_expand "one_cmpldi2"
9930 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9931 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9932 "TARGET_64BIT"
9933 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9934
9935 (define_insn "*one_cmpldi2_1_rex64"
9936 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9937 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9938 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9939 "not{q}\\t%0"
9940 [(set_attr "type" "negnot")
9941 (set_attr "mode" "DI")])
9942
9943 (define_insn "*one_cmpldi2_2_rex64"
9944 [(set (reg 17)
9945 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9946 (const_int 0)))
9947 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9948 (not:DI (match_dup 1)))]
9949 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9950 && ix86_unary_operator_ok (NOT, DImode, operands)"
9951 "#"
9952 [(set_attr "type" "alu1")
9953 (set_attr "mode" "DI")])
9954
9955 (define_split
9956 [(set (reg 17)
9957 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
9958 (const_int 0)))
9959 (set (match_operand:DI 0 "nonimmediate_operand" "")
9960 (not:DI (match_dup 1)))]
9961 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9962 [(parallel [(set (reg:CCNO 17)
9963 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
9964 (const_int 0)))
9965 (set (match_dup 0)
9966 (xor:DI (match_dup 1) (const_int -1)))])]
9967 "")
9968
9969 (define_expand "one_cmplsi2"
9970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9971 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9972 ""
9973 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9974
9975 (define_insn "*one_cmplsi2_1"
9976 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9977 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9978 "ix86_unary_operator_ok (NOT, SImode, operands)"
9979 "not{l}\\t%0"
9980 [(set_attr "type" "negnot")
9981 (set_attr "mode" "SI")])
9982
9983 ;; ??? Currently never generated - xor is used instead.
9984 (define_insn "*one_cmplsi2_1_zext"
9985 [(set (match_operand:DI 0 "register_operand" "=r")
9986 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9987 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9988 "not{l}\\t%k0"
9989 [(set_attr "type" "negnot")
9990 (set_attr "mode" "SI")])
9991
9992 (define_insn "*one_cmplsi2_2"
9993 [(set (reg 17)
9994 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9995 (const_int 0)))
9996 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9997 (not:SI (match_dup 1)))]
9998 "ix86_match_ccmode (insn, CCNOmode)
9999 && ix86_unary_operator_ok (NOT, SImode, operands)"
10000 "#"
10001 [(set_attr "type" "alu1")
10002 (set_attr "mode" "SI")])
10003
10004 (define_split
10005 [(set (reg 17)
10006 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10007 (const_int 0)))
10008 (set (match_operand:SI 0 "nonimmediate_operand" "")
10009 (not:SI (match_dup 1)))]
10010 "ix86_match_ccmode (insn, CCNOmode)"
10011 [(parallel [(set (reg:CCNO 17)
10012 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10013 (const_int 0)))
10014 (set (match_dup 0)
10015 (xor:SI (match_dup 1) (const_int -1)))])]
10016 "")
10017
10018 ;; ??? Currently never generated - xor is used instead.
10019 (define_insn "*one_cmplsi2_2_zext"
10020 [(set (reg 17)
10021 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10022 (const_int 0)))
10023 (set (match_operand:DI 0 "register_operand" "=r")
10024 (zero_extend:DI (not:SI (match_dup 1))))]
10025 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10026 && ix86_unary_operator_ok (NOT, SImode, operands)"
10027 "#"
10028 [(set_attr "type" "alu1")
10029 (set_attr "mode" "SI")])
10030
10031 (define_split
10032 [(set (reg 17)
10033 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10034 (const_int 0)))
10035 (set (match_operand:DI 0 "register_operand" "")
10036 (zero_extend:DI (not:SI (match_dup 1))))]
10037 "ix86_match_ccmode (insn, CCNOmode)"
10038 [(parallel [(set (reg:CCNO 17)
10039 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10040 (const_int 0)))
10041 (set (match_dup 0)
10042 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10043 "")
10044
10045 (define_expand "one_cmplhi2"
10046 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10047 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10048 "TARGET_HIMODE_MATH"
10049 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10050
10051 (define_insn "*one_cmplhi2_1"
10052 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10053 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10054 "ix86_unary_operator_ok (NOT, HImode, operands)"
10055 "not{w}\\t%0"
10056 [(set_attr "type" "negnot")
10057 (set_attr "mode" "HI")])
10058
10059 (define_insn "*one_cmplhi2_2"
10060 [(set (reg 17)
10061 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10062 (const_int 0)))
10063 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10064 (not:HI (match_dup 1)))]
10065 "ix86_match_ccmode (insn, CCNOmode)
10066 && ix86_unary_operator_ok (NEG, HImode, operands)"
10067 "#"
10068 [(set_attr "type" "alu1")
10069 (set_attr "mode" "HI")])
10070
10071 (define_split
10072 [(set (reg 17)
10073 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10074 (const_int 0)))
10075 (set (match_operand:HI 0 "nonimmediate_operand" "")
10076 (not:HI (match_dup 1)))]
10077 "ix86_match_ccmode (insn, CCNOmode)"
10078 [(parallel [(set (reg:CCNO 17)
10079 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10080 (const_int 0)))
10081 (set (match_dup 0)
10082 (xor:HI (match_dup 1) (const_int -1)))])]
10083 "")
10084
10085 ;; %%% Potential partial reg stall on alternative 1. What to do?
10086 (define_expand "one_cmplqi2"
10087 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10088 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10089 "TARGET_QIMODE_MATH"
10090 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10091
10092 (define_insn "*one_cmplqi2_1"
10093 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10094 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10095 "ix86_unary_operator_ok (NOT, QImode, operands)"
10096 "@
10097 not{b}\\t%0
10098 not{l}\\t%k0"
10099 [(set_attr "type" "negnot")
10100 (set_attr "mode" "QI,SI")])
10101
10102 (define_insn "*one_cmplqi2_2"
10103 [(set (reg 17)
10104 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10105 (const_int 0)))
10106 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10107 (not:QI (match_dup 1)))]
10108 "ix86_match_ccmode (insn, CCNOmode)
10109 && ix86_unary_operator_ok (NOT, QImode, operands)"
10110 "#"
10111 [(set_attr "type" "alu1")
10112 (set_attr "mode" "QI")])
10113
10114 (define_split
10115 [(set (reg 17)
10116 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10117 (const_int 0)))
10118 (set (match_operand:QI 0 "nonimmediate_operand" "")
10119 (not:QI (match_dup 1)))]
10120 "ix86_match_ccmode (insn, CCNOmode)"
10121 [(parallel [(set (reg:CCNO 17)
10122 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10123 (const_int 0)))
10124 (set (match_dup 0)
10125 (xor:QI (match_dup 1) (const_int -1)))])]
10126 "")
10127 \f
10128 ;; Arithmetic shift instructions
10129
10130 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10131 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10132 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10133 ;; from the assembler input.
10134 ;;
10135 ;; This instruction shifts the target reg/mem as usual, but instead of
10136 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10137 ;; is a left shift double, bits are taken from the high order bits of
10138 ;; reg, else if the insn is a shift right double, bits are taken from the
10139 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10140 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10141 ;;
10142 ;; Since sh[lr]d does not change the `reg' operand, that is done
10143 ;; separately, making all shifts emit pairs of shift double and normal
10144 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10145 ;; support a 63 bit shift, each shift where the count is in a reg expands
10146 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10147 ;;
10148 ;; If the shift count is a constant, we need never emit more than one
10149 ;; shift pair, instead using moves and sign extension for counts greater
10150 ;; than 31.
10151
10152 (define_expand "ashldi3"
10153 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10154 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10155 (match_operand:QI 2 "nonmemory_operand" "")))
10156 (clobber (reg:CC 17))])]
10157 ""
10158 "
10159 {
10160 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10161 {
10162 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10163 DONE;
10164 }
10165 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10166 DONE;
10167 }")
10168
10169 (define_insn "*ashldi3_1_rex64"
10170 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10171 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10172 (match_operand:QI 2 "nonmemory_operand" "c,M")))
10173 (clobber (reg:CC 17))]
10174 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10175 "*
10176 {
10177 switch (get_attr_type (insn))
10178 {
10179 case TYPE_ALU:
10180 if (operands[2] != const1_rtx)
10181 abort ();
10182 if (!rtx_equal_p (operands[0], operands[1]))
10183 abort ();
10184 return \"add{q}\\t{%0, %0|%0, %0}\";
10185
10186 case TYPE_LEA:
10187 if (GET_CODE (operands[2]) != CONST_INT
10188 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10189 abort ();
10190 operands[1] = gen_rtx_MULT (DImode, operands[1],
10191 GEN_INT (1 << INTVAL (operands[2])));
10192 return \"lea{q}\\t{%a1, %0|%0, %a1}\";
10193
10194 default:
10195 if (REG_P (operands[2]))
10196 return \"sal{q}\\t{%b2, %0|%0, %b2}\";
10197 else if (GET_CODE (operands[2]) == CONST_INT
10198 && INTVAL (operands[2]) == 1
10199 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10200 return \"sal{q}\\t%0\";
10201 else
10202 return \"sal{q}\\t{%2, %0|%0, %2}\";
10203 }
10204 }"
10205 [(set (attr "type")
10206 (cond [(eq_attr "alternative" "1")
10207 (const_string "lea")
10208 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10209 (const_int 0))
10210 (match_operand 0 "register_operand" ""))
10211 (match_operand 2 "const1_operand" ""))
10212 (const_string "alu")
10213 ]
10214 (const_string "ishift")))
10215 (set_attr "mode" "DI")])
10216
10217 ;; Convert lea to the lea pattern to avoid flags dependency.
10218 (define_split
10219 [(set (match_operand:DI 0 "register_operand" "")
10220 (ashift:DI (match_operand:DI 1 "register_operand" "")
10221 (match_operand:QI 2 "immediate_operand" "")))
10222 (clobber (reg:CC 17))]
10223 "reload_completed
10224 && TARGET_64BIT
10225 && true_regnum (operands[0]) != true_regnum (operands[1])"
10226 [(set (match_dup 0)
10227 (mult:DI (match_dup 1)
10228 (match_dup 2)))]
10229 "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10230 DImode));")
10231
10232 ;; This pattern can't accept a variable shift count, since shifts by
10233 ;; zero don't affect the flags. We assume that shifts by constant
10234 ;; zero are optimized away.
10235 (define_insn "*ashldi3_cmp_rex64"
10236 [(set (reg 17)
10237 (compare
10238 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10239 (match_operand:QI 2 "immediate_operand" "e"))
10240 (const_int 0)))
10241 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10242 (ashift:DI (match_dup 1) (match_dup 2)))]
10243 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10244 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10245 "*
10246 {
10247 switch (get_attr_type (insn))
10248 {
10249 case TYPE_ALU:
10250 if (operands[2] != const1_rtx)
10251 abort ();
10252 return \"add{q}\\t{%0, %0|%0, %0}\";
10253
10254 default:
10255 if (REG_P (operands[2]))
10256 return \"sal{q}\\t{%b2, %0|%0, %b2}\";
10257 else if (GET_CODE (operands[2]) == CONST_INT
10258 && INTVAL (operands[2]) == 1
10259 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10260 return \"sal{q}\\t%0\";
10261 else
10262 return \"sal{q}\\t{%2, %0|%0, %2}\";
10263 }
10264 }"
10265 [(set (attr "type")
10266 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10267 (const_int 0))
10268 (match_operand 0 "register_operand" ""))
10269 (match_operand 2 "const1_operand" ""))
10270 (const_string "alu")
10271 ]
10272 (const_string "ishift")))
10273 (set_attr "mode" "DI")])
10274
10275 (define_insn "ashldi3_1"
10276 [(set (match_operand:DI 0 "register_operand" "=r")
10277 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10278 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10279 (clobber (match_scratch:SI 3 "=&r"))
10280 (clobber (reg:CC 17))]
10281 "!TARGET_64BIT && TARGET_CMOVE"
10282 "#"
10283 [(set_attr "type" "multi")])
10284
10285 (define_insn "*ashldi3_2"
10286 [(set (match_operand:DI 0 "register_operand" "=r")
10287 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10288 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10289 (clobber (reg:CC 17))]
10290 "!TARGET_64BIT"
10291 "#"
10292 [(set_attr "type" "multi")])
10293
10294 (define_split
10295 [(set (match_operand:DI 0 "register_operand" "")
10296 (ashift:DI (match_operand:DI 1 "register_operand" "")
10297 (match_operand:QI 2 "nonmemory_operand" "")))
10298 (clobber (match_scratch:SI 3 ""))
10299 (clobber (reg:CC 17))]
10300 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10301 [(const_int 0)]
10302 "ix86_split_ashldi (operands, operands[3]); DONE;")
10303
10304 (define_split
10305 [(set (match_operand:DI 0 "register_operand" "")
10306 (ashift:DI (match_operand:DI 1 "register_operand" "")
10307 (match_operand:QI 2 "nonmemory_operand" "")))
10308 (clobber (reg:CC 17))]
10309 "!TARGET_64BIT && reload_completed"
10310 [(const_int 0)]
10311 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10312
10313 (define_insn "x86_shld_1"
10314 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10315 (ior:SI (ashift:SI (match_dup 0)
10316 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10317 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10318 (minus:QI (const_int 32) (match_dup 2)))))
10319 (clobber (reg:CC 17))]
10320 ""
10321 "@
10322 shld{l}\\t{%2, %1, %0|%0, %1, %2}
10323 shld{l}\\t{%s2%1, %0|%0, %1, %2}"
10324 [(set_attr "type" "ishift")
10325 (set_attr "prefix_0f" "1")
10326 (set_attr "mode" "SI")
10327 (set_attr "pent_pair" "np")
10328 (set_attr "athlon_decode" "vector")
10329 (set_attr "ppro_uops" "few")])
10330
10331 (define_expand "x86_shift_adj_1"
10332 [(set (reg:CCZ 17)
10333 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10334 (const_int 32))
10335 (const_int 0)))
10336 (set (match_operand:SI 0 "register_operand" "")
10337 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10338 (match_operand:SI 1 "register_operand" "")
10339 (match_dup 0)))
10340 (set (match_dup 1)
10341 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10342 (match_operand:SI 3 "register_operand" "r")
10343 (match_dup 1)))]
10344 "TARGET_CMOVE"
10345 "")
10346
10347 (define_expand "x86_shift_adj_2"
10348 [(use (match_operand:SI 0 "register_operand" ""))
10349 (use (match_operand:SI 1 "register_operand" ""))
10350 (use (match_operand:QI 2 "register_operand" ""))]
10351 ""
10352 "
10353 {
10354 rtx label = gen_label_rtx ();
10355 rtx tmp;
10356
10357 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10358
10359 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10360 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10361 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10362 gen_rtx_LABEL_REF (VOIDmode, label),
10363 pc_rtx);
10364 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10365 JUMP_LABEL (tmp) = label;
10366
10367 emit_move_insn (operands[0], operands[1]);
10368 emit_move_insn (operands[1], const0_rtx);
10369
10370 emit_label (label);
10371 LABEL_NUSES (label) = 1;
10372
10373 DONE;
10374 }")
10375
10376 (define_expand "ashlsi3"
10377 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10378 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10379 (match_operand:QI 2 "nonmemory_operand" "")))
10380 (clobber (reg:CC 17))]
10381 ""
10382 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10383
10384 (define_insn "*ashlsi3_1"
10385 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10386 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10387 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10388 (clobber (reg:CC 17))]
10389 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10390 "*
10391 {
10392 switch (get_attr_type (insn))
10393 {
10394 case TYPE_ALU:
10395 if (operands[2] != const1_rtx)
10396 abort ();
10397 if (!rtx_equal_p (operands[0], operands[1]))
10398 abort ();
10399 return \"add{l}\\t{%0, %0|%0, %0}\";
10400
10401 case TYPE_LEA:
10402 return \"#\";
10403
10404 default:
10405 if (REG_P (operands[2]))
10406 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
10407 else if (GET_CODE (operands[2]) == CONST_INT
10408 && INTVAL (operands[2]) == 1
10409 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10410 return \"sal{l}\\t%0\";
10411 else
10412 return \"sal{l}\\t{%2, %0|%0, %2}\";
10413 }
10414 }"
10415 [(set (attr "type")
10416 (cond [(eq_attr "alternative" "1")
10417 (const_string "lea")
10418 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10419 (const_int 0))
10420 (match_operand 0 "register_operand" ""))
10421 (match_operand 2 "const1_operand" ""))
10422 (const_string "alu")
10423 ]
10424 (const_string "ishift")))
10425 (set_attr "mode" "SI")])
10426
10427 ;; Convert lea to the lea pattern to avoid flags dependency.
10428 (define_split
10429 [(set (match_operand 0 "register_operand" "")
10430 (ashift (match_operand 1 "register_operand" "")
10431 (match_operand:QI 2 "const_int_operand" "")))
10432 (clobber (reg:CC 17))]
10433 "reload_completed
10434 && true_regnum (operands[0]) != true_regnum (operands[1])"
10435 [(const_int 0)]
10436 "
10437 {
10438 rtx pat;
10439 operands[0] = gen_lowpart (SImode, operands[0]);
10440 operands[1] = gen_lowpart (Pmode, operands[1]);
10441 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10442 Pmode));
10443 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10444 if (Pmode != SImode)
10445 pat = gen_rtx_SUBREG (SImode, pat, 0);
10446 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10447 DONE;
10448 }")
10449
10450 (define_insn "*ashlsi3_1_zext"
10451 [(set (match_operand:DI 0 "register_operand" "=r,r")
10452 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10453 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10454 (clobber (reg:CC 17))]
10455 "ix86_binary_operator_ok (ASHIFT, SImode, operands) && TARGET_64BIT"
10456 "*
10457 {
10458 switch (get_attr_type (insn))
10459 {
10460 case TYPE_ALU:
10461 if (operands[2] != const1_rtx)
10462 abort ();
10463 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
10464
10465 case TYPE_LEA:
10466 return \"#\";
10467
10468 default:
10469 if (REG_P (operands[2]))
10470 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
10471 else if (GET_CODE (operands[2]) == CONST_INT
10472 && INTVAL (operands[2]) == 1
10473 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10474 return \"sal{l}\\t%k0\";
10475 else
10476 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
10477 }
10478 }"
10479 [(set (attr "type")
10480 (cond [(eq_attr "alternative" "1")
10481 (const_string "lea")
10482 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10483 (const_int 0))
10484 (match_operand 2 "const1_operand" ""))
10485 (const_string "alu")
10486 ]
10487 (const_string "ishift")))
10488 (set_attr "mode" "SI")])
10489
10490 ;; Convert lea to the lea pattern to avoid flags dependency.
10491 (define_split
10492 [(set (match_operand:DI 0 "register_operand" "")
10493 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10494 (match_operand:QI 2 "const_int_operand" ""))))
10495 (clobber (reg:CC 17))]
10496 "reload_completed
10497 && true_regnum (operands[0]) != true_regnum (operands[1])"
10498 [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10499 "
10500 {
10501 operands[1] = gen_lowpart (Pmode, operands[1]);
10502 operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
10503 Pmode));
10504 }")
10505
10506 ;; This pattern can't accept a variable shift count, since shifts by
10507 ;; zero don't affect the flags. We assume that shifts by constant
10508 ;; zero are optimized away.
10509 (define_insn "*ashlsi3_cmp"
10510 [(set (reg 17)
10511 (compare
10512 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10513 (match_operand:QI 2 "immediate_operand" "I"))
10514 (const_int 0)))
10515 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10516 (ashift:SI (match_dup 1) (match_dup 2)))]
10517 "ix86_match_ccmode (insn, CCGOCmode)
10518 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10519 "*
10520 {
10521 switch (get_attr_type (insn))
10522 {
10523 case TYPE_ALU:
10524 if (operands[2] != const1_rtx)
10525 abort ();
10526 return \"add{l}\\t{%0, %0|%0, %0}\";
10527
10528 default:
10529 if (REG_P (operands[2]))
10530 return \"sal{l}\\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{l}\\t%0\";
10535 else
10536 return \"sal{l}\\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" "SI")])
10548
10549 (define_insn "*ashlsi3_cmp_zext"
10550 [(set (reg 17)
10551 (compare
10552 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10553 (match_operand:QI 2 "immediate_operand" "I"))
10554 (const_int 0)))
10555 (set (match_operand:DI 0 "register_operand" "=r")
10556 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10557 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10558 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10559 "*
10560 {
10561 switch (get_attr_type (insn))
10562 {
10563 case TYPE_ALU:
10564 if (operands[2] != const1_rtx)
10565 abort ();
10566 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
10567
10568 default:
10569 if (REG_P (operands[2]))
10570 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
10571 else if (GET_CODE (operands[2]) == CONST_INT
10572 && INTVAL (operands[2]) == 1
10573 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10574 return \"sal{l}\\t%k0\";
10575 else
10576 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
10577 }
10578 }"
10579 [(set (attr "type")
10580 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10581 (const_int 0))
10582 (match_operand 2 "const1_operand" ""))
10583 (const_string "alu")
10584 ]
10585 (const_string "ishift")))
10586 (set_attr "mode" "SI")])
10587
10588 (define_expand "ashlhi3"
10589 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10590 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10591 (match_operand:QI 2 "nonmemory_operand" "")))
10592 (clobber (reg:CC 17))]
10593 "TARGET_HIMODE_MATH"
10594 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10595
10596 (define_insn "*ashlhi3_1_lea"
10597 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10598 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10599 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10600 (clobber (reg:CC 17))]
10601 "!TARGET_PARTIAL_REG_STALL
10602 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10603 "*
10604 {
10605 switch (get_attr_type (insn))
10606 {
10607 case TYPE_LEA:
10608 return \"#\";
10609 case TYPE_ALU:
10610 if (operands[2] != const1_rtx)
10611 abort ();
10612 return \"add{w}\\t{%0, %0|%0, %0}\";
10613
10614 default:
10615 if (REG_P (operands[2]))
10616 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
10617 else if (GET_CODE (operands[2]) == CONST_INT
10618 && INTVAL (operands[2]) == 1
10619 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10620 return \"sal{w}\\t%0\";
10621 else
10622 return \"sal{w}\\t{%2, %0|%0, %2}\";
10623 }
10624 }"
10625 [(set (attr "type")
10626 (cond [(eq_attr "alternative" "1")
10627 (const_string "lea")
10628 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10629 (const_int 0))
10630 (match_operand 0 "register_operand" ""))
10631 (match_operand 2 "const1_operand" ""))
10632 (const_string "alu")
10633 ]
10634 (const_string "ishift")))
10635 (set_attr "mode" "HI,SI")])
10636
10637 (define_insn "*ashlhi3_1"
10638 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10639 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10640 (match_operand:QI 2 "nonmemory_operand" "cI")))
10641 (clobber (reg:CC 17))]
10642 "TARGET_PARTIAL_REG_STALL
10643 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10644 "*
10645 {
10646 switch (get_attr_type (insn))
10647 {
10648 case TYPE_ALU:
10649 if (operands[2] != const1_rtx)
10650 abort ();
10651 return \"add{w}\\t{%0, %0|%0, %0}\";
10652
10653 default:
10654 if (REG_P (operands[2]))
10655 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
10656 else if (GET_CODE (operands[2]) == CONST_INT
10657 && INTVAL (operands[2]) == 1
10658 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10659 return \"sal{w}\\t%0\";
10660 else
10661 return \"sal{w}\\t{%2, %0|%0, %2}\";
10662 }
10663 }"
10664 [(set (attr "type")
10665 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10666 (const_int 0))
10667 (match_operand 0 "register_operand" ""))
10668 (match_operand 2 "const1_operand" ""))
10669 (const_string "alu")
10670 ]
10671 (const_string "ishift")))
10672 (set_attr "mode" "HI")])
10673
10674 ;; This pattern can't accept a variable shift count, since shifts by
10675 ;; zero don't affect the flags. We assume that shifts by constant
10676 ;; zero are optimized away.
10677 (define_insn "*ashlhi3_cmp"
10678 [(set (reg 17)
10679 (compare
10680 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10681 (match_operand:QI 2 "immediate_operand" "I"))
10682 (const_int 0)))
10683 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10684 (ashift:HI (match_dup 1) (match_dup 2)))]
10685 "ix86_match_ccmode (insn, CCGOCmode)
10686 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10687 "*
10688 {
10689 switch (get_attr_type (insn))
10690 {
10691 case TYPE_ALU:
10692 if (operands[2] != const1_rtx)
10693 abort ();
10694 return \"add{w}\\t{%0, %0|%0, %0}\";
10695
10696 default:
10697 if (REG_P (operands[2]))
10698 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
10699 else if (GET_CODE (operands[2]) == CONST_INT
10700 && INTVAL (operands[2]) == 1
10701 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10702 return \"sal{w}\\t%0\";
10703 else
10704 return \"sal{w}\\t{%2, %0|%0, %2}\";
10705 }
10706 }"
10707 [(set (attr "type")
10708 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709 (const_int 0))
10710 (match_operand 0 "register_operand" ""))
10711 (match_operand 2 "const1_operand" ""))
10712 (const_string "alu")
10713 ]
10714 (const_string "ishift")))
10715 (set_attr "mode" "HI")])
10716
10717 (define_expand "ashlqi3"
10718 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10719 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10720 (match_operand:QI 2 "nonmemory_operand" "")))
10721 (clobber (reg:CC 17))]
10722 "TARGET_QIMODE_MATH"
10723 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10724
10725 ;; %%% Potential partial reg stall on alternative 2. What to do?
10726
10727 (define_insn "*ashlqi3_1_lea"
10728 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10729 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
10730 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10731 (clobber (reg:CC 17))]
10732 "!TARGET_PARTIAL_REG_STALL
10733 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10734 "*
10735 {
10736 switch (get_attr_type (insn))
10737 {
10738 case TYPE_LEA:
10739 return \"#\";
10740 case TYPE_ALU:
10741 if (operands[2] != const1_rtx)
10742 abort ();
10743 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10744 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
10745 else
10746 return \"add{b}\\t{%0, %0|%0, %0}\";
10747
10748 default:
10749 if (REG_P (operands[2]))
10750 {
10751 if (get_attr_mode (insn) == MODE_SI)
10752 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
10753 else
10754 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
10755 }
10756 else if (GET_CODE (operands[2]) == CONST_INT
10757 && INTVAL (operands[2]) == 1
10758 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10759 {
10760 if (get_attr_mode (insn) == MODE_SI)
10761 return \"sal{l}\\t%0\";
10762 else
10763 return \"sal{b}\\t%0\";
10764 }
10765 else
10766 {
10767 if (get_attr_mode (insn) == MODE_SI)
10768 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
10769 else
10770 return \"sal{b}\\t{%2, %0|%0, %2}\";
10771 }
10772 }
10773 }"
10774 [(set (attr "type")
10775 (cond [(eq_attr "alternative" "2")
10776 (const_string "lea")
10777 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10778 (const_int 0))
10779 (match_operand 0 "register_operand" ""))
10780 (match_operand 2 "const1_operand" ""))
10781 (const_string "alu")
10782 ]
10783 (const_string "ishift")))
10784 (set_attr "mode" "QI,SI,SI")])
10785
10786 (define_insn "*ashlqi3_1"
10787 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10788 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10789 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10790 (clobber (reg:CC 17))]
10791 "TARGET_PARTIAL_REG_STALL
10792 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10793 "*
10794 {
10795 switch (get_attr_type (insn))
10796 {
10797 case TYPE_ALU:
10798 if (operands[2] != const1_rtx)
10799 abort ();
10800 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10801 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
10802 else
10803 return \"add{b}\\t{%0, %0|%0, %0}\";
10804
10805 default:
10806 if (REG_P (operands[2]))
10807 {
10808 if (get_attr_mode (insn) == MODE_SI)
10809 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
10810 else
10811 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
10812 }
10813 else if (GET_CODE (operands[2]) == CONST_INT
10814 && INTVAL (operands[2]) == 1
10815 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10816 {
10817 if (get_attr_mode (insn) == MODE_SI)
10818 return \"sal{l}\\t%0\";
10819 else
10820 return \"sal{b}\\t%0\";
10821 }
10822 else
10823 {
10824 if (get_attr_mode (insn) == MODE_SI)
10825 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
10826 else
10827 return \"sal{b}\\t{%2, %0|%0, %2}\";
10828 }
10829 }
10830 }"
10831 [(set (attr "type")
10832 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10833 (const_int 0))
10834 (match_operand 0 "register_operand" ""))
10835 (match_operand 2 "const1_operand" ""))
10836 (const_string "alu")
10837 ]
10838 (const_string "ishift")))
10839 (set_attr "mode" "QI,SI")])
10840
10841 ;; This pattern can't accept a variable shift count, since shifts by
10842 ;; zero don't affect the flags. We assume that shifts by constant
10843 ;; zero are optimized away.
10844 (define_insn "*ashlqi3_cmp"
10845 [(set (reg 17)
10846 (compare
10847 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10848 (match_operand:QI 2 "immediate_operand" "I"))
10849 (const_int 0)))
10850 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10851 (ashift:QI (match_dup 1) (match_dup 2)))]
10852 "ix86_match_ccmode (insn, CCGOCmode)
10853 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10854 "*
10855 {
10856 switch (get_attr_type (insn))
10857 {
10858 case TYPE_ALU:
10859 if (operands[2] != const1_rtx)
10860 abort ();
10861 return \"add{b}\\t{%0, %0|%0, %0}\";
10862
10863 default:
10864 if (REG_P (operands[2]))
10865 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
10866 else if (GET_CODE (operands[2]) == CONST_INT
10867 && INTVAL (operands[2]) == 1
10868 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
10869 return \"sal{b}\\t%0\";
10870 else
10871 return \"sal{b}\\t{%2, %0|%0, %2}\";
10872 }
10873 }"
10874 [(set (attr "type")
10875 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10876 (const_int 0))
10877 (match_operand 0 "register_operand" ""))
10878 (match_operand 2 "const1_operand" ""))
10879 (const_string "alu")
10880 ]
10881 (const_string "ishift")))
10882 (set_attr "mode" "QI")])
10883
10884 ;; See comment above `ashldi3' about how this works.
10885
10886 (define_expand "ashrdi3"
10887 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10888 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10889 (match_operand:QI 2 "nonmemory_operand" "")))
10890 (clobber (reg:CC 17))])]
10891 ""
10892 "
10893 {
10894 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10895 {
10896 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
10897 DONE;
10898 }
10899 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
10900 DONE;
10901 }")
10902
10903 (define_insn "ashrdi3_63_rex64"
10904 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10905 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10906 (match_operand:DI 2 "const_int_operand" "i,i")))
10907 (clobber (reg:CC 17))]
10908 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
10909 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10910 "@
10911 {cqto|cqo}
10912 sar{q}\\t{%2, %0|%0, %2}"
10913 [(set_attr "type" "imovx,ishift")
10914 (set_attr "prefix_0f" "0,*")
10915 (set_attr "length_immediate" "0,*")
10916 (set_attr "modrm" "0,1")
10917 (set_attr "mode" "DI")])
10918
10919 (define_insn "*ashrdi3_1_one_bit_rex64"
10920 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10921 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10922 (match_operand:QI 2 "const_int_1_operand" "")))
10923 (clobber (reg:CC 17))]
10924 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10925 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
10926 "sar{q}\\t%0"
10927 [(set_attr "type" "ishift")
10928 (set (attr "length")
10929 (if_then_else (match_operand:DI 0 "register_operand" "")
10930 (const_string "2")
10931 (const_string "*")))])
10932
10933 (define_insn "*ashrdi3_1_rex64"
10934 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10935 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10936 (match_operand:QI 2 "nonmemory_operand" "n,c")))
10937 (clobber (reg:CC 17))]
10938 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10939 "@
10940 sar{q}\\t{%2, %0|%0, %2}
10941 sar{q}\\t{%b2, %0|%0, %b2}"
10942 [(set_attr "type" "ishift")
10943 (set_attr "mode" "DI")])
10944
10945 ;; This pattern can't accept a variable shift count, since shifts by
10946 ;; zero don't affect the flags. We assume that shifts by constant
10947 ;; zero are optimized away.
10948 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10949 [(set (reg 17)
10950 (compare
10951 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10952 (match_operand:QI 2 "const_int_1_operand" ""))
10953 (const_int 0)))
10954 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10955 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10956 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10957 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
10958 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10959 "sar{q}\\t%0"
10960 [(set_attr "type" "ishift")
10961 (set (attr "length")
10962 (if_then_else (match_operand:DI 0 "register_operand" "")
10963 (const_string "2")
10964 (const_string "*")))])
10965
10966 ;; This pattern can't accept a variable shift count, since shifts by
10967 ;; zero don't affect the flags. We assume that shifts by constant
10968 ;; zero are optimized away.
10969 (define_insn "*ashrdi3_cmp_rex64"
10970 [(set (reg 17)
10971 (compare
10972 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10973 (match_operand:QI 2 "const_int_operand" "n"))
10974 (const_int 0)))
10975 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10976 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10977 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10978 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10979 "sar{q}\\t{%2, %0|%0, %2}"
10980 [(set_attr "type" "ishift")
10981 (set_attr "mode" "DI")])
10982
10983
10984 (define_insn "ashrdi3_1"
10985 [(set (match_operand:DI 0 "register_operand" "=r")
10986 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10987 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10988 (clobber (match_scratch:SI 3 "=&r"))
10989 (clobber (reg:CC 17))]
10990 "!TARGET_64BIT && TARGET_CMOVE"
10991 "#"
10992 [(set_attr "type" "multi")])
10993
10994 (define_insn "*ashrdi3_2"
10995 [(set (match_operand:DI 0 "register_operand" "=r")
10996 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10997 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10998 (clobber (reg:CC 17))]
10999 "!TARGET_64BIT"
11000 "#"
11001 [(set_attr "type" "multi")])
11002
11003 (define_split
11004 [(set (match_operand:DI 0 "register_operand" "")
11005 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11006 (match_operand:QI 2 "nonmemory_operand" "")))
11007 (clobber (match_scratch:SI 3 ""))
11008 (clobber (reg:CC 17))]
11009 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11010 [(const_int 0)]
11011 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11012
11013 (define_split
11014 [(set (match_operand:DI 0 "register_operand" "")
11015 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11016 (match_operand:QI 2 "nonmemory_operand" "")))
11017 (clobber (reg:CC 17))]
11018 "!TARGET_64BIT && reload_completed"
11019 [(const_int 0)]
11020 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11021
11022 (define_insn "x86_shrd_1"
11023 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11024 (ior:SI (ashiftrt:SI (match_dup 0)
11025 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11026 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11027 (minus:QI (const_int 32) (match_dup 2)))))
11028 (clobber (reg:CC 17))]
11029 ""
11030 "@
11031 shrd{l}\\t{%2, %1, %0|%0, %1, %2}
11032 shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
11033 [(set_attr "type" "ishift")
11034 (set_attr "prefix_0f" "1")
11035 (set_attr "pent_pair" "np")
11036 (set_attr "ppro_uops" "few")
11037 (set_attr "mode" "SI")])
11038
11039 (define_expand "x86_shift_adj_3"
11040 [(use (match_operand:SI 0 "register_operand" ""))
11041 (use (match_operand:SI 1 "register_operand" ""))
11042 (use (match_operand:QI 2 "register_operand" ""))]
11043 ""
11044 "
11045 {
11046 rtx label = gen_label_rtx ();
11047 rtx tmp;
11048
11049 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11050
11051 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11052 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11053 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11054 gen_rtx_LABEL_REF (VOIDmode, label),
11055 pc_rtx);
11056 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11057 JUMP_LABEL (tmp) = label;
11058
11059 emit_move_insn (operands[0], operands[1]);
11060 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11061
11062 emit_label (label);
11063 LABEL_NUSES (label) = 1;
11064
11065 DONE;
11066 }")
11067
11068 (define_insn "ashrsi3_31"
11069 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11070 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11071 (match_operand:SI 2 "const_int_operand" "i,i")))
11072 (clobber (reg:CC 17))]
11073 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11074 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11075 "@
11076 {cltd|cdq}
11077 sar{l}\\t{%2, %0|%0, %2}"
11078 [(set_attr "type" "imovx,ishift")
11079 (set_attr "prefix_0f" "0,*")
11080 (set_attr "length_immediate" "0,*")
11081 (set_attr "modrm" "0,1")
11082 (set_attr "mode" "SI")])
11083
11084 (define_insn "*ashrsi3_31_zext"
11085 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11086 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11087 (match_operand:SI 2 "const_int_operand" "i,i"))))
11088 (clobber (reg:CC 17))]
11089 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11090 && TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11091 "@
11092 {cltd|cdq}
11093 sar{l}\\t{%2, %k0|%k0, %2}"
11094 [(set_attr "type" "imovx,ishift")
11095 (set_attr "prefix_0f" "0,*")
11096 (set_attr "length_immediate" "0,*")
11097 (set_attr "modrm" "0,1")
11098 (set_attr "mode" "SI")])
11099
11100 (define_expand "ashrsi3"
11101 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11102 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11103 (match_operand:QI 2 "nonmemory_operand" "")))
11104 (clobber (reg:CC 17))]
11105 ""
11106 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11107
11108 (define_insn "*ashrsi3_1_one_bit"
11109 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11110 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11111 (match_operand:QI 2 "const_int_1_operand" "")))
11112 (clobber (reg:CC 17))]
11113 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11114 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11115 "sar{l}\\t%0"
11116 [(set_attr "type" "ishift")
11117 (set (attr "length")
11118 (if_then_else (match_operand:SI 0 "register_operand" "")
11119 (const_string "2")
11120 (const_string "*")))])
11121
11122 (define_insn "*ashrsi3_1_one_bit_zext"
11123 [(set (match_operand:DI 0 "register_operand" "=r")
11124 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11125 (match_operand:QI 2 "const_int_1_operand" ""))))
11126 (clobber (reg:CC 17))]
11127 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11128 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11129 "sar{l}\\t%k0"
11130 [(set_attr "type" "ishift")
11131 (set_attr "length" "2")])
11132
11133 (define_insn "*ashrsi3_1"
11134 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11135 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11136 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11137 (clobber (reg:CC 17))]
11138 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11139 "@
11140 sar{l}\\t{%2, %0|%0, %2}
11141 sar{l}\\t{%b2, %0|%0, %b2}"
11142 [(set_attr "type" "ishift")
11143 (set_attr "mode" "SI")])
11144
11145 (define_insn "*ashrsi3_1_zext"
11146 [(set (match_operand:DI 0 "register_operand" "=r,r")
11147 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11148 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11149 (clobber (reg:CC 17))]
11150 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11151 "@
11152 sar{l}\\t{%2, %k0|%k0, %2}
11153 sar{l}\\t{%b2, %k0|%k0, %b2}"
11154 [(set_attr "type" "ishift")
11155 (set_attr "mode" "SI")])
11156
11157 ;; This pattern can't accept a variable shift count, since shifts by
11158 ;; zero don't affect the flags. We assume that shifts by constant
11159 ;; zero are optimized away.
11160 (define_insn "*ashrsi3_one_bit_cmp"
11161 [(set (reg 17)
11162 (compare
11163 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11164 (match_operand:QI 2 "const_int_1_operand" ""))
11165 (const_int 0)))
11166 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11167 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11168 "ix86_match_ccmode (insn, CCGOCmode)
11169 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11170 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11171 "sar{l}\\t%0"
11172 [(set_attr "type" "ishift")
11173 (set (attr "length")
11174 (if_then_else (match_operand:SI 0 "register_operand" "")
11175 (const_string "2")
11176 (const_string "*")))])
11177
11178 (define_insn "*ashrsi3_one_bit_cmp_zext"
11179 [(set (reg 17)
11180 (compare
11181 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11182 (match_operand:QI 2 "const_int_1_operand" ""))
11183 (const_int 0)))
11184 (set (match_operand:DI 0 "register_operand" "=r")
11185 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11186 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11187 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11188 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11189 "sar{l}\\t%k0"
11190 [(set_attr "type" "ishift")
11191 (set_attr "length" "2")])
11192
11193 ;; This pattern can't accept a variable shift count, since shifts by
11194 ;; zero don't affect the flags. We assume that shifts by constant
11195 ;; zero are optimized away.
11196 (define_insn "*ashrsi3_cmp"
11197 [(set (reg 17)
11198 (compare
11199 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11200 (match_operand:QI 2 "immediate_operand" "I"))
11201 (const_int 0)))
11202 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11203 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11204 "ix86_match_ccmode (insn, CCGOCmode)
11205 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11206 "sar{l}\\t{%2, %0|%0, %2}"
11207 [(set_attr "type" "ishift")
11208 (set_attr "mode" "SI")])
11209
11210 (define_insn "*ashrsi3_cmp_zext"
11211 [(set (reg 17)
11212 (compare
11213 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11214 (match_operand:QI 2 "immediate_operand" "I"))
11215 (const_int 0)))
11216 (set (match_operand:DI 0 "register_operand" "=r")
11217 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11218 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11219 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11220 "sar{l}\\t{%2, %k0|%k0, %2}"
11221 [(set_attr "type" "ishift")
11222 (set_attr "mode" "SI")])
11223
11224 (define_expand "ashrhi3"
11225 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11226 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11227 (match_operand:QI 2 "nonmemory_operand" "")))
11228 (clobber (reg:CC 17))]
11229 "TARGET_HIMODE_MATH"
11230 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11231
11232 (define_insn "*ashrhi3_1_one_bit"
11233 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11234 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11235 (match_operand:QI 2 "const_int_1_operand" "")))
11236 (clobber (reg:CC 17))]
11237 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11238 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11239 "sar{w}\\t%0"
11240 [(set_attr "type" "ishift")
11241 (set (attr "length")
11242 (if_then_else (match_operand 0 "register_operand" "")
11243 (const_string "2")
11244 (const_string "*")))])
11245
11246 (define_insn "*ashrhi3_1"
11247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11248 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11249 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11250 (clobber (reg:CC 17))]
11251 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11252 "@
11253 sar{w}\\t{%2, %0|%0, %2}
11254 sar{w}\\t{%b2, %0|%0, %b2}"
11255 [(set_attr "type" "ishift")
11256 (set_attr "mode" "HI")])
11257
11258 ;; This pattern can't accept a variable shift count, since shifts by
11259 ;; zero don't affect the flags. We assume that shifts by constant
11260 ;; zero are optimized away.
11261 (define_insn "*ashrhi3_one_bit_cmp"
11262 [(set (reg 17)
11263 (compare
11264 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11265 (match_operand:QI 2 "const_int_1_operand" ""))
11266 (const_int 0)))
11267 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11268 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11269 "ix86_match_ccmode (insn, CCGOCmode)
11270 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11271 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11272 "sar{w}\\t%0"
11273 [(set_attr "type" "ishift")
11274 (set (attr "length")
11275 (if_then_else (match_operand 0 "register_operand" "")
11276 (const_string "2")
11277 (const_string "*")))])
11278
11279 ;; This pattern can't accept a variable shift count, since shifts by
11280 ;; zero don't affect the flags. We assume that shifts by constant
11281 ;; zero are optimized away.
11282 (define_insn "*ashrhi3_cmp"
11283 [(set (reg 17)
11284 (compare
11285 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11286 (match_operand:QI 2 "immediate_operand" "I"))
11287 (const_int 0)))
11288 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11289 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11290 "ix86_match_ccmode (insn, CCGOCmode)
11291 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11292 "sar{w}\\t{%2, %0|%0, %2}"
11293 [(set_attr "type" "ishift")
11294 (set_attr "mode" "HI")])
11295
11296 (define_expand "ashrqi3"
11297 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11298 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11299 (match_operand:QI 2 "nonmemory_operand" "")))
11300 (clobber (reg:CC 17))]
11301 "TARGET_QIMODE_MATH"
11302 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11303
11304 (define_insn "*ashrqi3_1_one_bit"
11305 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11306 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11307 (match_operand:QI 2 "const_int_1_operand" "")))
11308 (clobber (reg:CC 17))]
11309 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11310 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11311 "sar{b}\\t%0"
11312 [(set_attr "type" "ishift")
11313 (set (attr "length")
11314 (if_then_else (match_operand 0 "register_operand" "")
11315 (const_string "2")
11316 (const_string "*")))])
11317
11318 (define_insn "*ashrqi3_1"
11319 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11320 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11321 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11322 (clobber (reg:CC 17))]
11323 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11324 "@
11325 sar{b}\\t{%2, %0|%0, %2}
11326 sar{b}\\t{%b2, %0|%0, %b2}"
11327 [(set_attr "type" "ishift")
11328 (set_attr "mode" "QI")])
11329
11330 ;; This pattern can't accept a variable shift count, since shifts by
11331 ;; zero don't affect the flags. We assume that shifts by constant
11332 ;; zero are optimized away.
11333 (define_insn "*ashrqi3_one_bit_cmp"
11334 [(set (reg 17)
11335 (compare
11336 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11337 (match_operand:QI 2 "const_int_1_operand" "I"))
11338 (const_int 0)))
11339 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11340 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11341 "ix86_match_ccmode (insn, CCGOCmode)
11342 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11343 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11344 "sar{b}\\t%0"
11345 [(set_attr "type" "ishift")
11346 (set (attr "length")
11347 (if_then_else (match_operand 0 "register_operand" "")
11348 (const_string "2")
11349 (const_string "*")))])
11350
11351 ;; This pattern can't accept a variable shift count, since shifts by
11352 ;; zero don't affect the flags. We assume that shifts by constant
11353 ;; zero are optimized away.
11354 (define_insn "*ashrqi3_cmp"
11355 [(set (reg 17)
11356 (compare
11357 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11358 (match_operand:QI 2 "immediate_operand" "I"))
11359 (const_int 0)))
11360 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
11361 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11362 "ix86_match_ccmode (insn, CCGOCmode)
11363 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11364 "sar{b}\\t{%2, %0|%0, %2}"
11365 [(set_attr "type" "ishift")
11366 (set_attr "mode" "QI")])
11367 \f
11368 ;; Logical shift instructions
11369
11370 ;; See comment above `ashldi3' about how this works.
11371
11372 (define_expand "lshrdi3"
11373 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11374 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11375 (match_operand:QI 2 "nonmemory_operand" "")))
11376 (clobber (reg:CC 17))])]
11377 ""
11378 "
11379 {
11380 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11381 {
11382 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11383 DONE;
11384 }
11385 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11386 DONE;
11387 }")
11388
11389 (define_insn "*lshrdi3_1_one_bit_rex64"
11390 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11391 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const_int_1_operand" "")))
11393 (clobber (reg:CC 17))]
11394 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11395 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11396 "shr{q}\\t%0"
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand:DI 0 "register_operand" "")
11400 (const_string "2")
11401 (const_string "*")))])
11402
11403 (define_insn "*lshrdi3_1_rex64"
11404 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11405 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11406 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11407 (clobber (reg:CC 17))]
11408 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11409 "@
11410 shr{q}\\t{%2, %0|%0, %2}
11411 shr{q}\\t{%b2, %0|%0, %b2}"
11412 [(set_attr "type" "ishift")
11413 (set_attr "mode" "DI")])
11414
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags. We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11419 [(set (reg 17)
11420 (compare
11421 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11422 (match_operand:QI 2 "const_int_1_operand" ""))
11423 (const_int 0)))
11424 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11425 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11426 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11427 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11428 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11429 "shr{q}\\t%0"
11430 [(set_attr "type" "ishift")
11431 (set (attr "length")
11432 (if_then_else (match_operand:DI 0 "register_operand" "")
11433 (const_string "2")
11434 (const_string "*")))])
11435
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags. We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*lshrdi3_cmp_rex64"
11440 [(set (reg 17)
11441 (compare
11442 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_int_operand" "e"))
11444 (const_int 0)))
11445 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11446 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11447 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11449 "shr{q}\\t{%2, %0|%0, %2}"
11450 [(set_attr "type" "ishift")
11451 (set_attr "mode" "DI")])
11452
11453 (define_insn "lshrdi3_1"
11454 [(set (match_operand:DI 0 "register_operand" "=r")
11455 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11457 (clobber (match_scratch:SI 3 "=&r"))
11458 (clobber (reg:CC 17))]
11459 "!TARGET_64BIT && TARGET_CMOVE"
11460 "#"
11461 [(set_attr "type" "multi")])
11462
11463 (define_insn "*lshrdi3_2"
11464 [(set (match_operand:DI 0 "register_operand" "=r")
11465 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11466 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11467 (clobber (reg:CC 17))]
11468 "!TARGET_64BIT"
11469 "#"
11470 [(set_attr "type" "multi")])
11471
11472 (define_split
11473 [(set (match_operand:DI 0 "register_operand" "")
11474 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11475 (match_operand:QI 2 "nonmemory_operand" "")))
11476 (clobber (match_scratch:SI 3 ""))
11477 (clobber (reg:CC 17))]
11478 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11479 [(const_int 0)]
11480 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11481
11482 (define_split
11483 [(set (match_operand:DI 0 "register_operand" "")
11484 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11485 (match_operand:QI 2 "nonmemory_operand" "")))
11486 (clobber (reg:CC 17))]
11487 "!TARGET_64BIT && reload_completed"
11488 [(const_int 0)]
11489 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11490
11491 (define_expand "lshrsi3"
11492 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11493 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11494 (match_operand:QI 2 "nonmemory_operand" "")))
11495 (clobber (reg:CC 17))]
11496 ""
11497 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11498
11499 (define_insn "*lshrsi3_1_one_bit"
11500 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11501 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11502 (match_operand:QI 2 "const_int_1_operand" "")))
11503 (clobber (reg:CC 17))]
11504 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11505 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11506 "shr{l}\\t%0"
11507 [(set_attr "type" "ishift")
11508 (set (attr "length")
11509 (if_then_else (match_operand:SI 0 "register_operand" "")
11510 (const_string "2")
11511 (const_string "*")))])
11512
11513 (define_insn "*lshrsi3_1_one_bit_zext"
11514 [(set (match_operand:DI 0 "register_operand" "=r")
11515 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11516 (match_operand:QI 2 "const_int_1_operand" "")))
11517 (clobber (reg:CC 17))]
11518 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11519 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11520 "shr{l}\\t%k0"
11521 [(set_attr "type" "ishift")
11522 (set_attr "length" "2")])
11523
11524 (define_insn "*lshrsi3_1"
11525 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11526 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11527 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11528 (clobber (reg:CC 17))]
11529 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11530 "@
11531 shr{l}\\t{%2, %0|%0, %2}
11532 shr{l}\\t{%b2, %0|%0, %b2}"
11533 [(set_attr "type" "ishift")
11534 (set_attr "mode" "SI")])
11535
11536 (define_insn "*lshrsi3_1_zext"
11537 [(set (match_operand:DI 0 "register_operand" "=r,r")
11538 (zero_extend:DI
11539 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11540 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11541 (clobber (reg:CC 17))]
11542 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11543 "@
11544 shr{l}\\t{%2, %k0|%k0, %2}
11545 shr{l}\\t{%b2, %k0|%k0, %b2}"
11546 [(set_attr "type" "ishift")
11547 (set_attr "mode" "SI")])
11548
11549 ;; This pattern can't accept a variable shift count, since shifts by
11550 ;; zero don't affect the flags. We assume that shifts by constant
11551 ;; zero are optimized away.
11552 (define_insn "*lshrsi3_one_bit_cmp"
11553 [(set (reg 17)
11554 (compare
11555 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11556 (match_operand:QI 2 "const_int_1_operand" ""))
11557 (const_int 0)))
11558 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11559 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11560 "ix86_match_ccmode (insn, CCGOCmode)
11561 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11562 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11563 "shr{l}\\t%0"
11564 [(set_attr "type" "ishift")
11565 (set (attr "length")
11566 (if_then_else (match_operand:SI 0 "register_operand" "")
11567 (const_string "2")
11568 (const_string "*")))])
11569
11570 (define_insn "*lshrsi3_cmp_one_bit_zext"
11571 [(set (reg 17)
11572 (compare
11573 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11574 (match_operand:QI 2 "const_int_1_operand" ""))
11575 (const_int 0)))
11576 (set (match_operand:DI 0 "register_operand" "=r")
11577 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11578 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11579 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11581 "shr{l}\\t%k0"
11582 [(set_attr "type" "ishift")
11583 (set_attr "length" "2")])
11584
11585 ;; This pattern can't accept a variable shift count, since shifts by
11586 ;; zero don't affect the flags. We assume that shifts by constant
11587 ;; zero are optimized away.
11588 (define_insn "*lshrsi3_cmp"
11589 [(set (reg 17)
11590 (compare
11591 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11592 (match_operand:QI 2 "immediate_operand" "I"))
11593 (const_int 0)))
11594 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11595 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11596 "ix86_match_ccmode (insn, CCGOCmode)
11597 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11598 "shr{l}\\t{%2, %0|%0, %2}"
11599 [(set_attr "type" "ishift")
11600 (set_attr "mode" "SI")])
11601
11602 (define_insn "*lshrsi3_cmp_zext"
11603 [(set (reg 17)
11604 (compare
11605 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11606 (match_operand:QI 2 "immediate_operand" "I"))
11607 (const_int 0)))
11608 (set (match_operand:DI 0 "register_operand" "=r")
11609 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11610 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11611 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11612 "shr{l}\\t{%2, %k0|%k0, %2}"
11613 [(set_attr "type" "ishift")
11614 (set_attr "mode" "SI")])
11615
11616 (define_expand "lshrhi3"
11617 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11618 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11619 (match_operand:QI 2 "nonmemory_operand" "")))
11620 (clobber (reg:CC 17))]
11621 "TARGET_HIMODE_MATH"
11622 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11623
11624 (define_insn "*lshrhi3_1_one_bit"
11625 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11626 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11627 (match_operand:QI 2 "const_int_1_operand" "")))
11628 (clobber (reg:CC 17))]
11629 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11630 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11631 "shr{w}\\t%0"
11632 [(set_attr "type" "ishift")
11633 (set (attr "length")
11634 (if_then_else (match_operand 0 "register_operand" "")
11635 (const_string "2")
11636 (const_string "*")))])
11637
11638 (define_insn "*lshrhi3_1"
11639 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11640 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11641 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11642 (clobber (reg:CC 17))]
11643 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11644 "@
11645 shr{w}\\t{%2, %0|%0, %2}
11646 shr{w}\\t{%b2, %0|%0, %b2}"
11647 [(set_attr "type" "ishift")
11648 (set_attr "mode" "HI")])
11649
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags. We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*lshrhi3_one_bit_cmp"
11654 [(set (reg 17)
11655 (compare
11656 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11657 (match_operand:QI 2 "const_int_1_operand" ""))
11658 (const_int 0)))
11659 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11660 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11661 "ix86_match_ccmode (insn, CCGOCmode)
11662 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11663 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11664 "shr{w}\\t%0"
11665 [(set_attr "type" "ishift")
11666 (set (attr "length")
11667 (if_then_else (match_operand:SI 0 "register_operand" "")
11668 (const_string "2")
11669 (const_string "*")))])
11670
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags. We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*lshrhi3_cmp"
11675 [(set (reg 17)
11676 (compare
11677 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11678 (match_operand:QI 2 "immediate_operand" "I"))
11679 (const_int 0)))
11680 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11681 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11682 "ix86_match_ccmode (insn, CCGOCmode)
11683 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684 "shr{w}\\t{%2, %0|%0, %2}"
11685 [(set_attr "type" "ishift")
11686 (set_attr "mode" "HI")])
11687
11688 (define_expand "lshrqi3"
11689 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11690 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11691 (match_operand:QI 2 "nonmemory_operand" "")))
11692 (clobber (reg:CC 17))]
11693 "TARGET_QIMODE_MATH"
11694 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11695
11696 (define_insn "*lshrqi3_1_one_bit"
11697 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11698 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11699 (match_operand:QI 2 "const_int_1_operand" "")))
11700 (clobber (reg:CC 17))]
11701 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11702 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11703 "shr{b}\\t%0"
11704 [(set_attr "type" "ishift")
11705 (set (attr "length")
11706 (if_then_else (match_operand 0 "register_operand" "")
11707 (const_string "2")
11708 (const_string "*")))])
11709
11710 (define_insn "*lshrqi3_1"
11711 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11712 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11713 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11714 (clobber (reg:CC 17))]
11715 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11716 "@
11717 shr{b}\\t{%2, %0|%0, %2}
11718 shr{b}\\t{%b2, %0|%0, %b2}"
11719 [(set_attr "type" "ishift")
11720 (set_attr "mode" "QI")])
11721
11722 ;; This pattern can't accept a variable shift count, since shifts by
11723 ;; zero don't affect the flags. We assume that shifts by constant
11724 ;; zero are optimized away.
11725 (define_insn "*lshrqi2_one_bit_cmp"
11726 [(set (reg 17)
11727 (compare
11728 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11729 (match_operand:QI 2 "const_int_1_operand" ""))
11730 (const_int 0)))
11731 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11732 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11733 "ix86_match_ccmode (insn, CCGOCmode)
11734 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
11735 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11736 "shr{b}\\t%0"
11737 [(set_attr "type" "ishift")
11738 (set (attr "length")
11739 (if_then_else (match_operand:SI 0 "register_operand" "")
11740 (const_string "2")
11741 (const_string "*")))])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags. We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*lshrqi2_cmp"
11747 [(set (reg 17)
11748 (compare
11749 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "immediate_operand" "I"))
11751 (const_int 0)))
11752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11753 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11754 "ix86_match_ccmode (insn, CCGOCmode)
11755 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11756 "shr{b}\\t{%2, %0|%0, %2}"
11757 [(set_attr "type" "ishift")
11758 (set_attr "mode" "QI")])
11759 \f
11760 ;; Rotate instructions
11761
11762 (define_expand "rotldi3"
11763 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11764 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11765 (match_operand:QI 2 "nonmemory_operand" "")))
11766 (clobber (reg:CC 17))]
11767 "TARGET_64BIT"
11768 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11769
11770 (define_insn "*rotlsi3_1_one_bit_rex64"
11771 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11772 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11773 (match_operand:QI 2 "const_int_1_operand" "")))
11774 (clobber (reg:CC 17))]
11775 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11776 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11777 "rol{q}\\t%0"
11778 [(set_attr "type" "ishift")
11779 (set (attr "length")
11780 (if_then_else (match_operand:DI 0 "register_operand" "")
11781 (const_string "2")
11782 (const_string "*")))])
11783
11784 (define_insn "*rotldi3_1_rex64"
11785 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11786 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11787 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11788 (clobber (reg:CC 17))]
11789 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11790 "@
11791 rol{q}\\t{%2, %0|%0, %2}
11792 rol{q}\\t{%b2, %0|%0, %b2}"
11793 [(set_attr "type" "ishift")
11794 (set_attr "mode" "DI")])
11795
11796 (define_expand "rotlsi3"
11797 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11798 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11799 (match_operand:QI 2 "nonmemory_operand" "")))
11800 (clobber (reg:CC 17))]
11801 ""
11802 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11803
11804 (define_insn "*rotlsi3_1_one_bit"
11805 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11806 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11807 (match_operand:QI 2 "const_int_1_operand" "")))
11808 (clobber (reg:CC 17))]
11809 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11810 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11811 "rol{l}\\t%0"
11812 [(set_attr "type" "ishift")
11813 (set (attr "length")
11814 (if_then_else (match_operand:SI 0 "register_operand" "")
11815 (const_string "2")
11816 (const_string "*")))])
11817
11818 (define_insn "*rotlsi3_1_one_bit_zext"
11819 [(set (match_operand:DI 0 "register_operand" "=r")
11820 (zero_extend:DI
11821 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11822 (match_operand:QI 2 "const_int_1_operand" ""))))
11823 (clobber (reg:CC 17))]
11824 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11825 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11826 "rol{l}\\t%k0"
11827 [(set_attr "type" "ishift")
11828 (set_attr "length" "2")])
11829
11830 (define_insn "*rotlsi3_1"
11831 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11832 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11833 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11834 (clobber (reg:CC 17))]
11835 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11836 "@
11837 rol{l}\\t{%2, %0|%0, %2}
11838 rol{l}\\t{%b2, %0|%0, %b2}"
11839 [(set_attr "type" "ishift")
11840 (set_attr "mode" "SI")])
11841
11842 (define_insn "*rotlsi3_1_zext"
11843 [(set (match_operand:DI 0 "register_operand" "=r,r")
11844 (zero_extend:DI
11845 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11846 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11847 (clobber (reg:CC 17))]
11848 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11849 "@
11850 rol{l}\\t{%2, %k0|%k0, %2}
11851 rol{l}\\t{%b2, %k0|%k0, %b2}"
11852 [(set_attr "type" "ishift")
11853 (set_attr "mode" "SI")])
11854
11855 (define_expand "rotlhi3"
11856 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11857 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11858 (match_operand:QI 2 "nonmemory_operand" "")))
11859 (clobber (reg:CC 17))]
11860 "TARGET_HIMODE_MATH"
11861 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11862
11863 (define_insn "*rotlhi3_1_one_bit"
11864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11865 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11866 (match_operand:QI 2 "const_int_1_operand" "")))
11867 (clobber (reg:CC 17))]
11868 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11869 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11870 "rol{w}\\t%0"
11871 [(set_attr "type" "ishift")
11872 (set (attr "length")
11873 (if_then_else (match_operand 0 "register_operand" "")
11874 (const_string "2")
11875 (const_string "*")))])
11876
11877 (define_insn "*rotlhi3_1"
11878 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11879 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11880 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11881 (clobber (reg:CC 17))]
11882 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11883 "@
11884 rol{w}\\t{%2, %0|%0, %2}
11885 rol{w}\\t{%b2, %0|%0, %b2}"
11886 [(set_attr "type" "ishift")
11887 (set_attr "mode" "HI")])
11888
11889 (define_expand "rotlqi3"
11890 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11891 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11892 (match_operand:QI 2 "nonmemory_operand" "")))
11893 (clobber (reg:CC 17))]
11894 "TARGET_QIMODE_MATH"
11895 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11896
11897 (define_insn "*rotlqi3_1_one_bit"
11898 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11899 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11900 (match_operand:QI 2 "const_int_1_operand" "")))
11901 (clobber (reg:CC 17))]
11902 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11903 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11904 "rol{b}\\t%0"
11905 [(set_attr "type" "ishift")
11906 (set (attr "length")
11907 (if_then_else (match_operand 0 "register_operand" "")
11908 (const_string "2")
11909 (const_string "*")))])
11910
11911 (define_insn "*rotlqi3_1"
11912 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11913 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11914 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11915 (clobber (reg:CC 17))]
11916 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11917 "@
11918 rol{b}\\t{%2, %0|%0, %2}
11919 rol{b}\\t{%b2, %0|%0, %b2}"
11920 [(set_attr "type" "ishift")
11921 (set_attr "mode" "QI")])
11922
11923 (define_expand "rotrdi3"
11924 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11925 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11926 (match_operand:QI 2 "nonmemory_operand" "")))
11927 (clobber (reg:CC 17))]
11928 "TARGET_64BIT"
11929 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11930
11931 (define_insn "*rotrdi3_1_one_bit_rex64"
11932 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11933 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11934 (match_operand:QI 2 "const_int_1_operand" "")))
11935 (clobber (reg:CC 17))]
11936 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11937 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11938 "ror{q}\\t%0"
11939 [(set_attr "type" "ishift")
11940 (set (attr "length")
11941 (if_then_else (match_operand:DI 0 "register_operand" "")
11942 (const_string "2")
11943 (const_string "*")))])
11944
11945 (define_insn "*rotrdi3_1_rex64"
11946 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11947 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11948 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11949 (clobber (reg:CC 17))]
11950 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11951 "@
11952 ror{q}\\t{%2, %0|%0, %2}
11953 ror{q}\\t{%b2, %0|%0, %b2}"
11954 [(set_attr "type" "ishift")
11955 (set_attr "mode" "DI")])
11956
11957 (define_expand "rotrsi3"
11958 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11959 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11960 (match_operand:QI 2 "nonmemory_operand" "")))
11961 (clobber (reg:CC 17))]
11962 ""
11963 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11964
11965 (define_insn "*rotrsi3_1_one_bit"
11966 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11967 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11968 (match_operand:QI 2 "const_int_1_operand" "")))
11969 (clobber (reg:CC 17))]
11970 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11971 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11972 "ror{l}\\t%0"
11973 [(set_attr "type" "ishift")
11974 (set (attr "length")
11975 (if_then_else (match_operand:SI 0 "register_operand" "")
11976 (const_string "2")
11977 (const_string "*")))])
11978
11979 (define_insn "*rotrsi3_1_one_bit_zext"
11980 [(set (match_operand:DI 0 "register_operand" "=r")
11981 (zero_extend:DI
11982 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11983 (match_operand:QI 2 "const_int_1_operand" ""))))
11984 (clobber (reg:CC 17))]
11985 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11986 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
11987 "ror{l}\\t%k0"
11988 [(set_attr "type" "ishift")
11989 (set (attr "length")
11990 (if_then_else (match_operand:SI 0 "register_operand" "")
11991 (const_string "2")
11992 (const_string "*")))])
11993
11994 (define_insn "*rotrsi3_1"
11995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11996 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11997 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11998 (clobber (reg:CC 17))]
11999 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12000 "@
12001 ror{l}\\t{%2, %0|%0, %2}
12002 ror{l}\\t{%b2, %0|%0, %b2}"
12003 [(set_attr "type" "ishift")
12004 (set_attr "mode" "SI")])
12005
12006 (define_insn "*rotrsi3_1_zext"
12007 [(set (match_operand:DI 0 "register_operand" "=r,r")
12008 (zero_extend:DI
12009 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12010 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12011 (clobber (reg:CC 17))]
12012 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12013 "@
12014 ror{l}\\t{%2, %k0|%k0, %2}
12015 ror{l}\\t{%b2, %k0|%k0, %b2}"
12016 [(set_attr "type" "ishift")
12017 (set_attr "mode" "SI")])
12018
12019 (define_expand "rotrhi3"
12020 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12021 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12022 (match_operand:QI 2 "nonmemory_operand" "")))
12023 (clobber (reg:CC 17))]
12024 "TARGET_HIMODE_MATH"
12025 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12026
12027 (define_insn "*rotrhi3_one_bit"
12028 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12029 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12030 (match_operand:QI 2 "const_int_1_operand" "")))
12031 (clobber (reg:CC 17))]
12032 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12033 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12034 "ror{w}\\t%0"
12035 [(set_attr "type" "ishift")
12036 (set (attr "length")
12037 (if_then_else (match_operand 0 "register_operand" "")
12038 (const_string "2")
12039 (const_string "*")))])
12040
12041 (define_insn "*rotrhi3"
12042 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12043 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12044 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12045 (clobber (reg:CC 17))]
12046 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12047 "@
12048 ror{w}\\t{%2, %0|%0, %2}
12049 ror{w}\\t{%b2, %0|%0, %b2}"
12050 [(set_attr "type" "ishift")
12051 (set_attr "mode" "HI")])
12052
12053 (define_expand "rotrqi3"
12054 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12055 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12056 (match_operand:QI 2 "nonmemory_operand" "")))
12057 (clobber (reg:CC 17))]
12058 "TARGET_QIMODE_MATH"
12059 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12060
12061 (define_insn "*rotrqi3_1_one_bit"
12062 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12063 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12064 (match_operand:QI 2 "const_int_1_operand" "")))
12065 (clobber (reg:CC 17))]
12066 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12067 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
12068 "ror{b}\\t%0"
12069 [(set_attr "type" "ishift")
12070 (set (attr "length")
12071 (if_then_else (match_operand 0 "register_operand" "")
12072 (const_string "2")
12073 (const_string "*")))])
12074
12075 (define_insn "*rotrqi3_1"
12076 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12077 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12078 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12079 (clobber (reg:CC 17))]
12080 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12081 "@
12082 ror{b}\\t{%2, %0|%0, %2}
12083 ror{b}\\t{%b2, %0|%0, %b2}"
12084 [(set_attr "type" "ishift")
12085 (set_attr "mode" "QI")])
12086 \f
12087 ;; Bit set / bit test instructions
12088
12089 (define_expand "extv"
12090 [(set (match_operand:SI 0 "register_operand" "")
12091 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12092 (match_operand:SI 2 "immediate_operand" "")
12093 (match_operand:SI 3 "immediate_operand" "")))]
12094 ""
12095 "
12096 {
12097 /* Handle extractions from %ah et al. */
12098 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12099 FAIL;
12100
12101 /* From mips.md: extract_bit_field doesn't verify that our source
12102 matches the predicate, so check it again here. */
12103 if (! register_operand (operands[1], VOIDmode))
12104 FAIL;
12105 }")
12106
12107 (define_expand "extzv"
12108 [(set (match_operand:SI 0 "register_operand" "")
12109 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12110 (match_operand:SI 2 "immediate_operand" "")
12111 (match_operand:SI 3 "immediate_operand" "")))]
12112 ""
12113 "
12114 {
12115 /* Handle extractions from %ah et al. */
12116 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12117 FAIL;
12118
12119 /* From mips.md: extract_bit_field doesn't verify that our source
12120 matches the predicate, so check it again here. */
12121 if (! register_operand (operands[1], VOIDmode))
12122 FAIL;
12123 }")
12124
12125 (define_expand "insv"
12126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12127 (match_operand:SI 1 "immediate_operand" "")
12128 (match_operand:SI 2 "immediate_operand" ""))
12129 (match_operand:SI 3 "register_operand" ""))]
12130 ""
12131 "
12132 {
12133 /* Handle extractions from %ah et al. */
12134 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12135 FAIL;
12136
12137 /* From mips.md: insert_bit_field doesn't verify that our source
12138 matches the predicate, so check it again here. */
12139 if (! register_operand (operands[0], VOIDmode))
12140 FAIL;
12141 }")
12142
12143 ;; %%% bts, btr, btc, bt.
12144 \f
12145 ;; Store-flag instructions.
12146
12147 ;; For all sCOND expanders, also expand the compare or test insn that
12148 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12149
12150 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12151 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12152 ;; way, which can later delete the movzx if only QImode is needed.
12153
12154 (define_expand "seq"
12155 [(set (match_operand:SI 0 "register_operand" "")
12156 (eq:SI (reg:CC 17) (const_int 0)))]
12157 ""
12158 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12159
12160 (define_expand "sne"
12161 [(set (match_operand:SI 0 "register_operand" "")
12162 (ne:SI (reg:CC 17) (const_int 0)))]
12163 ""
12164 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12165
12166 (define_expand "sgt"
12167 [(set (match_operand:SI 0 "register_operand" "")
12168 (gt:SI (reg:CC 17) (const_int 0)))]
12169 ""
12170 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12171
12172 (define_expand "sgtu"
12173 [(set (match_operand:SI 0 "register_operand" "")
12174 (gtu:SI (reg:CC 17) (const_int 0)))]
12175 ""
12176 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12177
12178 (define_expand "slt"
12179 [(set (match_operand:SI 0 "register_operand" "")
12180 (lt:SI (reg:CC 17) (const_int 0)))]
12181 ""
12182 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12183
12184 (define_expand "sltu"
12185 [(set (match_operand:SI 0 "register_operand" "")
12186 (ltu:SI (reg:CC 17) (const_int 0)))]
12187 ""
12188 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12189
12190 (define_expand "sge"
12191 [(set (match_operand:SI 0 "register_operand" "")
12192 (ge:SI (reg:CC 17) (const_int 0)))]
12193 ""
12194 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12195
12196 (define_expand "sgeu"
12197 [(set (match_operand:SI 0 "register_operand" "")
12198 (geu:SI (reg:CC 17) (const_int 0)))]
12199 ""
12200 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12201
12202 (define_expand "sle"
12203 [(set (match_operand:SI 0 "register_operand" "")
12204 (le:SI (reg:CC 17) (const_int 0)))]
12205 ""
12206 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12207
12208 (define_expand "sleu"
12209 [(set (match_operand:SI 0 "register_operand" "")
12210 (leu:SI (reg:CC 17) (const_int 0)))]
12211 ""
12212 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12213
12214 (define_expand "sunordered"
12215 [(set (match_operand:SI 0 "register_operand" "")
12216 (unordered:SI (reg:CC 17) (const_int 0)))]
12217 "TARGET_80387 || TARGET_SSE"
12218 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12219
12220 (define_expand "sordered"
12221 [(set (match_operand:SI 0 "register_operand" "")
12222 (ordered:SI (reg:CC 17) (const_int 0)))]
12223 "TARGET_80387"
12224 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12225
12226 (define_expand "suneq"
12227 [(set (match_operand:SI 0 "register_operand" "")
12228 (uneq:SI (reg:CC 17) (const_int 0)))]
12229 "TARGET_80387 || TARGET_SSE"
12230 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12231
12232 (define_expand "sunge"
12233 [(set (match_operand:SI 0 "register_operand" "")
12234 (unge:SI (reg:CC 17) (const_int 0)))]
12235 "TARGET_80387 || TARGET_SSE"
12236 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12237
12238 (define_expand "sungt"
12239 [(set (match_operand:SI 0 "register_operand" "")
12240 (ungt:SI (reg:CC 17) (const_int 0)))]
12241 "TARGET_80387 || TARGET_SSE"
12242 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12243
12244 (define_expand "sunle"
12245 [(set (match_operand:SI 0 "register_operand" "")
12246 (unle:SI (reg:CC 17) (const_int 0)))]
12247 "TARGET_80387 || TARGET_SSE"
12248 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12249
12250 (define_expand "sunlt"
12251 [(set (match_operand:SI 0 "register_operand" "")
12252 (unlt:SI (reg:CC 17) (const_int 0)))]
12253 "TARGET_80387 || TARGET_SSE"
12254 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12255
12256 (define_expand "sltgt"
12257 [(set (match_operand:SI 0 "register_operand" "")
12258 (ltgt:SI (reg:CC 17) (const_int 0)))]
12259 "TARGET_80387 || TARGET_SSE"
12260 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12261
12262 (define_insn "*setcc_1"
12263 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12264 (match_operator:QI 1 "ix86_comparison_operator"
12265 [(reg 17) (const_int 0)]))]
12266 ""
12267 "set%C1\\t%0"
12268 [(set_attr "type" "setcc")
12269 (set_attr "mode" "QI")])
12270
12271 (define_insn "setcc_2"
12272 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12273 (match_operator:QI 1 "ix86_comparison_operator"
12274 [(reg 17) (const_int 0)]))]
12275 ""
12276 "set%C1\\t%0"
12277 [(set_attr "type" "setcc")
12278 (set_attr "mode" "QI")])
12279
12280 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12281 ;; subsequent logical operations are used to imitate conditional moves.
12282 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12283 ;; it directly. Futher holding this value in pseudo register might bring
12284 ;; problem in implicit normalization in spill code.
12285 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12286 ;; instructions after reload by splitting the conditional move patterns.
12287
12288 (define_insn "*sse_setccsf"
12289 [(set (match_operand:SF 0 "register_operand" "=x")
12290 (match_operator:SF 1 "sse_comparison_operator"
12291 [(match_operand:SF 2 "register_operand" "0")
12292 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12293 "TARGET_SSE && reload_completed"
12294 "cmp%D1ss\\t{%3, %0|%0, %3}"
12295 [(set_attr "type" "sse")
12296 (set_attr "mode" "SF")])
12297
12298 (define_insn "*sse_setccdf"
12299 [(set (match_operand:DF 0 "register_operand" "=Y")
12300 (match_operator:DF 1 "sse_comparison_operator"
12301 [(match_operand:DF 2 "register_operand" "0")
12302 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12303 "TARGET_SSE2 && reload_completed"
12304 "cmp%D1sd\\t{%3, %0|%0, %3}"
12305 [(set_attr "type" "sse")
12306 (set_attr "mode" "DF")])
12307 \f
12308 ;; Basic conditional jump instructions.
12309 ;; We ignore the overflow flag for signed branch instructions.
12310
12311 ;; For all bCOND expanders, also expand the compare or test insn that
12312 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12313
12314 (define_expand "beq"
12315 [(set (pc)
12316 (if_then_else (match_dup 1)
12317 (label_ref (match_operand 0 "" ""))
12318 (pc)))]
12319 ""
12320 "ix86_expand_branch (EQ, operands[0]); DONE;")
12321
12322 (define_expand "bne"
12323 [(set (pc)
12324 (if_then_else (match_dup 1)
12325 (label_ref (match_operand 0 "" ""))
12326 (pc)))]
12327 ""
12328 "ix86_expand_branch (NE, operands[0]); DONE;")
12329
12330 (define_expand "bgt"
12331 [(set (pc)
12332 (if_then_else (match_dup 1)
12333 (label_ref (match_operand 0 "" ""))
12334 (pc)))]
12335 ""
12336 "ix86_expand_branch (GT, operands[0]); DONE;")
12337
12338 (define_expand "bgtu"
12339 [(set (pc)
12340 (if_then_else (match_dup 1)
12341 (label_ref (match_operand 0 "" ""))
12342 (pc)))]
12343 ""
12344 "ix86_expand_branch (GTU, operands[0]); DONE;")
12345
12346 (define_expand "blt"
12347 [(set (pc)
12348 (if_then_else (match_dup 1)
12349 (label_ref (match_operand 0 "" ""))
12350 (pc)))]
12351 ""
12352 "ix86_expand_branch (LT, operands[0]); DONE;")
12353
12354 (define_expand "bltu"
12355 [(set (pc)
12356 (if_then_else (match_dup 1)
12357 (label_ref (match_operand 0 "" ""))
12358 (pc)))]
12359 ""
12360 "ix86_expand_branch (LTU, operands[0]); DONE;")
12361
12362 (define_expand "bge"
12363 [(set (pc)
12364 (if_then_else (match_dup 1)
12365 (label_ref (match_operand 0 "" ""))
12366 (pc)))]
12367 ""
12368 "ix86_expand_branch (GE, operands[0]); DONE;")
12369
12370 (define_expand "bgeu"
12371 [(set (pc)
12372 (if_then_else (match_dup 1)
12373 (label_ref (match_operand 0 "" ""))
12374 (pc)))]
12375 ""
12376 "ix86_expand_branch (GEU, operands[0]); DONE;")
12377
12378 (define_expand "ble"
12379 [(set (pc)
12380 (if_then_else (match_dup 1)
12381 (label_ref (match_operand 0 "" ""))
12382 (pc)))]
12383 ""
12384 "ix86_expand_branch (LE, operands[0]); DONE;")
12385
12386 (define_expand "bleu"
12387 [(set (pc)
12388 (if_then_else (match_dup 1)
12389 (label_ref (match_operand 0 "" ""))
12390 (pc)))]
12391 ""
12392 "ix86_expand_branch (LEU, operands[0]); DONE;")
12393
12394 (define_expand "bunordered"
12395 [(set (pc)
12396 (if_then_else (match_dup 1)
12397 (label_ref (match_operand 0 "" ""))
12398 (pc)))]
12399 "TARGET_80387 || TARGET_SSE"
12400 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12401
12402 (define_expand "bordered"
12403 [(set (pc)
12404 (if_then_else (match_dup 1)
12405 (label_ref (match_operand 0 "" ""))
12406 (pc)))]
12407 "TARGET_80387 || TARGET_SSE"
12408 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12409
12410 (define_expand "buneq"
12411 [(set (pc)
12412 (if_then_else (match_dup 1)
12413 (label_ref (match_operand 0 "" ""))
12414 (pc)))]
12415 "TARGET_80387 || TARGET_SSE"
12416 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12417
12418 (define_expand "bunge"
12419 [(set (pc)
12420 (if_then_else (match_dup 1)
12421 (label_ref (match_operand 0 "" ""))
12422 (pc)))]
12423 "TARGET_80387 || TARGET_SSE"
12424 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12425
12426 (define_expand "bungt"
12427 [(set (pc)
12428 (if_then_else (match_dup 1)
12429 (label_ref (match_operand 0 "" ""))
12430 (pc)))]
12431 "TARGET_80387 || TARGET_SSE"
12432 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12433
12434 (define_expand "bunle"
12435 [(set (pc)
12436 (if_then_else (match_dup 1)
12437 (label_ref (match_operand 0 "" ""))
12438 (pc)))]
12439 "TARGET_80387 || TARGET_SSE"
12440 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12441
12442 (define_expand "bunlt"
12443 [(set (pc)
12444 (if_then_else (match_dup 1)
12445 (label_ref (match_operand 0 "" ""))
12446 (pc)))]
12447 "TARGET_80387 || TARGET_SSE"
12448 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12449
12450 (define_expand "bltgt"
12451 [(set (pc)
12452 (if_then_else (match_dup 1)
12453 (label_ref (match_operand 0 "" ""))
12454 (pc)))]
12455 "TARGET_80387 || TARGET_SSE"
12456 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12457
12458 (define_insn "*jcc_1"
12459 [(set (pc)
12460 (if_then_else (match_operator 1 "ix86_comparison_operator"
12461 [(reg 17) (const_int 0)])
12462 (label_ref (match_operand 0 "" ""))
12463 (pc)))]
12464 ""
12465 "j%C1\\t%l0"
12466 [(set_attr "type" "ibr")
12467 (set (attr "prefix_0f")
12468 (if_then_else (and (ge (minus (match_dup 0) (pc))
12469 (const_int -128))
12470 (lt (minus (match_dup 0) (pc))
12471 (const_int 124)))
12472 (const_int 0)
12473 (const_int 1)))])
12474
12475 (define_insn "*jcc_2"
12476 [(set (pc)
12477 (if_then_else (match_operator 1 "ix86_comparison_operator"
12478 [(reg 17) (const_int 0)])
12479 (pc)
12480 (label_ref (match_operand 0 "" ""))))]
12481 ""
12482 "j%c1\\t%l0"
12483 [(set_attr "type" "ibr")
12484 (set (attr "prefix_0f")
12485 (if_then_else (and (ge (minus (match_dup 0) (pc))
12486 (const_int -128))
12487 (lt (minus (match_dup 0) (pc))
12488 (const_int 124)))
12489 (const_int 0)
12490 (const_int 1)))])
12491
12492 ;; Define combination compare-and-branch fp compare instructions to use
12493 ;; during early optimization. Splitting the operation apart early makes
12494 ;; for bad code when we want to reverse the operation.
12495
12496 (define_insn "*fp_jcc_1"
12497 [(set (pc)
12498 (if_then_else (match_operator 0 "comparison_operator"
12499 [(match_operand 1 "register_operand" "f")
12500 (match_operand 2 "register_operand" "f")])
12501 (label_ref (match_operand 3 "" ""))
12502 (pc)))
12503 (clobber (reg:CCFP 18))
12504 (clobber (reg:CCFP 17))]
12505 "TARGET_CMOVE && TARGET_80387
12506 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12507 && FLOAT_MODE_P (GET_MODE (operands[1]))
12508 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12509 "#")
12510
12511 (define_insn "*fp_jcc_1_sse"
12512 [(set (pc)
12513 (if_then_else (match_operator 0 "comparison_operator"
12514 [(match_operand 1 "register_operand" "f#x,x#f")
12515 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12516 (label_ref (match_operand 3 "" ""))
12517 (pc)))
12518 (clobber (reg:CCFP 18))
12519 (clobber (reg:CCFP 17))]
12520 "TARGET_80387
12521 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12522 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12523 "#")
12524
12525 (define_insn "*fp_jcc_1_sse_only"
12526 [(set (pc)
12527 (if_then_else (match_operator 0 "comparison_operator"
12528 [(match_operand 1 "register_operand" "x")
12529 (match_operand 2 "nonimmediate_operand" "xm")])
12530 (label_ref (match_operand 3 "" ""))
12531 (pc)))
12532 (clobber (reg:CCFP 18))
12533 (clobber (reg:CCFP 17))]
12534 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12535 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12536 "#")
12537
12538 (define_insn "*fp_jcc_2"
12539 [(set (pc)
12540 (if_then_else (match_operator 0 "comparison_operator"
12541 [(match_operand 1 "register_operand" "f")
12542 (match_operand 2 "register_operand" "f")])
12543 (pc)
12544 (label_ref (match_operand 3 "" ""))))
12545 (clobber (reg:CCFP 18))
12546 (clobber (reg:CCFP 17))]
12547 "TARGET_CMOVE && TARGET_80387
12548 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12549 && FLOAT_MODE_P (GET_MODE (operands[1]))
12550 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12551 "#")
12552
12553 (define_insn "*fp_jcc_2_sse"
12554 [(set (pc)
12555 (if_then_else (match_operator 0 "comparison_operator"
12556 [(match_operand 1 "register_operand" "f#x,x#f")
12557 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12558 (pc)
12559 (label_ref (match_operand 3 "" ""))))
12560 (clobber (reg:CCFP 18))
12561 (clobber (reg:CCFP 17))]
12562 "TARGET_80387
12563 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12564 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12565 "#")
12566
12567 (define_insn "*fp_jcc_2_sse_only"
12568 [(set (pc)
12569 (if_then_else (match_operator 0 "comparison_operator"
12570 [(match_operand 1 "register_operand" "x")
12571 (match_operand 2 "nonimmediate_operand" "xm")])
12572 (pc)
12573 (label_ref (match_operand 3 "" ""))))
12574 (clobber (reg:CCFP 18))
12575 (clobber (reg:CCFP 17))]
12576 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12577 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12578 "#")
12579
12580 (define_insn "*fp_jcc_3"
12581 [(set (pc)
12582 (if_then_else (match_operator 0 "comparison_operator"
12583 [(match_operand 1 "register_operand" "f")
12584 (match_operand 2 "nonimmediate_operand" "fm")])
12585 (label_ref (match_operand 3 "" ""))
12586 (pc)))
12587 (clobber (reg:CCFP 18))
12588 (clobber (reg:CCFP 17))
12589 (clobber (match_scratch:HI 4 "=a"))]
12590 "TARGET_80387
12591 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12592 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12593 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12594 && SELECT_CC_MODE (GET_CODE (operands[0]),
12595 operands[1], operands[2]) == CCFPmode"
12596 "#")
12597
12598 (define_insn "*fp_jcc_4"
12599 [(set (pc)
12600 (if_then_else (match_operator 0 "comparison_operator"
12601 [(match_operand 1 "register_operand" "f")
12602 (match_operand 2 "nonimmediate_operand" "fm")])
12603 (pc)
12604 (label_ref (match_operand 3 "" ""))))
12605 (clobber (reg:CCFP 18))
12606 (clobber (reg:CCFP 17))
12607 (clobber (match_scratch:HI 4 "=a"))]
12608 "TARGET_80387
12609 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12610 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12611 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12612 && SELECT_CC_MODE (GET_CODE (operands[0]),
12613 operands[1], operands[2]) == CCFPmode"
12614 "#")
12615
12616 (define_insn "*fp_jcc_5"
12617 [(set (pc)
12618 (if_then_else (match_operator 0 "comparison_operator"
12619 [(match_operand 1 "register_operand" "f")
12620 (match_operand 2 "register_operand" "f")])
12621 (label_ref (match_operand 3 "" ""))
12622 (pc)))
12623 (clobber (reg:CCFP 18))
12624 (clobber (reg:CCFP 17))
12625 (clobber (match_scratch:HI 4 "=a"))]
12626 "TARGET_80387
12627 && FLOAT_MODE_P (GET_MODE (operands[1]))
12628 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12629 "#")
12630
12631 (define_insn "*fp_jcc_6"
12632 [(set (pc)
12633 (if_then_else (match_operator 0 "comparison_operator"
12634 [(match_operand 1 "register_operand" "f")
12635 (match_operand 2 "register_operand" "f")])
12636 (pc)
12637 (label_ref (match_operand 3 "" ""))))
12638 (clobber (reg:CCFP 18))
12639 (clobber (reg:CCFP 17))
12640 (clobber (match_scratch:HI 4 "=a"))]
12641 "TARGET_80387
12642 && FLOAT_MODE_P (GET_MODE (operands[1]))
12643 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
12644 "#")
12645
12646 (define_split
12647 [(set (pc)
12648 (if_then_else (match_operator 0 "comparison_operator"
12649 [(match_operand 1 "register_operand" "")
12650 (match_operand 2 "nonimmediate_operand" "")])
12651 (match_operand 3 "" "")
12652 (match_operand 4 "" "")))
12653 (clobber (reg:CCFP 18))
12654 (clobber (reg:CCFP 17))]
12655 "reload_completed"
12656 [(const_int 0)]
12657 "
12658 {
12659 ix86_split_fp_branch (operands[0], operands[1], operands[2],
12660 operands[3], operands[4], NULL_RTX);
12661 DONE;
12662 }")
12663
12664 (define_split
12665 [(set (pc)
12666 (if_then_else (match_operator 0 "comparison_operator"
12667 [(match_operand 1 "register_operand" "")
12668 (match_operand 2 "nonimmediate_operand" "")])
12669 (match_operand 3 "" "")
12670 (match_operand 4 "" "")))
12671 (clobber (reg:CCFP 18))
12672 (clobber (reg:CCFP 17))
12673 (clobber (match_scratch:HI 5 "=a"))]
12674 "reload_completed"
12675 [(set (pc)
12676 (if_then_else (match_dup 6)
12677 (match_dup 3)
12678 (match_dup 4)))]
12679 "
12680 {
12681 ix86_split_fp_branch (operands[0], operands[1], operands[2],
12682 operands[3], operands[4], operands[5]);
12683 DONE;
12684 }")
12685 \f
12686 ;; Unconditional and other jump instructions
12687
12688 (define_insn "jump"
12689 [(set (pc)
12690 (label_ref (match_operand 0 "" "")))]
12691 ""
12692 "jmp\\t%l0"
12693 [(set_attr "type" "ibr")])
12694
12695 (define_insn "indirect_jump"
12696 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
12697 ""
12698 "jmp\\t%A0"
12699 [(set_attr "type" "ibr")
12700 (set_attr "length_immediate" "0")])
12701
12702 (define_insn "tablejump"
12703 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
12704 (use (label_ref (match_operand 1 "" "")))]
12705 "! flag_pic"
12706 "jmp\\t%A0"
12707 [(set_attr "type" "ibr")
12708 (set_attr "length_immediate" "0")])
12709
12710 ;; Implement switch statements when generating PIC code. Switches are
12711 ;; implemented by `tablejump' when not using -fpic.
12712 ;;
12713 ;; Emit code here to do the range checking and make the index zero based.
12714 ;;
12715 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
12716 ;; two rules below:
12717 ;;
12718 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
12719 ;;
12720 ;; 1. An expression involving an external reference may only use the
12721 ;; addition operator, and only with an assembly-time constant.
12722 ;; The example above satisfies this because ".-.L2" is a constant.
12723 ;;
12724 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
12725 ;; given the value of "GOT - .", where GOT is the actual address of
12726 ;; the Global Offset Table. Therefore, the .long above actually
12727 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
12728 ;; expression "GOT - .L2" by itself would generate an error from as(1).
12729 ;;
12730 ;; The pattern below emits code that looks like this:
12731 ;;
12732 ;; movl %ebx,reg
12733 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
12734 ;; jmp reg
12735 ;;
12736 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
12737 ;; the addr_diff_vec is known to be part of this module.
12738 ;;
12739 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
12740 ;; evaluates to just ".L2".
12741
12742 (define_expand "casesi"
12743 [(set (match_dup 5)
12744 (match_operand:SI 0 "general_operand" ""))
12745 (parallel [(set (match_dup 6)
12746 (minus:SI (match_dup 5)
12747 (match_operand:SI 1 "general_operand" "")))
12748 (clobber (reg:CC 17))])
12749 (set (reg:CC 17)
12750 (compare:CC (match_dup 6)
12751 (match_operand:SI 2 "general_operand" "")))
12752 (set (pc)
12753 (if_then_else (gtu (reg:CC 17)
12754 (const_int 0))
12755 (label_ref (match_operand 4 "" ""))
12756 (pc)))
12757 (parallel
12758 [(set (match_dup 7)
12759 (minus:SI (match_dup 8)
12760 (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
12761 (match_dup 8))
12762 (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
12763 (clobber (reg:CC 17))])
12764 (parallel [(set (pc) (match_dup 7))
12765 (use (label_ref (match_dup 3)))])]
12766 "flag_pic"
12767 "
12768 {
12769 operands[5] = gen_reg_rtx (SImode);
12770 operands[6] = gen_reg_rtx (SImode);
12771 operands[7] = gen_reg_rtx (SImode);
12772 operands[8] = pic_offset_table_rtx;
12773 current_function_uses_pic_offset_table = 1;
12774 }")
12775
12776 (define_insn "*tablejump_pic"
12777 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
12778 (use (label_ref (match_operand 1 "" "")))]
12779 ""
12780 "jmp\\t%A0"
12781 [(set_attr "type" "ibr")
12782 (set_attr "length_immediate" "0")])
12783 \f
12784 ;; Loop instruction
12785 ;;
12786 ;; This is all complicated by the fact that since this is a jump insn
12787 ;; we must handle our own reloads.
12788
12789 (define_expand "doloop_end"
12790 [(use (match_operand 0 "" "")) ; loop pseudo
12791 (use (match_operand 1 "" "")) ; iterations; zero if unknown
12792 (use (match_operand 2 "" "")) ; max iterations
12793 (use (match_operand 3 "" "")) ; loop level
12794 (use (match_operand 4 "" ""))] ; label
12795 "TARGET_USE_LOOP && !TARGET_64BIT"
12796 "
12797 {
12798 /* Only use cloop on innermost loops. */
12799 if (INTVAL (operands[3]) > 1)
12800 FAIL;
12801 if (GET_MODE (operands[0]) != SImode)
12802 FAIL;
12803 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
12804 operands[0]));
12805 DONE;
12806 }")
12807
12808 (define_insn "doloop_end_internal"
12809 [(set (pc)
12810 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
12811 (const_int 1))
12812 (label_ref (match_operand 0 "" ""))
12813 (pc)))
12814 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
12815 (plus:SI (match_dup 1)
12816 (const_int -1)))
12817 (clobber (match_scratch:SI 3 "=X,X,r"))
12818 (clobber (reg:CC 17))]
12819 "TARGET_USE_LOOP && !TARGET_64BIT"
12820 "*
12821 {
12822 if (which_alternative != 0)
12823 return \"#\";
12824 if (get_attr_length (insn) == 2)
12825 return \"loop\\t%l0\";
12826 else
12827 return \"dec{l}\\t%1\;jne\\t%l0\";
12828 }"
12829 [(set_attr "ppro_uops" "many")
12830 (set (attr "type")
12831 (if_then_else (and (eq_attr "alternative" "0")
12832 (and (ge (minus (match_dup 0) (pc))
12833 (const_int -128))
12834 (lt (minus (match_dup 0) (pc))
12835 (const_int 124))))
12836 (const_string "ibr")
12837 (const_string "multi")))])
12838
12839 (define_split
12840 [(set (pc)
12841 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
12842 (const_int 1))
12843 (match_operand 0 "" "")
12844 (pc)))
12845 (set (match_dup 1)
12846 (plus:SI (match_dup 1)
12847 (const_int -1)))
12848 (clobber (match_scratch:SI 2 ""))
12849 (clobber (reg:CC 17))]
12850 "TARGET_USE_LOOP && !TARGET_64BIT
12851 && reload_completed
12852 && REGNO (operands[1]) != 2"
12853 [(parallel [(set (reg:CCZ 17)
12854 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
12855 (const_int 0)))
12856 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
12857 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
12858 (match_dup 0)
12859 (pc)))]
12860 "")
12861
12862 (define_split
12863 [(set (pc)
12864 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
12865 (const_int 1))
12866 (match_operand 0 "" "")
12867 (pc)))
12868 (set (match_operand:SI 2 "nonimmediate_operand" "")
12869 (plus:SI (match_dup 1)
12870 (const_int -1)))
12871 (clobber (match_scratch:SI 3 ""))
12872 (clobber (reg:CC 17))]
12873 "TARGET_USE_LOOP && !TARGET_64BIT
12874 && reload_completed
12875 && (! REG_P (operands[2])
12876 || ! rtx_equal_p (operands[1], operands[2]))"
12877 [(set (match_dup 3) (match_dup 1))
12878 (parallel [(set (reg:CCZ 17)
12879 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
12880 (const_int 0)))
12881 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
12882 (set (match_dup 2) (match_dup 3))
12883 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
12884 (match_dup 0)
12885 (pc)))]
12886 "")
12887 \f
12888 ;; Call instructions.
12889
12890 ;; The predicates normally associated with named expanders are not properly
12891 ;; checked for calls. This is a bug in the generic code, but it isn't that
12892 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12893
12894 ;; Call subroutine returning no value.
12895
12896 (define_expand "call_pop"
12897 [(parallel [(call (match_operand:QI 0 "" "")
12898 (match_operand:SI 1 "" ""))
12899 (set (reg:SI 7)
12900 (plus:SI (reg:SI 7)
12901 (match_operand:SI 3 "" "")))])]
12902 "!TARGET_64BIT"
12903 "
12904 {
12905 if (operands[3] == const0_rtx)
12906 {
12907 emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
12908 DONE;
12909 }
12910 /* Static functions and indirect calls don't need
12911 current_function_uses_pic_offset_table. */
12912 if (flag_pic
12913 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
12914 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
12915 current_function_uses_pic_offset_table = 1;
12916 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
12917 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
12918 if (TARGET_64BIT)
12919 abort();
12920 }")
12921
12922 (define_insn "*call_pop_0"
12923 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
12924 (match_operand:SI 1 "" ""))
12925 (set (reg:SI 7) (plus:SI (reg:SI 7)
12926 (match_operand:SI 2 "immediate_operand" "")))]
12927 "!TARGET_64BIT"
12928 "*
12929 {
12930 if (SIBLING_CALL_P (insn))
12931 return \"jmp\\t%P0\";
12932 else
12933 return \"call\\t%P0\";
12934 }"
12935 [(set_attr "type" "call")])
12936
12937 (define_insn "*call_pop_1"
12938 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
12939 (match_operand:SI 1 "" ""))
12940 (set (reg:SI 7) (plus:SI (reg:SI 7)
12941 (match_operand:SI 2 "immediate_operand" "i")))]
12942 "!TARGET_64BIT"
12943 "*
12944 {
12945 if (constant_call_address_operand (operands[0], Pmode))
12946 {
12947 if (SIBLING_CALL_P (insn))
12948 return \"jmp\\t%P0\";
12949 else
12950 return \"call\\t%P0\";
12951 }
12952 if (SIBLING_CALL_P (insn))
12953 return \"jmp\\t%A0\";
12954 else
12955 return \"call\\t%A0\";
12956 }"
12957 [(set_attr "type" "call")])
12958
12959 (define_expand "call"
12960 [(call (match_operand:QI 0 "" "")
12961 (match_operand 1 "" ""))
12962 (use (match_operand 2 "" ""))]
12963 ;; Operand 1 not used on the i386.
12964 ""
12965 "
12966 {
12967 rtx insn;
12968 /* Static functions and indirect calls don't need
12969 current_function_uses_pic_offset_table. */
12970 if (flag_pic
12971 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
12972 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
12973 current_function_uses_pic_offset_table = 1;
12974
12975 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
12976 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
12977 if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
12978 {
12979 rtx reg = gen_rtx_REG (QImode, 0);
12980 emit_move_insn (reg, operands[2]);
12981 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
12982 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
12983 DONE;
12984 }
12985 insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
12986 DONE;
12987 }")
12988
12989 (define_expand "call_exp"
12990 [(call (match_operand:QI 0 "" "")
12991 (match_operand 1 "" ""))]
12992 ""
12993 "")
12994
12995 (define_insn "*call_0"
12996 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
12997 (match_operand 1 "" ""))]
12998 ""
12999 "*
13000 {
13001 if (SIBLING_CALL_P (insn))
13002 return \"jmp\\t%P0\";
13003 else
13004 return \"call\\t%P0\";
13005 }"
13006 [(set_attr "type" "call")])
13007
13008 (define_insn "*call_1"
13009 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13010 (match_operand 1 "" ""))]
13011 "!TARGET_64BIT"
13012 "*
13013 {
13014 if (constant_call_address_operand (operands[0], QImode))
13015 {
13016 if (SIBLING_CALL_P (insn))
13017 return \"jmp\\t%P0\";
13018 else
13019 return \"call\\t%P0\";
13020 }
13021 if (SIBLING_CALL_P (insn))
13022 return \"jmp\\t%A0\";
13023 else
13024 return \"call\\t%A0\";
13025 }"
13026 [(set_attr "type" "call")])
13027
13028 (define_insn "*call_1_rex64"
13029 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13030 (match_operand 1 "" ""))]
13031 "TARGET_64BIT"
13032 "*
13033 {
13034 if (constant_call_address_operand (operands[0], QImode))
13035 {
13036 if (SIBLING_CALL_P (insn))
13037 return \"jmp\\t%P0\";
13038 else
13039 return \"call\\t%P0\";
13040 }
13041 if (SIBLING_CALL_P (insn))
13042 return \"jmp\\t%A0\";
13043 else
13044 return \"call\\t%A0\";
13045 }"
13046 [(set_attr "type" "call")])
13047
13048 ;; Call subroutine, returning value in operand 0
13049 ;; (which must be a hard register).
13050
13051 (define_expand "call_value_pop"
13052 [(parallel [(set (match_operand 0 "" "")
13053 (call (match_operand:QI 1 "" "")
13054 (match_operand:SI 2 "" "")))
13055 (set (reg:SI 7)
13056 (plus:SI (reg:SI 7)
13057 (match_operand:SI 4 "" "")))])]
13058 "!TARGET_64BIT"
13059 "
13060 {
13061 if (operands[4] == const0_rtx)
13062 {
13063 emit_insn (gen_call_value (operands[0], operands[1], operands[2],
13064 constm1_rtx));
13065 DONE;
13066 }
13067 /* Static functions and indirect calls don't need
13068 current_function_uses_pic_offset_table. */
13069 if (flag_pic
13070 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13071 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13072 current_function_uses_pic_offset_table = 1;
13073 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13074 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13075 }")
13076
13077 (define_expand "call_value"
13078 [(set (match_operand 0 "" "")
13079 (call (match_operand:QI 1 "" "")
13080 (match_operand:SI 2 "" "")))
13081 (use (match_operand:SI 3 "" ""))]
13082 ;; Operand 2 not used on the i386.
13083 ""
13084 "
13085 {
13086 rtx insn;
13087 /* Static functions and indirect calls don't need
13088 current_function_uses_pic_offset_table. */
13089 if (flag_pic
13090 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
13091 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
13092 current_function_uses_pic_offset_table = 1;
13093 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
13094 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
13095 if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
13096 {
13097 rtx reg = gen_rtx_REG (QImode, 0);
13098 emit_move_insn (reg, operands[3]);
13099 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13100 operands[2]));
13101 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
13102 DONE;
13103 }
13104 insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
13105 operands[2]));
13106 DONE;
13107 }")
13108
13109 (define_expand "call_value_exp"
13110 [(set (match_operand 0 "" "")
13111 (call (match_operand:QI 1 "" "")
13112 (match_operand:SI 2 "" "")))]
13113 ""
13114 "")
13115
13116 ;; Call subroutine returning any type.
13117
13118 (define_expand "untyped_call"
13119 [(parallel [(call (match_operand 0 "" "")
13120 (const_int 0))
13121 (match_operand 1 "" "")
13122 (match_operand 2 "" "")])]
13123 ""
13124 "
13125 {
13126 int i;
13127
13128 /* In order to give reg-stack an easier job in validating two
13129 coprocessor registers as containing a possible return value,
13130 simply pretend the untyped call returns a complex long double
13131 value. */
13132
13133 emit_call_insn (TARGET_80387
13134 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
13135 operands[0], const0_rtx,
13136 GEN_INT (SSE_REGPARM_MAX - 1))
13137 : gen_call (operands[0], const0_rtx,
13138 GEN_INT (SSE_REGPARM_MAX - 1)));
13139
13140 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13141 {
13142 rtx set = XVECEXP (operands[2], 0, i);
13143 emit_move_insn (SET_DEST (set), SET_SRC (set));
13144 }
13145
13146 /* The optimizer does not know that the call sets the function value
13147 registers we stored in the result block. We avoid problems by
13148 claiming that all hard registers are used and clobbered at this
13149 point. */
13150 emit_insn (gen_blockage ());
13151
13152 DONE;
13153 }")
13154 \f
13155 ;; Prologue and epilogue instructions
13156
13157 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13158 ;; all of memory. This blocks insns from being moved across this point.
13159
13160 (define_insn "blockage"
13161 [(unspec_volatile [(const_int 0)] 0)]
13162 ""
13163 ""
13164 [(set_attr "length" "0")])
13165
13166 ;; Insn emitted into the body of a function to return from a function.
13167 ;; This is only done if the function's epilogue is known to be simple.
13168 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13169
13170 (define_expand "return"
13171 [(return)]
13172 "ix86_can_use_return_insn_p ()"
13173 "
13174 {
13175 if (current_function_pops_args)
13176 {
13177 rtx popc = GEN_INT (current_function_pops_args);
13178 emit_jump_insn (gen_return_pop_internal (popc));
13179 DONE;
13180 }
13181 }")
13182
13183 (define_insn "return_internal"
13184 [(return)]
13185 "reload_completed"
13186 "ret"
13187 [(set_attr "length" "1")
13188 (set_attr "length_immediate" "0")
13189 (set_attr "modrm" "0")])
13190
13191 (define_insn "return_pop_internal"
13192 [(return)
13193 (use (match_operand:SI 0 "const_int_operand" ""))]
13194 "reload_completed"
13195 "ret\\t%0"
13196 [(set_attr "length" "3")
13197 (set_attr "length_immediate" "2")
13198 (set_attr "modrm" "0")])
13199
13200 (define_insn "return_indirect_internal"
13201 [(return)
13202 (use (match_operand:SI 0 "register_operand" "r"))]
13203 "reload_completed"
13204 "jmp\\t%A0"
13205 [(set_attr "type" "ibr")
13206 (set_attr "length_immediate" "0")])
13207
13208 (define_insn "nop"
13209 [(const_int 0)]
13210 ""
13211 "nop"
13212 [(set_attr "length" "1")
13213 (set_attr "length_immediate" "0")
13214 (set_attr "modrm" "0")
13215 (set_attr "ppro_uops" "one")])
13216
13217 (define_expand "prologue"
13218 [(const_int 1)]
13219 ""
13220 "ix86_expand_prologue (); DONE;")
13221
13222 (define_insn "prologue_set_got"
13223 [(set (match_operand:SI 0 "register_operand" "=r")
13224 (unspec_volatile:SI
13225 [(plus:SI (match_dup 0)
13226 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
13227 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
13228 (clobber (reg:CC 17))]
13229 "!TARGET_64BIT"
13230 "*
13231 {
13232 if (GET_CODE (operands[2]) == LABEL_REF)
13233 operands[2] = XEXP (operands[2], 0);
13234 if (TARGET_DEEP_BRANCH_PREDICTION)
13235 return \"add{l}\\t{%1, %0|%0, %1}\";
13236 else
13237 return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
13238 }"
13239 [(set_attr "type" "alu")
13240 ; Since this insn may have two constant operands, we must set the
13241 ; length manually.
13242 (set_attr "length_immediate" "4")
13243 (set_attr "mode" "SI")])
13244
13245 (define_insn "prologue_get_pc"
13246 [(set (match_operand:SI 0 "register_operand" "=r")
13247 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
13248 "!TARGET_64BIT"
13249 "*
13250 {
13251 if (GET_CODE (operands[1]) == LABEL_REF)
13252 operands[1] = XEXP (operands[1], 0);
13253 output_asm_insn (\"call\\t%X1\", operands);
13254 if (! TARGET_DEEP_BRANCH_PREDICTION)
13255 {
13256 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
13257 CODE_LABEL_NUMBER (operands[1]));
13258 }
13259 RET;
13260 }"
13261 [(set_attr "type" "multi")])
13262
13263 (define_expand "epilogue"
13264 [(const_int 1)]
13265 ""
13266 "ix86_expand_epilogue (1); DONE;")
13267
13268 (define_expand "sibcall_epilogue"
13269 [(const_int 1)]
13270 ""
13271 "ix86_expand_epilogue (0); DONE;")
13272
13273 (define_expand "eh_return"
13274 [(use (match_operand 0 "register_operand" ""))
13275 (use (match_operand 1 "register_operand" ""))]
13276 ""
13277 "
13278 {
13279 rtx tmp, sa = operands[0], ra = operands[1];
13280
13281 /* Tricky bit: we write the address of the handler to which we will
13282 be returning into someone else's stack frame, one word below the
13283 stack address we wish to restore. */
13284 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13285 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13286 tmp = gen_rtx_MEM (Pmode, tmp);
13287 emit_move_insn (tmp, ra);
13288
13289 emit_insn (gen_eh_return_1 (sa));
13290 emit_barrier ();
13291 DONE;
13292 }")
13293
13294 (define_insn_and_split "eh_return_1"
13295 [(unspec_volatile [(match_operand 0 "register_operand" "c")] 13)]
13296 ""
13297 "#"
13298 "reload_completed"
13299 [(const_int 1)]
13300 "ix86_expand_epilogue (2); DONE;")
13301
13302 (define_insn "leave"
13303 [(set (reg:SI 7) (reg:SI 6))
13304 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
13305 "!TARGET_64BIT"
13306 "leave"
13307 [(set_attr "length_immediate" "0")
13308 (set_attr "length" "1")
13309 (set_attr "modrm" "0")
13310 (set_attr "modrm" "0")
13311 (set_attr "athlon_decode" "vector")
13312 (set_attr "ppro_uops" "few")])
13313
13314 (define_insn "leave_rex64"
13315 [(set (reg:DI 7) (reg:DI 6))
13316 (set (reg:DI 6) (mem:DI (pre_dec:DI (reg:DI 7))))]
13317 "TARGET_64BIT"
13318 "leave"
13319 [(set_attr "length_immediate" "0")
13320 (set_attr "length" "1")
13321 (set_attr "modrm" "0")
13322 (set_attr "modrm" "0")
13323 (set_attr "athlon_decode" "vector")
13324 (set_attr "ppro_uops" "few")])
13325 \f
13326 (define_expand "ffssi2"
13327 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13328 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
13329 ""
13330 "
13331 {
13332 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
13333 rtx in = operands[1];
13334
13335 if (TARGET_CMOVE)
13336 {
13337 emit_move_insn (tmp, constm1_rtx);
13338 emit_insn (gen_ffssi_1 (out, in));
13339 emit_insn (gen_rtx_SET (VOIDmode, out,
13340 gen_rtx_IF_THEN_ELSE (SImode,
13341 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
13342 const0_rtx),
13343 tmp,
13344 out)));
13345 emit_insn (gen_addsi3 (out, out, const1_rtx));
13346 emit_move_insn (operands[0], out);
13347 }
13348
13349 /* Pentium bsf instruction is extremly slow. The following code is
13350 recommended by the Intel Optimizing Manual as a reasonable replacement:
13351 TEST EAX,EAX
13352 JZ SHORT BS2
13353 XOR ECX,ECX
13354 MOV DWORD PTR [TEMP+4],ECX
13355 SUB ECX,EAX
13356 AND EAX,ECX
13357 MOV DWORD PTR [TEMP],EAX
13358 FILD QWORD PTR [TEMP]
13359 FSTP QWORD PTR [TEMP]
13360 WAIT ; WAIT only needed for compatibility with
13361 ; earlier processors
13362 MOV ECX, DWORD PTR [TEMP+4]
13363 SHR ECX,20
13364 SUB ECX,3FFH
13365 TEST EAX,EAX ; clear zero flag
13366 BS2:
13367 Following piece of code expand ffs to similar beast.
13368 */
13369
13370 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
13371 {
13372 rtx label = gen_label_rtx ();
13373 rtx lo, hi;
13374 rtx mem = assign_386_stack_local (DImode, 0);
13375 rtx fptmp = gen_reg_rtx (DFmode);
13376 split_di (&mem, 1, &lo, &hi);
13377
13378 emit_move_insn (out, const0_rtx);
13379
13380 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
13381
13382 emit_move_insn (hi, out);
13383 emit_insn (gen_subsi3 (out, out, in));
13384 emit_insn (gen_andsi3 (out, out, in));
13385 emit_move_insn (lo, out);
13386 emit_insn (gen_floatdidf2 (fptmp,mem));
13387 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
13388 emit_move_insn (out, hi);
13389 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
13390 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
13391
13392 emit_label (label);
13393 LABEL_NUSES (label) = 1;
13394
13395 emit_move_insn (operands[0], out);
13396 }
13397 else
13398 {
13399 emit_move_insn (tmp, const0_rtx);
13400 emit_insn (gen_ffssi_1 (out, in));
13401 emit_insn (gen_rtx_SET (VOIDmode,
13402 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
13403 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
13404 const0_rtx)));
13405 emit_insn (gen_negsi2 (tmp, tmp));
13406 emit_insn (gen_iorsi3 (out, out, tmp));
13407 emit_insn (gen_addsi3 (out, out, const1_rtx));
13408 emit_move_insn (operands[0], out);
13409 }
13410 DONE;
13411 }")
13412
13413 (define_insn "ffssi_1"
13414 [(set (reg:CCZ 17)
13415 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13416 (const_int 0)))
13417 (set (match_operand:SI 0 "register_operand" "=r")
13418 (unspec:SI [(match_dup 1)] 5))]
13419 ""
13420 "bsf{l}\\t{%1, %0|%0, %1}"
13421 [(set_attr "prefix_0f" "1")
13422 (set_attr "ppro_uops" "few")])
13423
13424 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
13425 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
13426 \f
13427 ;; These patterns match the binary 387 instructions for addM3, subM3,
13428 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13429 ;; SFmode. The first is the normal insn, the second the same insn but
13430 ;; with one operand a conversion, and the third the same insn but with
13431 ;; the other operand a conversion. The conversion may be SFmode or
13432 ;; SImode if the target mode DFmode, but only SImode if the target mode
13433 ;; is SFmode.
13434
13435 ;; Gcc is slightly more smart about handling normal two address instructions
13436 ;; so use special patterns for add and mull.
13437 (define_insn "*fop_sf_comm"
13438 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13439 (match_operator:SF 3 "binary_fp_operator"
13440 [(match_operand:SF 1 "register_operand" "%0,0")
13441 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13442 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
13443 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13444 "* return output_387_binary_op (insn, operands);"
13445 [(set (attr "type")
13446 (if_then_else (eq_attr "alternative" "1")
13447 (const_string "sse")
13448 (if_then_else (match_operand:SF 3 "mult_operator" "")
13449 (const_string "fmul")
13450 (const_string "fop"))))
13451 (set_attr "mode" "SF")])
13452
13453 (define_insn "*fop_sf_comm_sse"
13454 [(set (match_operand:SF 0 "register_operand" "=x")
13455 (match_operator:SF 3 "binary_fp_operator"
13456 [(match_operand:SF 1 "register_operand" "%0")
13457 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13458 "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13459 "* return output_387_binary_op (insn, operands);"
13460 [(set_attr "type" "sse")
13461 (set_attr "mode" "SF")])
13462
13463 (define_insn "*fop_df_comm"
13464 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
13465 (match_operator:DF 3 "binary_fp_operator"
13466 [(match_operand:DF 1 "register_operand" "%0,0")
13467 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
13468 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
13469 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13470 "* return output_387_binary_op (insn, operands);"
13471 [(set (attr "type")
13472 (if_then_else (eq_attr "alternative" "1")
13473 (const_string "sse")
13474 (if_then_else (match_operand:SF 3 "mult_operator" "")
13475 (const_string "fmul")
13476 (const_string "fop"))))
13477 (set_attr "mode" "DF")])
13478
13479 (define_insn "*fop_df_comm_sse"
13480 [(set (match_operand:DF 0 "register_operand" "=Y")
13481 (match_operator:DF 3 "binary_fp_operator"
13482 [(match_operand:DF 1 "register_operand" "%0")
13483 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13484 "TARGET_SSE2
13485 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13486 "* return output_387_binary_op (insn, operands);"
13487 [(set_attr "type" "sse")
13488 (set_attr "mode" "DF")])
13489
13490 (define_insn "*fop_xf_comm"
13491 [(set (match_operand:XF 0 "register_operand" "=f")
13492 (match_operator:XF 3 "binary_fp_operator"
13493 [(match_operand:XF 1 "register_operand" "%0")
13494 (match_operand:XF 2 "register_operand" "f")]))]
13495 "TARGET_80387 && !TARGET_64BIT
13496 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13497 "* return output_387_binary_op (insn, operands);"
13498 [(set (attr "type")
13499 (if_then_else (match_operand:XF 3 "mult_operator" "")
13500 (const_string "fmul")
13501 (const_string "fop")))
13502 (set_attr "mode" "XF")])
13503
13504 (define_insn "*fop_tf_comm"
13505 [(set (match_operand:TF 0 "register_operand" "=f")
13506 (match_operator:TF 3 "binary_fp_operator"
13507 [(match_operand:TF 1 "register_operand" "%0")
13508 (match_operand:TF 2 "register_operand" "f")]))]
13509 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
13510 "* return output_387_binary_op (insn, operands);"
13511 [(set (attr "type")
13512 (if_then_else (match_operand:TF 3 "mult_operator" "")
13513 (const_string "fmul")
13514 (const_string "fop")))
13515 (set_attr "mode" "XF")])
13516
13517 (define_insn "*fop_sf_1"
13518 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13519 (match_operator:SF 3 "binary_fp_operator"
13520 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13521 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13522 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
13523 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13524 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13525 "* return output_387_binary_op (insn, operands);"
13526 [(set (attr "type")
13527 (cond [(eq_attr "alternative" "2")
13528 (const_string "sse")
13529 (match_operand:SF 3 "mult_operator" "")
13530 (const_string "fmul")
13531 (match_operand:SF 3 "div_operator" "")
13532 (const_string "fdiv")
13533 ]
13534 (const_string "fop")))
13535 (set_attr "mode" "SF")])
13536
13537 (define_insn "*fop_sf_1_sse"
13538 [(set (match_operand:SF 0 "register_operand" "=x")
13539 (match_operator:SF 3 "binary_fp_operator"
13540 [(match_operand:SF 1 "register_operand" "0")
13541 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13542 "TARGET_SSE
13543 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13544 "* return output_387_binary_op (insn, operands);"
13545 [(set_attr "type" "sse")
13546 (set_attr "mode" "SF")])
13547
13548 ;; ??? Add SSE splitters for these!
13549 (define_insn "*fop_sf_2"
13550 [(set (match_operand:SF 0 "register_operand" "=f,f")
13551 (match_operator:SF 3 "binary_fp_operator"
13552 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13553 (match_operand:SF 2 "register_operand" "0,0")]))]
13554 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
13555 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13556 [(set (attr "type")
13557 (cond [(match_operand:SF 3 "mult_operator" "")
13558 (const_string "fmul")
13559 (match_operand:SF 3 "div_operator" "")
13560 (const_string "fdiv")
13561 ]
13562 (const_string "fop")))
13563 (set_attr "fp_int_src" "true")
13564 (set_attr "ppro_uops" "many")
13565 (set_attr "mode" "SI")])
13566
13567 (define_insn "*fop_sf_3"
13568 [(set (match_operand:SF 0 "register_operand" "=f,f")
13569 (match_operator:SF 3 "binary_fp_operator"
13570 [(match_operand:SF 1 "register_operand" "0,0")
13571 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13572 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
13573 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13574 [(set (attr "type")
13575 (cond [(match_operand:SF 3 "mult_operator" "")
13576 (const_string "fmul")
13577 (match_operand:SF 3 "div_operator" "")
13578 (const_string "fdiv")
13579 ]
13580 (const_string "fop")))
13581 (set_attr "fp_int_src" "true")
13582 (set_attr "ppro_uops" "many")
13583 (set_attr "mode" "SI")])
13584
13585 (define_insn "*fop_df_1"
13586 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
13587 (match_operator:DF 3 "binary_fp_operator"
13588 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
13589 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
13590 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
13591 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
13592 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13593 "* return output_387_binary_op (insn, operands);"
13594 [(set (attr "type")
13595 (cond [(eq_attr "alternative" "2")
13596 (const_string "sse")
13597 (match_operand:DF 3 "mult_operator" "")
13598 (const_string "fmul")
13599 (match_operand:DF 3 "div_operator" "")
13600 (const_string "fdiv")
13601 ]
13602 (const_string "fop")))
13603 (set_attr "mode" "DF")])
13604
13605 (define_insn "*fop_df_1_sse"
13606 [(set (match_operand:DF 0 "register_operand" "=Y")
13607 (match_operator:DF 3 "binary_fp_operator"
13608 [(match_operand:DF 1 "register_operand" "0")
13609 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
13610 "TARGET_SSE
13611 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13612 "* return output_387_binary_op (insn, operands);"
13613 [(set_attr "type" "sse")])
13614
13615 ;; ??? Add SSE splitters for these!
13616 (define_insn "*fop_df_2"
13617 [(set (match_operand:DF 0 "register_operand" "=f,f")
13618 (match_operator:DF 3 "binary_fp_operator"
13619 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13620 (match_operand:DF 2 "register_operand" "0,0")]))]
13621 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
13622 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13623 [(set (attr "type")
13624 (cond [(match_operand:DF 3 "mult_operator" "")
13625 (const_string "fmul")
13626 (match_operand:DF 3 "div_operator" "")
13627 (const_string "fdiv")
13628 ]
13629 (const_string "fop")))
13630 (set_attr "fp_int_src" "true")
13631 (set_attr "ppro_uops" "many")
13632 (set_attr "mode" "SI")])
13633
13634 (define_insn "*fop_df_3"
13635 [(set (match_operand:DF 0 "register_operand" "=f,f")
13636 (match_operator:DF 3 "binary_fp_operator"
13637 [(match_operand:DF 1 "register_operand" "0,0")
13638 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13639 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
13640 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13641 [(set (attr "type")
13642 (cond [(match_operand:DF 3 "mult_operator" "")
13643 (const_string "fmul")
13644 (match_operand:DF 3 "div_operator" "")
13645 (const_string "fdiv")
13646 ]
13647 (const_string "fop")))
13648 (set_attr "fp_int_src" "true")
13649 (set_attr "ppro_uops" "many")
13650 (set_attr "mode" "SI")])
13651
13652 (define_insn "*fop_df_4"
13653 [(set (match_operand:DF 0 "register_operand" "=f,f")
13654 (match_operator:DF 3 "binary_fp_operator"
13655 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13656 (match_operand:DF 2 "register_operand" "0,f")]))]
13657 "TARGET_80387
13658 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13659 "* return output_387_binary_op (insn, operands);"
13660 [(set (attr "type")
13661 (cond [(match_operand:DF 3 "mult_operator" "")
13662 (const_string "fmul")
13663 (match_operand:DF 3 "div_operator" "")
13664 (const_string "fdiv")
13665 ]
13666 (const_string "fop")))
13667 (set_attr "mode" "SF")])
13668
13669 (define_insn "*fop_df_5"
13670 [(set (match_operand:DF 0 "register_operand" "=f,f")
13671 (match_operator:DF 3 "binary_fp_operator"
13672 [(match_operand:DF 1 "register_operand" "0,f")
13673 (float_extend:DF
13674 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13675 "TARGET_80387 && !TARGET_SSE2"
13676 "* return output_387_binary_op (insn, operands);"
13677 [(set (attr "type")
13678 (cond [(match_operand:DF 3 "mult_operator" "")
13679 (const_string "fmul")
13680 (match_operand:DF 3 "div_operator" "")
13681 (const_string "fdiv")
13682 ]
13683 (const_string "fop")))
13684 (set_attr "mode" "SF")])
13685
13686 (define_insn "*fop_xf_1"
13687 [(set (match_operand:XF 0 "register_operand" "=f,f")
13688 (match_operator:XF 3 "binary_fp_operator"
13689 [(match_operand:XF 1 "register_operand" "0,f")
13690 (match_operand:XF 2 "register_operand" "f,0")]))]
13691 "TARGET_80387 && !TARGET_64BIT
13692 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13693 "* return output_387_binary_op (insn, operands);"
13694 [(set (attr "type")
13695 (cond [(match_operand:XF 3 "mult_operator" "")
13696 (const_string "fmul")
13697 (match_operand:XF 3 "div_operator" "")
13698 (const_string "fdiv")
13699 ]
13700 (const_string "fop")))
13701 (set_attr "mode" "XF")])
13702
13703 (define_insn "*fop_tf_1"
13704 [(set (match_operand:TF 0 "register_operand" "=f,f")
13705 (match_operator:TF 3 "binary_fp_operator"
13706 [(match_operand:TF 1 "register_operand" "0,f")
13707 (match_operand:TF 2 "register_operand" "f,0")]))]
13708 "TARGET_80387
13709 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
13710 "* return output_387_binary_op (insn, operands);"
13711 [(set (attr "type")
13712 (cond [(match_operand:TF 3 "mult_operator" "")
13713 (const_string "fmul")
13714 (match_operand:TF 3 "div_operator" "")
13715 (const_string "fdiv")
13716 ]
13717 (const_string "fop")))
13718 (set_attr "mode" "XF")])
13719
13720 (define_insn "*fop_xf_2"
13721 [(set (match_operand:XF 0 "register_operand" "=f,f")
13722 (match_operator:XF 3 "binary_fp_operator"
13723 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13724 (match_operand:XF 2 "register_operand" "0,0")]))]
13725 "TARGET_80387 && !TARGET_64BIT && TARGET_USE_FIOP"
13726 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13727 [(set (attr "type")
13728 (cond [(match_operand:XF 3 "mult_operator" "")
13729 (const_string "fmul")
13730 (match_operand:XF 3 "div_operator" "")
13731 (const_string "fdiv")
13732 ]
13733 (const_string "fop")))
13734 (set_attr "fp_int_src" "true")
13735 (set_attr "mode" "SI")
13736 (set_attr "ppro_uops" "many")])
13737
13738 (define_insn "*fop_tf_2"
13739 [(set (match_operand:TF 0 "register_operand" "=f,f")
13740 (match_operator:TF 3 "binary_fp_operator"
13741 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
13742 (match_operand:TF 2 "register_operand" "0,0")]))]
13743 "TARGET_80387 && TARGET_USE_FIOP"
13744 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13745 [(set (attr "type")
13746 (cond [(match_operand:TF 3 "mult_operator" "")
13747 (const_string "fmul")
13748 (match_operand:TF 3 "div_operator" "")
13749 (const_string "fdiv")
13750 ]
13751 (const_string "fop")))
13752 (set_attr "fp_int_src" "true")
13753 (set_attr "mode" "SI")
13754 (set_attr "ppro_uops" "many")])
13755
13756 (define_insn "*fop_xf_3"
13757 [(set (match_operand:XF 0 "register_operand" "=f,f")
13758 (match_operator:XF 3 "binary_fp_operator"
13759 [(match_operand:XF 1 "register_operand" "0,0")
13760 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13761 "TARGET_80387 && !TARGET_64BIT && TARGET_USE_FIOP"
13762 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13763 [(set (attr "type")
13764 (cond [(match_operand:XF 3 "mult_operator" "")
13765 (const_string "fmul")
13766 (match_operand:XF 3 "div_operator" "")
13767 (const_string "fdiv")
13768 ]
13769 (const_string "fop")))
13770 (set_attr "fp_int_src" "true")
13771 (set_attr "mode" "SI")
13772 (set_attr "ppro_uops" "many")])
13773
13774 (define_insn "*fop_tf_3"
13775 [(set (match_operand:TF 0 "register_operand" "=f,f")
13776 (match_operator:TF 3 "binary_fp_operator"
13777 [(match_operand:TF 1 "register_operand" "0,0")
13778 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
13779 "TARGET_80387 && TARGET_USE_FIOP"
13780 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13781 [(set (attr "type")
13782 (cond [(match_operand:TF 3 "mult_operator" "")
13783 (const_string "fmul")
13784 (match_operand:TF 3 "div_operator" "")
13785 (const_string "fdiv")
13786 ]
13787 (const_string "fop")))
13788 (set_attr "fp_int_src" "true")
13789 (set_attr "mode" "SI")
13790 (set_attr "ppro_uops" "many")])
13791
13792 (define_insn "*fop_xf_4"
13793 [(set (match_operand:XF 0 "register_operand" "=f,f")
13794 (match_operator:XF 3 "binary_fp_operator"
13795 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13796 (match_operand:XF 2 "register_operand" "0,f")]))]
13797 "TARGET_80387 && !TARGET_64BIT"
13798 "* return output_387_binary_op (insn, operands);"
13799 [(set (attr "type")
13800 (cond [(match_operand:XF 3 "mult_operator" "")
13801 (const_string "fmul")
13802 (match_operand:XF 3 "div_operator" "")
13803 (const_string "fdiv")
13804 ]
13805 (const_string "fop")))
13806 (set_attr "mode" "SF")])
13807
13808 (define_insn "*fop_tf_4"
13809 [(set (match_operand:TF 0 "register_operand" "=f,f")
13810 (match_operator:TF 3 "binary_fp_operator"
13811 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13812 (match_operand:TF 2 "register_operand" "0,f")]))]
13813 "TARGET_80387"
13814 "* return output_387_binary_op (insn, operands);"
13815 [(set (attr "type")
13816 (cond [(match_operand:TF 3 "mult_operator" "")
13817 (const_string "fmul")
13818 (match_operand:TF 3 "div_operator" "")
13819 (const_string "fdiv")
13820 ]
13821 (const_string "fop")))
13822 (set_attr "mode" "SF")])
13823
13824 (define_insn "*fop_xf_5"
13825 [(set (match_operand:XF 0 "register_operand" "=f,f")
13826 (match_operator:XF 3 "binary_fp_operator"
13827 [(match_operand:XF 1 "register_operand" "0,f")
13828 (float_extend:XF
13829 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13830 "TARGET_80387 && !TARGET_64BIT"
13831 "* return output_387_binary_op (insn, operands);"
13832 [(set (attr "type")
13833 (cond [(match_operand:XF 3 "mult_operator" "")
13834 (const_string "fmul")
13835 (match_operand:XF 3 "div_operator" "")
13836 (const_string "fdiv")
13837 ]
13838 (const_string "fop")))
13839 (set_attr "mode" "SF")])
13840
13841 (define_insn "*fop_tf_5"
13842 [(set (match_operand:TF 0 "register_operand" "=f,f")
13843 (match_operator:TF 3 "binary_fp_operator"
13844 [(match_operand:TF 1 "register_operand" "0,f")
13845 (float_extend:TF
13846 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13847 "TARGET_80387"
13848 "* return output_387_binary_op (insn, operands);"
13849 [(set (attr "type")
13850 (cond [(match_operand:TF 3 "mult_operator" "")
13851 (const_string "fmul")
13852 (match_operand:TF 3 "div_operator" "")
13853 (const_string "fdiv")
13854 ]
13855 (const_string "fop")))
13856 (set_attr "mode" "SF")])
13857
13858 (define_insn "*fop_xf_6"
13859 [(set (match_operand:XF 0 "register_operand" "=f,f")
13860 (match_operator:XF 3 "binary_fp_operator"
13861 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
13862 (match_operand:XF 2 "register_operand" "0,f")]))]
13863 "TARGET_80387 && !TARGET_64BIT"
13864 "* return output_387_binary_op (insn, operands);"
13865 [(set (attr "type")
13866 (cond [(match_operand:XF 3 "mult_operator" "")
13867 (const_string "fmul")
13868 (match_operand:XF 3 "div_operator" "")
13869 (const_string "fdiv")
13870 ]
13871 (const_string "fop")))
13872 (set_attr "mode" "DF")])
13873
13874 (define_insn "*fop_tf_6"
13875 [(set (match_operand:TF 0 "register_operand" "=f,f")
13876 (match_operator:TF 3 "binary_fp_operator"
13877 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
13878 (match_operand:TF 2 "register_operand" "0,f")]))]
13879 "TARGET_80387"
13880 "* return output_387_binary_op (insn, operands);"
13881 [(set (attr "type")
13882 (cond [(match_operand:TF 3 "mult_operator" "")
13883 (const_string "fmul")
13884 (match_operand:TF 3 "div_operator" "")
13885 (const_string "fdiv")
13886 ]
13887 (const_string "fop")))
13888 (set_attr "mode" "DF")])
13889
13890 (define_insn "*fop_xf_7"
13891 [(set (match_operand:XF 0 "register_operand" "=f,f")
13892 (match_operator:XF 3 "binary_fp_operator"
13893 [(match_operand:XF 1 "register_operand" "0,f")
13894 (float_extend:XF
13895 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
13896 "TARGET_80387 && !TARGET_64BIT"
13897 "* return output_387_binary_op (insn, operands);"
13898 [(set (attr "type")
13899 (cond [(match_operand:XF 3 "mult_operator" "")
13900 (const_string "fmul")
13901 (match_operand:XF 3 "div_operator" "")
13902 (const_string "fdiv")
13903 ]
13904 (const_string "fop")))
13905 (set_attr "mode" "DF")])
13906
13907 (define_insn "*fop_tf_7"
13908 [(set (match_operand:TF 0 "register_operand" "=f,f")
13909 (match_operator:TF 3 "binary_fp_operator"
13910 [(match_operand:TF 1 "register_operand" "0,f")
13911 (float_extend:TF
13912 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
13913 "TARGET_80387"
13914 "* return output_387_binary_op (insn, operands);"
13915 [(set (attr "type")
13916 (cond [(match_operand:TF 3 "mult_operator" "")
13917 (const_string "fmul")
13918 (match_operand:TF 3 "div_operator" "")
13919 (const_string "fdiv")
13920 ]
13921 (const_string "fop")))
13922 (set_attr "mode" "DF")])
13923
13924 (define_split
13925 [(set (match_operand 0 "register_operand" "")
13926 (match_operator 3 "binary_fp_operator"
13927 [(float (match_operand:SI 1 "register_operand" ""))
13928 (match_operand 2 "register_operand" "")]))]
13929 "TARGET_80387 && reload_completed
13930 && FLOAT_MODE_P (GET_MODE (operands[0]))"
13931 [(const_int 0)]
13932 "
13933 {
13934 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13935 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13936 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13937 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13938 GET_MODE (operands[3]),
13939 operands[4],
13940 operands[2])));
13941 ix86_free_from_memory (GET_MODE (operands[1]));
13942 DONE;
13943 }")
13944
13945 (define_split
13946 [(set (match_operand 0 "register_operand" "")
13947 (match_operator 3 "binary_fp_operator"
13948 [(match_operand 1 "register_operand" "")
13949 (float (match_operand:SI 2 "register_operand" ""))]))]
13950 "TARGET_80387 && reload_completed
13951 && FLOAT_MODE_P (GET_MODE (operands[0]))"
13952 [(const_int 0)]
13953 "
13954 {
13955 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13956 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13957 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13958 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13959 GET_MODE (operands[3]),
13960 operands[1],
13961 operands[4])));
13962 ix86_free_from_memory (GET_MODE (operands[2]));
13963 DONE;
13964 }")
13965 \f
13966 ;; FPU special functions.
13967
13968 (define_expand "sqrtsf2"
13969 [(set (match_operand:SF 0 "register_operand" "")
13970 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
13971 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE"
13972 "
13973 {
13974 if (!TARGET_SSE)
13975 operands[1] = force_reg (SFmode, operands[1]);
13976 }")
13977
13978 (define_insn "sqrtsf2_1"
13979 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13980 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
13981 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
13982 && (TARGET_SSE && TARGET_MIX_SSE_I387)"
13983 "@
13984 fsqrt
13985 sqrtss\\t{%1, %0|%0, %1}"
13986 [(set_attr "type" "fpspc,sse")
13987 (set_attr "mode" "SF,SF")
13988 (set_attr "athlon_decode" "direct,*")])
13989
13990 (define_insn "sqrtsf2_1_sse_only"
13991 [(set (match_operand:SF 0 "register_operand" "=x")
13992 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
13993 "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
13994 "sqrtss\\t{%1, %0|%0, %1}"
13995 [(set_attr "type" "sse")
13996 (set_attr "mode" "SF")
13997 (set_attr "athlon_decode" "*")])
13998
13999 (define_insn "sqrtsf2_i387"
14000 [(set (match_operand:SF 0 "register_operand" "=f")
14001 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14002 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14003 && (!TARGET_SSE && !TARGET_MIX_SSE_I387)"
14004 "fsqrt"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "SF")
14007 (set_attr "athlon_decode" "direct")])
14008
14009 (define_expand "sqrtdf2"
14010 [(set (match_operand:DF 0 "register_operand" "")
14011 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14012 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
14013 "
14014 {
14015 if (!TARGET_SSE2)
14016 operands[1] = force_reg (SFmode, operands[1]);
14017 }")
14018
14019 (define_insn "sqrtdf2_1"
14020 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14021 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14022 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14023 && (TARGET_SSE2 && TARGET_MIX_SSE_I387)"
14024 "@
14025 fsqrt
14026 sqrtsd\\t{%1, %0|%0, %1}"
14027 [(set_attr "type" "fpspc,sse")
14028 (set_attr "mode" "DF,DF")
14029 (set_attr "athlon_decode" "direct,*")])
14030
14031 (define_insn "sqrtdf2_1_sse_only"
14032 [(set (match_operand:DF 0 "register_operand" "=Y")
14033 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14034 "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14035 "sqrtsd\\t{%1, %0|%0, %1}"
14036 [(set_attr "type" "sse")
14037 (set_attr "mode" "DF")
14038 (set_attr "athlon_decode" "*")])
14039
14040 (define_insn "sqrtdf2_i387"
14041 [(set (match_operand:DF 0 "register_operand" "=f")
14042 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14043 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14044 && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)"
14045 "fsqrt"
14046 [(set_attr "type" "fpspc")
14047 (set_attr "mode" "DF")
14048 (set_attr "athlon_decode" "direct")])
14049
14050 (define_insn "*sqrtextendsfdf2"
14051 [(set (match_operand:DF 0 "register_operand" "=f")
14052 (sqrt:DF (float_extend:DF
14053 (match_operand:SF 1 "register_operand" "0"))))]
14054 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_SSE2"
14055 "fsqrt"
14056 [(set_attr "type" "fpspc")
14057 (set_attr "mode" "DF")
14058 (set_attr "athlon_decode" "direct")])
14059
14060 (define_insn "sqrtxf2"
14061 [(set (match_operand:XF 0 "register_operand" "=f")
14062 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14063 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT
14064 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14065 "fsqrt"
14066 [(set_attr "type" "fpspc")
14067 (set_attr "mode" "XF")
14068 (set_attr "athlon_decode" "direct")])
14069
14070 (define_insn "sqrttf2"
14071 [(set (match_operand:TF 0 "register_operand" "=f")
14072 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
14073 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14074 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14075 "fsqrt"
14076 [(set_attr "type" "fpspc")
14077 (set_attr "mode" "XF")
14078 (set_attr "athlon_decode" "direct")])
14079
14080 (define_insn "*sqrtextenddfxf2"
14081 [(set (match_operand:XF 0 "register_operand" "=f")
14082 (sqrt:XF (float_extend:XF
14083 (match_operand:DF 1 "register_operand" "0"))))]
14084 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT"
14085 "fsqrt"
14086 [(set_attr "type" "fpspc")
14087 (set_attr "mode" "XF")
14088 (set_attr "athlon_decode" "direct")])
14089
14090 (define_insn "*sqrtextenddftf2"
14091 [(set (match_operand:TF 0 "register_operand" "=f")
14092 (sqrt:TF (float_extend:TF
14093 (match_operand:DF 1 "register_operand" "0"))))]
14094 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14095 "fsqrt"
14096 [(set_attr "type" "fpspc")
14097 (set_attr "mode" "XF")
14098 (set_attr "athlon_decode" "direct")])
14099
14100 (define_insn "*sqrtextendsfxf2"
14101 [(set (match_operand:XF 0 "register_operand" "=f")
14102 (sqrt:XF (float_extend:XF
14103 (match_operand:SF 1 "register_operand" "0"))))]
14104 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT"
14105 "fsqrt"
14106 [(set_attr "type" "fpspc")
14107 (set_attr "mode" "XF")
14108 (set_attr "athlon_decode" "direct")])
14109
14110 (define_insn "*sqrtextendsftf2"
14111 [(set (match_operand:TF 0 "register_operand" "=f")
14112 (sqrt:TF (float_extend:TF
14113 (match_operand:SF 1 "register_operand" "0"))))]
14114 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
14115 "fsqrt"
14116 [(set_attr "type" "fpspc")
14117 (set_attr "mode" "XF")
14118 (set_attr "athlon_decode" "direct")])
14119
14120 (define_insn "sindf2"
14121 [(set (match_operand:DF 0 "register_operand" "=f")
14122 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
14123 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14124 && flag_unsafe_math_optimizations"
14125 "fsin"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "DF")])
14128
14129 (define_insn "sinsf2"
14130 [(set (match_operand:SF 0 "register_operand" "=f")
14131 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
14132 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14133 && flag_unsafe_math_optimizations"
14134 "fsin"
14135 [(set_attr "type" "fpspc")
14136 (set_attr "mode" "SF")])
14137
14138 (define_insn "*sinextendsfdf2"
14139 [(set (match_operand:DF 0 "register_operand" "=f")
14140 (unspec:DF [(float_extend:DF
14141 (match_operand:SF 1 "register_operand" "0"))] 1))]
14142 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14143 && flag_unsafe_math_optimizations"
14144 "fsin"
14145 [(set_attr "type" "fpspc")
14146 (set_attr "mode" "DF")])
14147
14148 (define_insn "sinxf2"
14149 [(set (match_operand:XF 0 "register_operand" "=f")
14150 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
14151 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_64BIT
14152 && flag_unsafe_math_optimizations"
14153 "fsin"
14154 [(set_attr "type" "fpspc")
14155 (set_attr "mode" "XF")])
14156
14157 (define_insn "sintf2"
14158 [(set (match_operand:TF 0 "register_operand" "=f")
14159 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
14160 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14161 && flag_unsafe_math_optimizations"
14162 "fsin"
14163 [(set_attr "type" "fpspc")
14164 (set_attr "mode" "XF")])
14165
14166 (define_insn "cosdf2"
14167 [(set (match_operand:DF 0 "register_operand" "=f")
14168 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
14169 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14170 && flag_unsafe_math_optimizations"
14171 "fcos"
14172 [(set_attr "type" "fpspc")
14173 (set_attr "mode" "DF")])
14174
14175 (define_insn "cossf2"
14176 [(set (match_operand:SF 0 "register_operand" "=f")
14177 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
14178 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14179 && flag_unsafe_math_optimizations"
14180 "fcos"
14181 [(set_attr "type" "fpspc")
14182 (set_attr "mode" "SF")])
14183
14184 (define_insn "*cosextendsfdf2"
14185 [(set (match_operand:DF 0 "register_operand" "=f")
14186 (unspec:DF [(float_extend:DF
14187 (match_operand:SF 1 "register_operand" "0"))] 2))]
14188 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14189 && flag_unsafe_math_optimizations"
14190 "fcos"
14191 [(set_attr "type" "fpspc")
14192 (set_attr "mode" "DF")])
14193
14194 (define_insn "cosxf2"
14195 [(set (match_operand:XF 0 "register_operand" "=f")
14196 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
14197 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14198 && flag_unsafe_math_optimizations"
14199 "fcos"
14200 [(set_attr "type" "fpspc")
14201 (set_attr "mode" "XF")])
14202
14203 (define_insn "costf2"
14204 [(set (match_operand:TF 0 "register_operand" "=f")
14205 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
14206 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14207 && flag_unsafe_math_optimizations"
14208 "fcos"
14209 [(set_attr "type" "fpspc")
14210 (set_attr "mode" "XF")])
14211 \f
14212 ;; Block operation instructions
14213
14214 (define_insn "cld"
14215 [(set (reg:SI 19) (const_int 0))]
14216 ""
14217 "cld"
14218 [(set_attr "type" "cld")])
14219
14220 (define_expand "movstrsi"
14221 [(use (match_operand:BLK 0 "memory_operand" ""))
14222 (use (match_operand:BLK 1 "memory_operand" ""))
14223 (use (match_operand:SI 2 "nonmemory_operand" ""))
14224 (use (match_operand:SI 3 "const_int_operand" ""))]
14225 ""
14226 "
14227 {
14228 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14229 DONE;
14230 else
14231 FAIL;
14232 }")
14233
14234 (define_expand "movstrdi"
14235 [(use (match_operand:BLK 0 "memory_operand" ""))
14236 (use (match_operand:BLK 1 "memory_operand" ""))
14237 (use (match_operand:DI 2 "nonmemory_operand" ""))
14238 (use (match_operand:DI 3 "const_int_operand" ""))]
14239 "TARGET_64BIT"
14240 "
14241 {
14242 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
14243 DONE;
14244 else
14245 FAIL;
14246 }")
14247
14248 ;; Most CPUs don't like single string operations
14249 ;; Handle this case here to simplify previous expander.
14250
14251 (define_expand "strmovdi_rex64"
14252 [(set (match_dup 2)
14253 (mem:DI (match_operand:DI 1 "register_operand" "")))
14254 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
14255 (match_dup 2))
14256 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14257 (clobber (reg:CC 17))])
14258 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
14259 (clobber (reg:CC 17))])]
14260 "TARGET_64BIT"
14261 "
14262 {
14263 if (TARGET_SINGLE_STRINGOP || optimize_size)
14264 {
14265 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
14266 operands[1]));
14267 DONE;
14268 }
14269 else
14270 operands[2] = gen_reg_rtx (DImode);
14271 }")
14272
14273
14274 (define_expand "strmovsi"
14275 [(set (match_dup 2)
14276 (mem:SI (match_operand:SI 1 "register_operand" "")))
14277 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
14278 (match_dup 2))
14279 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14280 (clobber (reg:CC 17))])
14281 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
14282 (clobber (reg:CC 17))])]
14283 ""
14284 "
14285 {
14286 if (TARGET_64BIT)
14287 {
14288 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
14289 DONE;
14290 }
14291 if (TARGET_SINGLE_STRINGOP || optimize_size)
14292 {
14293 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
14294 operands[1]));
14295 DONE;
14296 }
14297 else
14298 operands[2] = gen_reg_rtx (SImode);
14299 }")
14300
14301 (define_expand "strmovsi_rex64"
14302 [(set (match_dup 2)
14303 (mem:SI (match_operand:DI 1 "register_operand" "")))
14304 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
14305 (match_dup 2))
14306 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14307 (clobber (reg:CC 17))])
14308 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
14309 (clobber (reg:CC 17))])]
14310 "TARGET_64BIT"
14311 "
14312 {
14313 if (TARGET_SINGLE_STRINGOP || optimize_size)
14314 {
14315 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
14316 operands[1]));
14317 DONE;
14318 }
14319 else
14320 operands[2] = gen_reg_rtx (SImode);
14321 }")
14322
14323 (define_expand "strmovhi"
14324 [(set (match_dup 2)
14325 (mem:HI (match_operand:SI 1 "register_operand" "")))
14326 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
14327 (match_dup 2))
14328 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14329 (clobber (reg:CC 17))])
14330 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
14331 (clobber (reg:CC 17))])]
14332 ""
14333 "
14334 {
14335 if (TARGET_64BIT)
14336 {
14337 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
14338 DONE;
14339 }
14340 if (TARGET_SINGLE_STRINGOP || optimize_size)
14341 {
14342 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
14343 operands[1]));
14344 DONE;
14345 }
14346 else
14347 operands[2] = gen_reg_rtx (HImode);
14348 }")
14349
14350 (define_expand "strmovhi_rex64"
14351 [(set (match_dup 2)
14352 (mem:HI (match_operand:DI 1 "register_operand" "")))
14353 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
14354 (match_dup 2))
14355 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14356 (clobber (reg:CC 17))])
14357 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
14358 (clobber (reg:CC 17))])]
14359 "TARGET_64BIT"
14360 "
14361 {
14362 if (TARGET_SINGLE_STRINGOP || optimize_size)
14363 {
14364 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
14365 operands[1]));
14366 DONE;
14367 }
14368 else
14369 operands[2] = gen_reg_rtx (HImode);
14370 }")
14371
14372 (define_expand "strmovqi"
14373 [(set (match_dup 2)
14374 (mem:QI (match_operand:SI 1 "register_operand" "")))
14375 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
14376 (match_dup 2))
14377 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14378 (clobber (reg:CC 17))])
14379 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
14380 (clobber (reg:CC 17))])]
14381 ""
14382 "
14383 {
14384 if (TARGET_64BIT)
14385 {
14386 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
14387 DONE;
14388 }
14389 if (TARGET_SINGLE_STRINGOP || optimize_size)
14390 {
14391 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
14392 operands[1]));
14393 DONE;
14394 }
14395 else
14396 operands[2] = gen_reg_rtx (QImode);
14397 }")
14398
14399 (define_expand "strmovqi_rex64"
14400 [(set (match_dup 2)
14401 (mem:QI (match_operand:DI 1 "register_operand" "")))
14402 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
14403 (match_dup 2))
14404 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14405 (clobber (reg:CC 17))])
14406 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
14407 (clobber (reg:CC 17))])]
14408 "!TARGET_64BIT"
14409 "
14410 {
14411 if (TARGET_SINGLE_STRINGOP || optimize_size)
14412 {
14413 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
14414 operands[1]));
14415 DONE;
14416 }
14417 else
14418 operands[2] = gen_reg_rtx (QImode);
14419 }")
14420
14421 (define_insn "strmovdi_rex_1"
14422 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
14423 (mem:DI (match_operand:DI 3 "register_operand" "1")))
14424 (set (match_operand:DI 0 "register_operand" "=D")
14425 (plus:DI (match_dup 2)
14426 (const_int 8)))
14427 (set (match_operand:DI 1 "register_operand" "=S")
14428 (plus:DI (match_dup 3)
14429 (const_int 8)))
14430 (use (reg:SI 19))]
14431 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14432 "movsq"
14433 [(set_attr "type" "str")
14434 (set_attr "mode" "DI")
14435 (set_attr "memory" "both")])
14436
14437 (define_insn "strmovsi_1"
14438 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
14439 (mem:SI (match_operand:SI 3 "register_operand" "1")))
14440 (set (match_operand:SI 0 "register_operand" "=D")
14441 (plus:SI (match_dup 2)
14442 (const_int 4)))
14443 (set (match_operand:SI 1 "register_operand" "=S")
14444 (plus:SI (match_dup 3)
14445 (const_int 4)))
14446 (use (reg:SI 19))]
14447 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14448 "{movsl|movsd}"
14449 [(set_attr "type" "str")
14450 (set_attr "mode" "SI")
14451 (set_attr "memory" "both")])
14452
14453 (define_insn "strmovsi_rex_1"
14454 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
14455 (mem:SI (match_operand:DI 3 "register_operand" "1")))
14456 (set (match_operand:DI 0 "register_operand" "=D")
14457 (plus:DI (match_dup 2)
14458 (const_int 4)))
14459 (set (match_operand:DI 1 "register_operand" "=S")
14460 (plus:DI (match_dup 3)
14461 (const_int 4)))
14462 (use (reg:SI 19))]
14463 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14464 "{movsl|movsd}"
14465 [(set_attr "type" "str")
14466 (set_attr "mode" "SI")
14467 (set_attr "memory" "both")])
14468
14469 (define_insn "strmovhi_1"
14470 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
14471 (mem:HI (match_operand:SI 3 "register_operand" "1")))
14472 (set (match_operand:SI 0 "register_operand" "=D")
14473 (plus:SI (match_dup 2)
14474 (const_int 2)))
14475 (set (match_operand:SI 1 "register_operand" "=S")
14476 (plus:SI (match_dup 3)
14477 (const_int 2)))
14478 (use (reg:SI 19))]
14479 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14480 "movsw"
14481 [(set_attr "type" "str")
14482 (set_attr "memory" "both")
14483 (set_attr "mode" "HI")])
14484
14485 (define_insn "strmovhi_rex_1"
14486 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
14487 (mem:HI (match_operand:DI 3 "register_operand" "1")))
14488 (set (match_operand:DI 0 "register_operand" "=D")
14489 (plus:DI (match_dup 2)
14490 (const_int 2)))
14491 (set (match_operand:DI 1 "register_operand" "=S")
14492 (plus:DI (match_dup 3)
14493 (const_int 2)))
14494 (use (reg:SI 19))]
14495 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14496 "movsw"
14497 [(set_attr "type" "str")
14498 (set_attr "memory" "both")
14499 (set_attr "mode" "HI")])
14500
14501 (define_insn "strmovqi_1"
14502 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
14503 (mem:QI (match_operand:SI 3 "register_operand" "1")))
14504 (set (match_operand:SI 0 "register_operand" "=D")
14505 (plus:SI (match_dup 2)
14506 (const_int 1)))
14507 (set (match_operand:SI 1 "register_operand" "=S")
14508 (plus:SI (match_dup 3)
14509 (const_int 1)))
14510 (use (reg:SI 19))]
14511 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14512 "movsb"
14513 [(set_attr "type" "str")
14514 (set_attr "memory" "both")
14515 (set_attr "mode" "QI")])
14516
14517 (define_insn "strmovqi_rex_1"
14518 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
14519 (mem:QI (match_operand:DI 3 "register_operand" "1")))
14520 (set (match_operand:DI 0 "register_operand" "=D")
14521 (plus:DI (match_dup 2)
14522 (const_int 1)))
14523 (set (match_operand:DI 1 "register_operand" "=S")
14524 (plus:DI (match_dup 3)
14525 (const_int 1)))
14526 (use (reg:SI 19))]
14527 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14528 "movsb"
14529 [(set_attr "type" "str")
14530 (set_attr "memory" "both")
14531 (set_attr "mode" "QI")])
14532
14533 (define_insn "rep_movdi_rex64"
14534 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14535 (set (match_operand:DI 0 "register_operand" "=D")
14536 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14537 (const_int 3))
14538 (match_operand:DI 3 "register_operand" "0")))
14539 (set (match_operand:DI 1 "register_operand" "=S")
14540 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
14541 (match_operand:DI 4 "register_operand" "1")))
14542 (set (mem:BLK (match_dup 3))
14543 (mem:BLK (match_dup 4)))
14544 (use (match_dup 5))
14545 (use (reg:SI 19))]
14546 "TARGET_64BIT"
14547 "rep\;movsq|rep movsq"
14548 [(set_attr "type" "str")
14549 (set_attr "prefix_rep" "1")
14550 (set_attr "memory" "both")
14551 (set_attr "mode" "DI")])
14552
14553 (define_insn "rep_movsi"
14554 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14555 (set (match_operand:SI 0 "register_operand" "=D")
14556 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
14557 (const_int 2))
14558 (match_operand:SI 3 "register_operand" "0")))
14559 (set (match_operand:SI 1 "register_operand" "=S")
14560 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
14561 (match_operand:SI 4 "register_operand" "1")))
14562 (set (mem:BLK (match_dup 3))
14563 (mem:BLK (match_dup 4)))
14564 (use (match_dup 5))
14565 (use (reg:SI 19))]
14566 "!TARGET_64BIT"
14567 "rep\;movsl|rep movsd"
14568 [(set_attr "type" "str")
14569 (set_attr "prefix_rep" "1")
14570 (set_attr "memory" "both")
14571 (set_attr "mode" "SI")])
14572
14573 (define_insn "rep_movsi_rex64"
14574 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14575 (set (match_operand:DI 0 "register_operand" "=D")
14576 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
14577 (const_int 2))
14578 (match_operand:DI 3 "register_operand" "0")))
14579 (set (match_operand:DI 1 "register_operand" "=S")
14580 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
14581 (match_operand:DI 4 "register_operand" "1")))
14582 (set (mem:BLK (match_dup 3))
14583 (mem:BLK (match_dup 4)))
14584 (use (match_dup 5))
14585 (use (reg:SI 19))]
14586 "TARGET_64BIT"
14587 "rep\;movsl|rep movsd"
14588 [(set_attr "type" "str")
14589 (set_attr "prefix_rep" "1")
14590 (set_attr "memory" "both")
14591 (set_attr "mode" "SI")])
14592
14593 (define_insn "rep_movqi"
14594 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
14595 (set (match_operand:SI 0 "register_operand" "=D")
14596 (plus:SI (match_operand:SI 3 "register_operand" "0")
14597 (match_operand:SI 5 "register_operand" "2")))
14598 (set (match_operand:SI 1 "register_operand" "=S")
14599 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
14600 (set (mem:BLK (match_dup 3))
14601 (mem:BLK (match_dup 4)))
14602 (use (match_dup 5))
14603 (use (reg:SI 19))]
14604 "!TARGET_64BIT"
14605 "rep\;movsb|rep movsb"
14606 [(set_attr "type" "str")
14607 (set_attr "prefix_rep" "1")
14608 (set_attr "memory" "both")
14609 (set_attr "mode" "SI")])
14610
14611 (define_insn "rep_movqi_rex64"
14612 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
14613 (set (match_operand:DI 0 "register_operand" "=D")
14614 (plus:DI (match_operand:DI 3 "register_operand" "0")
14615 (match_operand:DI 5 "register_operand" "2")))
14616 (set (match_operand:DI 1 "register_operand" "=S")
14617 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
14618 (set (mem:BLK (match_dup 3))
14619 (mem:BLK (match_dup 4)))
14620 (use (match_dup 5))
14621 (use (reg:SI 19))]
14622 "TARGET_64BIT"
14623 "rep\;movsb|rep movsb"
14624 [(set_attr "type" "str")
14625 (set_attr "prefix_rep" "1")
14626 (set_attr "memory" "both")
14627 (set_attr "mode" "SI")])
14628
14629 (define_expand "clrstrsi"
14630 [(use (match_operand:BLK 0 "memory_operand" ""))
14631 (use (match_operand:SI 1 "nonmemory_operand" ""))
14632 (use (match_operand 2 "const_int_operand" ""))]
14633 ""
14634 "
14635 {
14636 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14637 DONE;
14638 else
14639 FAIL;
14640 }")
14641
14642 (define_expand "clrstrdi"
14643 [(use (match_operand:BLK 0 "memory_operand" ""))
14644 (use (match_operand:DI 1 "nonmemory_operand" ""))
14645 (use (match_operand 2 "const_int_operand" ""))]
14646 "TARGET_64BIT"
14647 "
14648 {
14649 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
14650 DONE;
14651 else
14652 FAIL;
14653 }")
14654
14655 ;; Most CPUs don't like single string operations
14656 ;; Handle this case here to simplify previous expander.
14657
14658 (define_expand "strsetdi_rex64"
14659 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
14660 (match_operand:DI 1 "register_operand" ""))
14661 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
14662 (clobber (reg:CC 17))])]
14663 "TARGET_64BIT"
14664 "
14665 {
14666 if (TARGET_SINGLE_STRINGOP || optimize_size)
14667 {
14668 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
14669 DONE;
14670 }
14671 }")
14672
14673 (define_expand "strsetsi"
14674 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
14675 (match_operand:SI 1 "register_operand" ""))
14676 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
14677 (clobber (reg:CC 17))])]
14678 ""
14679 "
14680 {
14681 if (TARGET_64BIT)
14682 {
14683 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
14684 DONE;
14685 }
14686 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14687 {
14688 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
14689 DONE;
14690 }
14691 }")
14692
14693 (define_expand "strsetsi_rex64"
14694 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
14695 (match_operand:SI 1 "register_operand" ""))
14696 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
14697 (clobber (reg:CC 17))])]
14698 "TARGET_64BIT"
14699 "
14700 {
14701 if (TARGET_SINGLE_STRINGOP || optimize_size)
14702 {
14703 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
14704 DONE;
14705 }
14706 }")
14707
14708 (define_expand "strsethi"
14709 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
14710 (match_operand:HI 1 "register_operand" ""))
14711 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
14712 (clobber (reg:CC 17))])]
14713 ""
14714 "
14715 {
14716 if (TARGET_64BIT)
14717 {
14718 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
14719 DONE;
14720 }
14721 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14722 {
14723 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
14724 DONE;
14725 }
14726 }")
14727
14728 (define_expand "strsethi_rex64"
14729 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
14730 (match_operand:HI 1 "register_operand" ""))
14731 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
14732 (clobber (reg:CC 17))])]
14733 "TARGET_64BIT"
14734 "
14735 {
14736 if (TARGET_SINGLE_STRINGOP || optimize_size)
14737 {
14738 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
14739 DONE;
14740 }
14741 }")
14742
14743 (define_expand "strsetqi"
14744 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
14745 (match_operand:QI 1 "register_operand" ""))
14746 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14747 (clobber (reg:CC 17))])]
14748 ""
14749 "
14750 {
14751 if (TARGET_64BIT)
14752 {
14753 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
14754 DONE;
14755 }
14756 else if (TARGET_SINGLE_STRINGOP || optimize_size)
14757 {
14758 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
14759 DONE;
14760 }
14761 }")
14762
14763 (define_expand "strsetqi_rex64"
14764 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
14765 (match_operand:QI 1 "register_operand" ""))
14766 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14767 (clobber (reg:CC 17))])]
14768 "TARGET_64BIT"
14769 "
14770 {
14771 if (TARGET_SINGLE_STRINGOP || optimize_size)
14772 {
14773 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
14774 DONE;
14775 }
14776 }")
14777
14778 (define_insn "strsetdi_rex_1"
14779 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
14780 (match_operand:SI 2 "register_operand" "a"))
14781 (set (match_operand:DI 0 "register_operand" "=D")
14782 (plus:DI (match_dup 1)
14783 (const_int 8)))
14784 (use (reg:SI 19))]
14785 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14786 "stosq"
14787 [(set_attr "type" "str")
14788 (set_attr "memory" "store")
14789 (set_attr "mode" "DI")])
14790
14791 (define_insn "strsetsi_1"
14792 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
14793 (match_operand:SI 2 "register_operand" "a"))
14794 (set (match_operand:SI 0 "register_operand" "=D")
14795 (plus:SI (match_dup 1)
14796 (const_int 4)))
14797 (use (reg:SI 19))]
14798 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14799 "stosl|stosd"
14800 [(set_attr "type" "str")
14801 (set_attr "memory" "store")
14802 (set_attr "mode" "SI")])
14803
14804 (define_insn "strsetsi_rex_1"
14805 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
14806 (match_operand:SI 2 "register_operand" "a"))
14807 (set (match_operand:DI 0 "register_operand" "=D")
14808 (plus:DI (match_dup 1)
14809 (const_int 4)))
14810 (use (reg:SI 19))]
14811 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14812 "stosl|stosd"
14813 [(set_attr "type" "str")
14814 (set_attr "memory" "store")
14815 (set_attr "mode" "SI")])
14816
14817 (define_insn "strsethi_1"
14818 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
14819 (match_operand:HI 2 "register_operand" "a"))
14820 (set (match_operand:SI 0 "register_operand" "=D")
14821 (plus:SI (match_dup 1)
14822 (const_int 2)))
14823 (use (reg:SI 19))]
14824 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14825 "stosw"
14826 [(set_attr "type" "str")
14827 (set_attr "memory" "store")
14828 (set_attr "mode" "HI")])
14829
14830 (define_insn "strsethi_rex_1"
14831 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
14832 (match_operand:HI 2 "register_operand" "a"))
14833 (set (match_operand:DI 0 "register_operand" "=D")
14834 (plus:DI (match_dup 1)
14835 (const_int 2)))
14836 (use (reg:SI 19))]
14837 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14838 "stosw"
14839 [(set_attr "type" "str")
14840 (set_attr "memory" "store")
14841 (set_attr "mode" "HI")])
14842
14843 (define_insn "strsetqi_1"
14844 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
14845 (match_operand:QI 2 "register_operand" "a"))
14846 (set (match_operand:SI 0 "register_operand" "=D")
14847 (plus:SI (match_dup 1)
14848 (const_int 1)))
14849 (use (reg:SI 19))]
14850 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14851 "stosb"
14852 [(set_attr "type" "str")
14853 (set_attr "memory" "store")
14854 (set_attr "mode" "QI")])
14855
14856 (define_insn "strsetqi_rex_1"
14857 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
14858 (match_operand:QI 2 "register_operand" "a"))
14859 (set (match_operand:DI 0 "register_operand" "=D")
14860 (plus:DI (match_dup 1)
14861 (const_int 1)))
14862 (use (reg:SI 19))]
14863 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
14864 "stosb"
14865 [(set_attr "type" "str")
14866 (set_attr "memory" "store")
14867 (set_attr "mode" "QI")])
14868
14869 (define_insn "rep_stosdi_rex64"
14870 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
14871 (set (match_operand:DI 0 "register_operand" "=D")
14872 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
14873 (const_int 3))
14874 (match_operand:DI 3 "register_operand" "0")))
14875 (set (mem:BLK (match_dup 3))
14876 (const_int 0))
14877 (use (match_operand:DI 2 "register_operand" "a"))
14878 (use (match_dup 4))
14879 (use (reg:SI 19))]
14880 "TARGET_64BIT"
14881 "rep\;stosq|rep stosq"
14882 [(set_attr "type" "str")
14883 (set_attr "prefix_rep" "1")
14884 (set_attr "memory" "store")
14885 (set_attr "mode" "DI")])
14886
14887 (define_insn "rep_stossi"
14888 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
14889 (set (match_operand:SI 0 "register_operand" "=D")
14890 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
14891 (const_int 2))
14892 (match_operand:SI 3 "register_operand" "0")))
14893 (set (mem:BLK (match_dup 3))
14894 (const_int 0))
14895 (use (match_operand:SI 2 "register_operand" "a"))
14896 (use (match_dup 4))
14897 (use (reg:SI 19))]
14898 "!TARGET_64BIT"
14899 "rep\;stosl|rep stosd"
14900 [(set_attr "type" "str")
14901 (set_attr "prefix_rep" "1")
14902 (set_attr "memory" "store")
14903 (set_attr "mode" "SI")])
14904
14905 (define_insn "rep_stossi_rex64"
14906 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
14907 (set (match_operand:DI 0 "register_operand" "=D")
14908 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
14909 (const_int 2))
14910 (match_operand:DI 3 "register_operand" "0")))
14911 (set (mem:BLK (match_dup 3))
14912 (const_int 0))
14913 (use (match_operand:SI 2 "register_operand" "a"))
14914 (use (match_dup 4))
14915 (use (reg:SI 19))]
14916 "TARGET_64BIT"
14917 "rep\;stosl|rep stosd"
14918 [(set_attr "type" "str")
14919 (set_attr "prefix_rep" "1")
14920 (set_attr "memory" "store")
14921 (set_attr "mode" "SI")])
14922
14923 (define_insn "rep_stosqi"
14924 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
14925 (set (match_operand:SI 0 "register_operand" "=D")
14926 (plus:SI (match_operand:SI 3 "register_operand" "0")
14927 (match_operand:SI 4 "register_operand" "1")))
14928 (set (mem:BLK (match_dup 3))
14929 (const_int 0))
14930 (use (match_operand:QI 2 "register_operand" "a"))
14931 (use (match_dup 4))
14932 (use (reg:SI 19))]
14933 "!TARGET_64BIT"
14934 "rep\;stosb|rep stosb"
14935 [(set_attr "type" "str")
14936 (set_attr "prefix_rep" "1")
14937 (set_attr "memory" "store")
14938 (set_attr "mode" "QI")])
14939
14940 (define_insn "rep_stosqi_rex64"
14941 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
14942 (set (match_operand:DI 0 "register_operand" "=D")
14943 (plus:DI (match_operand:DI 3 "register_operand" "0")
14944 (match_operand:DI 4 "register_operand" "1")))
14945 (set (mem:BLK (match_dup 3))
14946 (const_int 0))
14947 (use (match_operand:QI 2 "register_operand" "a"))
14948 (use (match_dup 4))
14949 (use (reg:DI 19))]
14950 "TARGET_64BIT"
14951 "rep\;stosb|rep stosb"
14952 [(set_attr "type" "str")
14953 (set_attr "prefix_rep" "1")
14954 (set_attr "memory" "store")
14955 (set_attr "mode" "QI")])
14956
14957 (define_expand "cmpstrsi"
14958 [(set (match_operand:SI 0 "register_operand" "")
14959 (compare:SI (match_operand:BLK 1 "general_operand" "")
14960 (match_operand:BLK 2 "general_operand" "")))
14961 (use (match_operand 3 "general_operand" ""))
14962 (use (match_operand 4 "immediate_operand" ""))]
14963 ""
14964 "
14965 {
14966 rtx addr1, addr2, out, outlow, count, countreg, align;
14967
14968 out = operands[0];
14969 if (GET_CODE (out) != REG)
14970 out = gen_reg_rtx (SImode);
14971
14972 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
14973 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
14974
14975 count = operands[3];
14976 countreg = copy_to_mode_reg (Pmode, count);
14977
14978 /* %%% Iff we are testing strict equality, we can use known alignment
14979 to good advantage. This may be possible with combine, particularly
14980 once cc0 is dead. */
14981 align = operands[4];
14982
14983 emit_insn (gen_cld ());
14984 if (GET_CODE (count) == CONST_INT)
14985 {
14986 if (INTVAL (count) == 0)
14987 {
14988 emit_move_insn (operands[0], const0_rtx);
14989 DONE;
14990 }
14991 if (TARGET_64BIT)
14992 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
14993 addr1, addr2, countreg));
14994 else
14995 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
14996 addr1, addr2, countreg));
14997 }
14998 else
14999 {
15000 if (TARGET_64BIT)
15001 {
15002 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15003 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15004 addr1, addr2, countreg));
15005 }
15006 else
15007 {
15008 emit_insn (gen_cmpsi_1 (countreg, countreg));
15009 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15010 addr1, addr2, countreg));
15011 }
15012 }
15013
15014 outlow = gen_lowpart (QImode, out);
15015 emit_insn (gen_cmpintqi (outlow));
15016 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15017
15018 if (operands[0] != out)
15019 emit_move_insn (operands[0], out);
15020
15021 DONE;
15022 }")
15023
15024 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15025
15026 (define_expand "cmpintqi"
15027 [(set (match_dup 1)
15028 (gtu:QI (reg:CC 17) (const_int 0)))
15029 (set (match_dup 2)
15030 (ltu:QI (reg:CC 17) (const_int 0)))
15031 (parallel [(set (match_operand:QI 0 "register_operand" "")
15032 (minus:QI (match_dup 1)
15033 (match_dup 2)))
15034 (clobber (reg:CC 17))])]
15035 ""
15036 "operands[1] = gen_reg_rtx (QImode);
15037 operands[2] = gen_reg_rtx (QImode);")
15038
15039 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15040 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15041
15042 (define_insn "cmpstrqi_nz_1"
15043 [(set (reg:CC 17)
15044 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15045 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15046 (use (match_operand:SI 6 "register_operand" "2"))
15047 (use (match_operand:SI 3 "immediate_operand" "i"))
15048 (use (reg:SI 19))
15049 (clobber (match_operand:SI 0 "register_operand" "=S"))
15050 (clobber (match_operand:SI 1 "register_operand" "=D"))
15051 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15052 "!TARGET_64BIT"
15053 "repz{\;| }cmpsb"
15054 [(set_attr "type" "str")
15055 (set_attr "mode" "QI")
15056 (set_attr "prefix_rep" "1")])
15057
15058 (define_insn "cmpstrqi_nz_rex_1"
15059 [(set (reg:CC 17)
15060 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15061 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15062 (use (match_operand:DI 6 "register_operand" "2"))
15063 (use (match_operand:SI 3 "immediate_operand" "i"))
15064 (use (reg:SI 19))
15065 (clobber (match_operand:DI 0 "register_operand" "=S"))
15066 (clobber (match_operand:DI 1 "register_operand" "=D"))
15067 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15068 "TARGET_64BIT"
15069 "repz{\;| }cmpsb"
15070 [(set_attr "type" "str")
15071 (set_attr "mode" "QI")
15072 (set_attr "prefix_rep" "1")])
15073
15074 ;; The same, but the count is not known to not be zero.
15075
15076 (define_insn "cmpstrqi_1"
15077 [(set (reg:CC 17)
15078 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15079 (const_int 0))
15080 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15081 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15082 (const_int 0)))
15083 (use (match_operand:SI 3 "immediate_operand" "i"))
15084 (use (reg:CC 17))
15085 (use (reg:SI 19))
15086 (clobber (match_operand:SI 0 "register_operand" "=S"))
15087 (clobber (match_operand:SI 1 "register_operand" "=D"))
15088 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15089 "!TARGET_64BIT"
15090 "repz{\;| }cmpsb"
15091 [(set_attr "type" "str")
15092 (set_attr "mode" "QI")
15093 (set_attr "prefix_rep" "1")])
15094
15095 (define_insn "cmpstrqi_rex_1"
15096 [(set (reg:CC 17)
15097 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15098 (const_int 0))
15099 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15100 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15101 (const_int 0)))
15102 (use (match_operand:SI 3 "immediate_operand" "i"))
15103 (use (reg:CC 17))
15104 (use (reg:SI 19))
15105 (clobber (match_operand:DI 0 "register_operand" "=S"))
15106 (clobber (match_operand:DI 1 "register_operand" "=D"))
15107 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15108 "TARGET_64BIT"
15109 "repz{\;| }cmpsb"
15110 [(set_attr "type" "str")
15111 (set_attr "mode" "QI")
15112 (set_attr "prefix_rep" "1")])
15113
15114 (define_expand "strlensi"
15115 [(set (match_operand:SI 0 "register_operand" "")
15116 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15117 (match_operand:QI 2 "immediate_operand" "")
15118 (match_operand 3 "immediate_operand" "")] 0))]
15119 ""
15120 "
15121 {
15122 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15123 DONE;
15124 else
15125 FAIL;
15126 }")
15127
15128 (define_expand "strlendi"
15129 [(set (match_operand:DI 0 "register_operand" "")
15130 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15131 (match_operand:QI 2 "immediate_operand" "")
15132 (match_operand 3 "immediate_operand" "")] 0))]
15133 ""
15134 "
15135 {
15136 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15137 DONE;
15138 else
15139 FAIL;
15140 }")
15141
15142 (define_insn "strlenqi_1"
15143 [(set (match_operand:SI 0 "register_operand" "=&c")
15144 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15145 (match_operand:QI 2 "register_operand" "a")
15146 (match_operand:SI 3 "immediate_operand" "i")
15147 (match_operand:SI 4 "register_operand" "0")] 0))
15148 (use (reg:SI 19))
15149 (clobber (match_operand:SI 1 "register_operand" "=D"))
15150 (clobber (reg:CC 17))]
15151 "!TARGET_64BIT"
15152 "repnz{\;| }scasb"
15153 [(set_attr "type" "str")
15154 (set_attr "mode" "QI")
15155 (set_attr "prefix_rep" "1")])
15156
15157 (define_insn "strlenqi_rex_1"
15158 [(set (match_operand:DI 0 "register_operand" "=&c")
15159 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15160 (match_operand:QI 2 "register_operand" "a")
15161 (match_operand:DI 3 "immediate_operand" "i")
15162 (match_operand:DI 4 "register_operand" "0")] 0))
15163 (use (reg:SI 19))
15164 (clobber (match_operand:DI 1 "register_operand" "=D"))
15165 (clobber (reg:CC 17))]
15166 "TARGET_64BIT"
15167 "repnz{\;| }scasb"
15168 [(set_attr "type" "str")
15169 (set_attr "mode" "QI")
15170 (set_attr "prefix_rep" "1")])
15171 \f
15172 ;; Conditional move instructions.
15173
15174 (define_expand "movdicc_rex64"
15175 [(set (match_operand:DI 0 "register_operand" "")
15176 (if_then_else:DI (match_operand 1 "comparison_operator" "")
15177 (match_operand:DI 2 "x86_64_general_operand" "")
15178 (match_operand:DI 3 "x86_64_general_operand" "")))]
15179 "TARGET_64BIT"
15180 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15181
15182 (define_insn "x86_movdicc_0_m1_rex64"
15183 [(set (match_operand:DI 0 "register_operand" "=r")
15184 (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
15185 (const_int -1)
15186 (const_int 0)))
15187 (clobber (reg:CC 17))]
15188 "TARGET_64BIT"
15189 "sbb{q}\\t%0, %0"
15190 ; Since we don't have the proper number of operands for an alu insn,
15191 ; fill in all the blanks.
15192 [(set_attr "type" "alu")
15193 (set_attr "memory" "none")
15194 (set_attr "imm_disp" "false")
15195 (set_attr "mode" "DI")
15196 (set_attr "length_immediate" "0")])
15197
15198 (define_insn "*movdicc_c_rex64"
15199 [(set (match_operand:DI 0 "register_operand" "=r,r")
15200 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
15201 [(reg 17) (const_int 0)])
15202 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
15203 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
15204 "TARGET_64BIT && TARGET_CMOVE
15205 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15206 "@
15207 cmov%C1\\t{%2, %0|%0, %2}
15208 cmov%c1\\t{%3, %0|%0, %3}"
15209 [(set_attr "type" "icmov")
15210 (set_attr "mode" "DI")])
15211
15212 (define_expand "movsicc"
15213 [(set (match_operand:SI 0 "register_operand" "")
15214 (if_then_else:SI (match_operand 1 "comparison_operator" "")
15215 (match_operand:SI 2 "general_operand" "")
15216 (match_operand:SI 3 "general_operand" "")))]
15217 ""
15218 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15219
15220 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15221 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15222 ;; So just document what we're doing explicitly.
15223
15224 (define_insn "x86_movsicc_0_m1"
15225 [(set (match_operand:SI 0 "register_operand" "=r")
15226 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
15227 (const_int -1)
15228 (const_int 0)))
15229 (clobber (reg:CC 17))]
15230 ""
15231 "sbb{l}\\t%0, %0"
15232 ; Since we don't have the proper number of operands for an alu insn,
15233 ; fill in all the blanks.
15234 [(set_attr "type" "alu")
15235 (set_attr "memory" "none")
15236 (set_attr "imm_disp" "false")
15237 (set_attr "mode" "SI")
15238 (set_attr "length_immediate" "0")])
15239
15240 (define_insn "*movsicc_noc"
15241 [(set (match_operand:SI 0 "register_operand" "=r,r")
15242 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
15243 [(reg 17) (const_int 0)])
15244 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
15245 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
15246 "TARGET_CMOVE
15247 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15248 "@
15249 cmov%C1\\t{%2, %0|%0, %2}
15250 cmov%c1\\t{%3, %0|%0, %3}"
15251 [(set_attr "type" "icmov")
15252 (set_attr "mode" "SI")])
15253
15254 (define_expand "movhicc"
15255 [(set (match_operand:HI 0 "register_operand" "")
15256 (if_then_else:HI (match_operand 1 "comparison_operator" "")
15257 (match_operand:HI 2 "nonimmediate_operand" "")
15258 (match_operand:HI 3 "nonimmediate_operand" "")))]
15259 "TARGET_CMOVE && TARGET_HIMODE_MATH"
15260 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
15261
15262 (define_insn "*movhicc_noc"
15263 [(set (match_operand:HI 0 "register_operand" "=r,r")
15264 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
15265 [(reg 17) (const_int 0)])
15266 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
15267 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
15268 "TARGET_CMOVE
15269 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15270 "@
15271 cmov%C1\\t{%2, %0|%0, %2}
15272 cmov%c1\\t{%3, %0|%0, %3}"
15273 [(set_attr "type" "icmov")
15274 (set_attr "mode" "HI")])
15275
15276 (define_expand "movsfcc"
15277 [(set (match_operand:SF 0 "register_operand" "")
15278 (if_then_else:SF (match_operand 1 "comparison_operator" "")
15279 (match_operand:SF 2 "register_operand" "")
15280 (match_operand:SF 3 "register_operand" "")))]
15281 "TARGET_CMOVE"
15282 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15283
15284 (define_insn "*movsfcc_1"
15285 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15286 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15287 [(reg 17) (const_int 0)])
15288 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15289 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15290 "TARGET_CMOVE
15291 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15292 "@
15293 fcmov%F1\\t{%2, %0|%0, %2}
15294 fcmov%f1\\t{%3, %0|%0, %3}
15295 cmov%C1\\t{%2, %0|%0, %2}
15296 cmov%c1\\t{%3, %0|%0, %3}"
15297 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15298 (set_attr "mode" "SF,SF,SI,SI")])
15299
15300 (define_expand "movdfcc"
15301 [(set (match_operand:DF 0 "register_operand" "")
15302 (if_then_else:DF (match_operand 1 "comparison_operator" "")
15303 (match_operand:DF 2 "register_operand" "")
15304 (match_operand:DF 3 "register_operand" "")))]
15305 "TARGET_CMOVE"
15306 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15307
15308 (define_insn "*movdfcc_1"
15309 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15310 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15311 [(reg 17) (const_int 0)])
15312 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15313 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15314 "TARGET_CMOVE && !TARGET_64BIT
15315 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15316 "@
15317 fcmov%F1\\t{%2, %0|%0, %2}
15318 fcmov%f1\\t{%3, %0|%0, %3}
15319 #
15320 #"
15321 [(set_attr "type" "fcmov,fcmov,multi,multi")
15322 (set_attr "mode" "DF")])
15323
15324 (define_insn "*movdfcc_1_rex64"
15325 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15326 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15327 [(reg 17) (const_int 0)])
15328 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15329 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15330 "TARGET_CMOVE && TARGET_64BIT
15331 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15332 "@
15333 fcmov%F1\\t{%2, %0|%0, %2}
15334 fcmov%f1\\t{%3, %0|%0, %3}
15335 cmov%C1\\t{%2, %0|%0, %2}
15336 cmov%c1\\t{%3, %0|%0, %3}"
15337 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15338 (set_attr "mode" "DF")])
15339
15340 (define_split
15341 [(set (match_operand:DF 0 "register_operand" "")
15342 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15343 [(match_operand 4 "" "") (const_int 0)])
15344 (match_operand:DF 2 "nonimmediate_operand" "")
15345 (match_operand:DF 3 "nonimmediate_operand" "")))]
15346 "!ANY_FP_REG_P (operands[0]) && reload_completed && !TARGET_64BIT"
15347 [(set (match_dup 2)
15348 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15349 (match_dup 5)
15350 (match_dup 7)))
15351 (set (match_dup 3)
15352 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15353 (match_dup 6)
15354 (match_dup 8)))]
15355 "split_di (operands+2, 1, operands+5, operands+6);
15356 split_di (operands+3, 1, operands+7, operands+8);
15357 split_di (operands, 1, operands+2, operands+3);")
15358
15359 (define_expand "movxfcc"
15360 [(set (match_operand:XF 0 "register_operand" "")
15361 (if_then_else:XF (match_operand 1 "comparison_operator" "")
15362 (match_operand:XF 2 "register_operand" "")
15363 (match_operand:XF 3 "register_operand" "")))]
15364 "TARGET_CMOVE && !TARGET_64BIT"
15365 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15366
15367 (define_expand "movtfcc"
15368 [(set (match_operand:TF 0 "register_operand" "")
15369 (if_then_else:TF (match_operand 1 "comparison_operator" "")
15370 (match_operand:TF 2 "register_operand" "")
15371 (match_operand:TF 3 "register_operand" "")))]
15372 "TARGET_CMOVE"
15373 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
15374
15375 (define_insn "*movxfcc_1"
15376 [(set (match_operand:XF 0 "register_operand" "=f,f")
15377 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15378 [(reg 17) (const_int 0)])
15379 (match_operand:XF 2 "register_operand" "f,0")
15380 (match_operand:XF 3 "register_operand" "0,f")))]
15381 "TARGET_CMOVE && !TARGET_64BIT"
15382 "@
15383 fcmov%F1\\t{%2, %0|%0, %2}
15384 fcmov%f1\\t{%3, %0|%0, %3}"
15385 [(set_attr "type" "fcmov")
15386 (set_attr "mode" "XF")])
15387
15388 (define_insn "*movtfcc_1"
15389 [(set (match_operand:TF 0 "register_operand" "=f,f")
15390 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
15391 [(reg 17) (const_int 0)])
15392 (match_operand:TF 2 "register_operand" "f,0")
15393 (match_operand:TF 3 "register_operand" "0,f")))]
15394 "TARGET_CMOVE"
15395 "@
15396 fcmov%F1\\t{%2, %0|%0, %2}
15397 fcmov%f1\\t{%3, %0|%0, %3}"
15398 [(set_attr "type" "fcmov")
15399 (set_attr "mode" "XF")])
15400
15401 (define_expand "minsf3"
15402 [(parallel [
15403 (set (match_operand:SF 0 "register_operand" "")
15404 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15405 (match_operand:SF 2 "nonimmediate_operand" ""))
15406 (match_dup 1)
15407 (match_dup 2)))
15408 (clobber (reg:CC 17))])]
15409 "TARGET_SSE"
15410 "")
15411
15412 (define_insn "*minsf"
15413 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15414 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
15415 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
15416 (match_dup 1)
15417 (match_dup 2)))
15418 (clobber (reg:CC 17))]
15419 "TARGET_SSE && TARGET_IEEE_FP"
15420 "#")
15421
15422 (define_insn "*minsf_nonieee"
15423 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15424 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
15425 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15426 (match_dup 1)
15427 (match_dup 2)))
15428 (clobber (reg:CC 17))]
15429 "TARGET_SSE && !TARGET_IEEE_FP"
15430 "#")
15431
15432 (define_split
15433 [(set (match_operand:SF 0 "register_operand" "")
15434 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15435 (match_operand:SF 2 "nonimmediate_operand" ""))
15436 (match_dup 1)
15437 (match_dup 2)))
15438 (clobber (reg:CC 17))]
15439 "SSE_REG_P (operands[0]) && reload_completed"
15440 [(set (match_dup 0)
15441 (if_then_else:SF (lt (match_dup 1)
15442 (match_dup 2))
15443 (match_dup 1)
15444 (match_dup 2)))])
15445
15446 ;; We can't represent the LT test directly. Do this by swapping the operands.
15447 (define_split
15448 [(set (match_operand:SF 0 "register_operand" "")
15449 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
15450 (match_operand:SF 2 "register_operand" ""))
15451 (match_dup 1)
15452 (match_dup 2)))
15453 (clobber (reg:CC 17))]
15454 "FP_REG_P (operands[0]) && reload_completed"
15455 [(set (reg:CCFP 17)
15456 (compare:CCFP (match_dup 2)
15457 (match_dup 1)))
15458 (set (match_dup 0)
15459 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
15460 (match_dup 1)
15461 (match_dup 2)))])
15462
15463 (define_insn "*minsf_sse"
15464 [(set (match_operand:SF 0 "register_operand" "=x")
15465 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
15466 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15467 (match_dup 1)
15468 (match_dup 2)))]
15469 "TARGET_SSE && reload_completed"
15470 "minss\\t{%2, %0|%0, %2}"
15471 [(set_attr "type" "sse")
15472 (set_attr "mode" "SF")])
15473
15474 (define_expand "mindf3"
15475 [(parallel [
15476 (set (match_operand:DF 0 "register_operand" "")
15477 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15478 (match_operand:DF 2 "nonimmediate_operand" ""))
15479 (match_dup 1)
15480 (match_dup 2)))
15481 (clobber (reg:CC 17))])]
15482 "TARGET_SSE2"
15483 "#")
15484
15485 (define_insn "*mindf"
15486 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15487 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15488 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
15489 (match_dup 1)
15490 (match_dup 2)))
15491 (clobber (reg:CC 17))]
15492 "TARGET_SSE2 && TARGET_IEEE_FP"
15493 "#")
15494
15495 (define_insn "*mindf_nonieee"
15496 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15497 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
15498 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
15499 (match_dup 1)
15500 (match_dup 2)))
15501 (clobber (reg:CC 17))]
15502 "TARGET_SSE2 && !TARGET_IEEE_FP"
15503 "#")
15504
15505 (define_split
15506 [(set (match_operand:DF 0 "register_operand" "")
15507 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15508 (match_operand:DF 2 "nonimmediate_operand" ""))
15509 (match_dup 1)
15510 (match_dup 2)))
15511 (clobber (reg:CC 17))]
15512 "SSE_REG_P (operands[0]) && reload_completed"
15513 [(set (match_dup 0)
15514 (if_then_else:DF (lt (match_dup 1)
15515 (match_dup 2))
15516 (match_dup 1)
15517 (match_dup 2)))])
15518
15519 ;; We can't represent the LT test directly. Do this by swapping the operands.
15520 (define_split
15521 [(set (match_operand:DF 0 "register_operand" "")
15522 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
15523 (match_operand:DF 2 "register_operand" ""))
15524 (match_dup 1)
15525 (match_dup 2)))
15526 (clobber (reg:CC 17))]
15527 "FP_REG_P (operands[0]) && reload_completed"
15528 [(set (reg:CCFP 17)
15529 (compare:CCFP (match_dup 2)
15530 (match_dup 2)))
15531 (set (match_dup 0)
15532 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
15533 (match_dup 1)
15534 (match_dup 2)))])
15535
15536 (define_insn "*mindf_sse"
15537 [(set (match_operand:DF 0 "register_operand" "=Y")
15538 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
15539 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15540 (match_dup 1)
15541 (match_dup 2)))]
15542 "TARGET_SSE2 && reload_completed"
15543 "minsd\\t{%2, %0|%0, %2}"
15544 [(set_attr "type" "sse")
15545 (set_attr "mode" "DF")])
15546
15547 (define_expand "maxsf3"
15548 [(parallel [
15549 (set (match_operand:SF 0 "register_operand" "")
15550 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15551 (match_operand:SF 2 "nonimmediate_operand" ""))
15552 (match_dup 1)
15553 (match_dup 2)))
15554 (clobber (reg:CC 17))])]
15555 "TARGET_SSE"
15556 "#")
15557
15558 (define_insn "*maxsf"
15559 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
15560 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
15561 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x,0"))
15562 (match_dup 1)
15563 (match_dup 2)))
15564 (clobber (reg:CC 17))]
15565 "TARGET_SSE && TARGET_IEEE_FP"
15566 "#")
15567
15568 (define_insn "*maxsf_nonieee"
15569 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
15570 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
15571 (match_operand:SF 2 "nonimmediate_operand" "xm#f,fm#x"))
15572 (match_dup 1)
15573 (match_dup 2)))
15574 (clobber (reg:CC 17))]
15575 "TARGET_SSE && !TARGET_IEEE_FP"
15576 "#")
15577
15578 (define_split
15579 [(set (match_operand:SF 0 "register_operand" "")
15580 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15581 (match_operand:SF 2 "nonimmediate_operand" ""))
15582 (match_dup 1)
15583 (match_dup 2)))
15584 (clobber (reg:CC 17))]
15585 "SSE_REG_P (operands[0]) && reload_completed"
15586 [(set (match_dup 0)
15587 (if_then_else:SF (gt (match_dup 1)
15588 (match_dup 2))
15589 (match_dup 1)
15590 (match_dup 2)))])
15591
15592 (define_split
15593 [(set (match_operand:SF 0 "register_operand" "")
15594 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
15595 (match_operand:SF 2 "register_operand" ""))
15596 (match_dup 1)
15597 (match_dup 2)))
15598 (clobber (reg:CC 17))]
15599 "FP_REG_P (operands[0]) && reload_completed"
15600 [(set (reg:CCFP 17)
15601 (compare:CCFP (match_dup 1)
15602 (match_dup 2)))
15603 (set (match_dup 0)
15604 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
15605 (match_dup 1)
15606 (match_dup 2)))])
15607
15608 (define_insn "*maxsf_sse"
15609 [(set (match_operand:SF 0 "register_operand" "=x")
15610 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
15611 (match_operand:SF 2 "nonimmediate_operand" "xm"))
15612 (match_dup 1)
15613 (match_dup 2)))]
15614 "TARGET_SSE && reload_completed"
15615 "maxss\\t{%2, %0|%0, %2}"
15616 [(set_attr "type" "sse")
15617 (set_attr "mode" "SF")])
15618
15619 (define_expand "maxdf3"
15620 [(parallel [
15621 (set (match_operand:DF 0 "register_operand" "")
15622 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15623 (match_operand:DF 2 "nonimmediate_operand" ""))
15624 (match_dup 1)
15625 (match_dup 2)))
15626 (clobber (reg:CC 17))])]
15627 "TARGET_SSE2"
15628 "#")
15629
15630 (define_insn "*maxdf"
15631 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
15632 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
15633 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y,0"))
15634 (match_dup 1)
15635 (match_dup 2)))
15636 (clobber (reg:CC 17))]
15637 "TARGET_SSE2 && TARGET_IEEE_FP"
15638 "#")
15639
15640 (define_insn "*maxdf_nonieee"
15641 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
15642 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
15643 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,fm#Y"))
15644 (match_dup 1)
15645 (match_dup 2)))
15646 (clobber (reg:CC 17))]
15647 "TARGET_SSE2 && !TARGET_IEEE_FP"
15648 "#")
15649
15650 (define_split
15651 [(set (match_operand:DF 0 "register_operand" "")
15652 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15653 (match_operand:DF 2 "nonimmediate_operand" ""))
15654 (match_dup 1)
15655 (match_dup 2)))
15656 (clobber (reg:CC 17))]
15657 "SSE_REG_P (operands[0]) && reload_completed"
15658 [(set (match_dup 0)
15659 (if_then_else:DF (gt (match_dup 1)
15660 (match_dup 2))
15661 (match_dup 1)
15662 (match_dup 2)))])
15663
15664 (define_split
15665 [(set (match_operand:DF 0 "register_operand" "")
15666 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
15667 (match_operand:DF 2 "register_operand" ""))
15668 (match_dup 1)
15669 (match_dup 2)))
15670 (clobber (reg:CC 17))]
15671 "FP_REG_P (operands[0]) && reload_completed"
15672 [(set (reg:CCFP 17)
15673 (compare:CCFP (match_dup 1)
15674 (match_dup 2)))
15675 (set (match_dup 0)
15676 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
15677 (match_dup 1)
15678 (match_dup 2)))])
15679
15680 (define_insn "*maxdf_sse"
15681 [(set (match_operand:DF 0 "register_operand" "=Y")
15682 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
15683 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
15684 (match_dup 1)
15685 (match_dup 2)))]
15686 "TARGET_SSE2 && reload_completed"
15687 "maxsd\\t{%2, %0|%0, %2}"
15688 [(set_attr "type" "sse")
15689 (set_attr "mode" "DF")])
15690 \f
15691 ;; Misc patterns (?)
15692
15693 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
15694 ;; Otherwise there will be nothing to keep
15695 ;;
15696 ;; [(set (reg ebp) (reg esp))]
15697 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
15698 ;; (clobber (eflags)]
15699 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
15700 ;;
15701 ;; in proper program order.
15702 (define_expand "pro_epilogue_adjust_stack"
15703 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
15704 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
15705 (match_operand:SI 2 "immediate_operand" "i,i")))
15706 (set (match_operand:SI 3 "register_operand" "+r,r")
15707 (match_dup 3))
15708 (clobber (reg:CC 17))])]
15709 ""
15710 "
15711 {
15712 if (TARGET_64BIT)
15713 {
15714 emit_insn (gen_pro_epilogue_adjust_stack_rex64 (operands[0], operands[1],
15715 operands[2], operands[3]));
15716 DONE;
15717 }
15718 }")
15719
15720 (define_insn "*pro_epilogue_adjust_stack_1"
15721 [(set (match_operand:SI 0 "register_operand" "=r,r")
15722 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
15723 (match_operand:SI 2 "immediate_operand" "i,i")))
15724 (set (match_operand:SI 3 "register_operand" "+r,r")
15725 (match_dup 3))
15726 (clobber (reg:CC 17))]
15727 "!TARGET_64BIT"
15728 "*
15729 {
15730 switch (get_attr_type (insn))
15731 {
15732 case TYPE_IMOV:
15733 return \"mov{l}\\t{%1, %0|%0, %1}\";
15734
15735 case TYPE_ALU:
15736 if (GET_CODE (operands[2]) == CONST_INT
15737 && (INTVAL (operands[2]) == 128
15738 || (INTVAL (operands[2]) < 0
15739 && INTVAL (operands[2]) != -128)))
15740 {
15741 operands[2] = GEN_INT (-INTVAL (operands[2]));
15742 return \"sub{l}\\t{%2, %0|%0, %2}\";
15743 }
15744 return \"add{l}\\t{%2, %0|%0, %2}\";
15745
15746 case TYPE_LEA:
15747 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
15748 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
15749
15750 default:
15751 abort ();
15752 }
15753 }"
15754 [(set (attr "type")
15755 (cond [(eq_attr "alternative" "0")
15756 (const_string "alu")
15757 (match_operand:SI 2 "const0_operand" "")
15758 (const_string "imov")
15759 ]
15760 (const_string "lea")))
15761 (set_attr "mode" "SI")])
15762
15763 (define_insn "pro_epilogue_adjust_stack_rex64"
15764 [(set (match_operand:DI 0 "register_operand" "=r,r")
15765 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
15766 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
15767 (set (match_operand:DI 3 "register_operand" "+r,r")
15768 (match_dup 3))
15769 (clobber (reg:CC 17))]
15770 "TARGET_64BIT"
15771 "*
15772 {
15773 switch (get_attr_type (insn))
15774 {
15775 case TYPE_IMOV:
15776 return \"mov{q}\\t{%1, %0|%0, %1}\";
15777
15778 case TYPE_ALU:
15779 if (GET_CODE (operands[2]) == CONST_INT
15780 && (INTVAL (operands[2]) == 128
15781 || (INTVAL (operands[2]) < 0
15782 && INTVAL (operands[2]) != -128)))
15783 {
15784 operands[2] = GEN_INT (-INTVAL (operands[2]));
15785 return \"sub{q}\\t{%2, %0|%0, %2}\";
15786 }
15787 return \"add{q}\\t{%2, %0|%0, %2}\";
15788
15789 case TYPE_LEA:
15790 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
15791 return \"lea{q}\\t{%a2, %0|%0, %a2}\";
15792
15793 default:
15794 abort ();
15795 }
15796 }"
15797 [(set (attr "type")
15798 (cond [(eq_attr "alternative" "0")
15799 (const_string "alu")
15800 (match_operand:DI 2 "const0_operand" "")
15801 (const_string "imov")
15802 ]
15803 (const_string "lea")))
15804 (set_attr "mode" "DI")])
15805
15806
15807 ;; Placeholder for the conditional moves. This one is split eighter to SSE
15808 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
15809 ;; fact is that compares supported by the cmp??ss instructions are exactly
15810 ;; swapped of those supported by cmove sequence.
15811 ;; The EQ/NE comparisons also needs bit care, since they are not directly
15812 ;; supported by i387 comparisons and we do need to emit two conditional moves
15813 ;; in tandem.
15814
15815 (define_insn "sse_movsfcc"
15816 [(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")
15817 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
15818 [(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")
15819 (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")])
15820 (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")
15821 (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")))
15822 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
15823 (clobber (reg:CC 17))]
15824 "TARGET_SSE
15825 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
15826 && (!TARGET_IEEE_FP
15827 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
15828 "#")
15829
15830 (define_insn "sse_movsfcc_eq"
15831 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
15832 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
15833 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
15834 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
15835 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
15836 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
15837 (clobber (reg:CC 17))]
15838 "TARGET_SSE
15839 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15840 "#")
15841
15842 (define_insn "sse_movdfcc"
15843 [(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")
15844 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
15845 [(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")
15846 (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")])
15847 (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")
15848 (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")))
15849 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
15850 (clobber (reg:CC 17))]
15851 "TARGET_SSE2
15852 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
15853 && (!TARGET_IEEE_FP
15854 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
15855 "#")
15856
15857 (define_insn "sse_movdfcc_eq"
15858 [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
15859 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
15860 (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
15861 (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
15862 (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
15863 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
15864 (clobber (reg:CC 17))]
15865 "TARGET_SSE
15866 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
15867 "#")
15868
15869 ;; For non-sse moves just expand the usual cmove sequence.
15870 (define_split
15871 [(set (match_operand 0 "register_operand" "")
15872 (if_then_else (match_operator 1 "comparison_operator"
15873 [(match_operand 4 "nonimmediate_operand" "")
15874 (match_operand 5 "register_operand" "")])
15875 (match_operand 2 "nonimmediate_operand" "")
15876 (match_operand 3 "nonimmediate_operand" "")))
15877 (clobber (match_operand 6 "" ""))
15878 (clobber (reg:CC 17))]
15879 "!SSE_REG_P (operands[0]) && reload_completed
15880 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
15881 [(const_int 0)]
15882 "
15883 {
15884 ix86_compare_op0 = operands[5];
15885 ix86_compare_op1 = operands[4];
15886 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
15887 VOIDmode, operands[5], operands[4]);
15888 ix86_expand_fp_movcc (operands);
15889 DONE;
15890 }")
15891
15892 ;; Split SSE based conditional move into seqence:
15893 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
15894 ;; and op2, op0 - zero op2 if comparison was false
15895 ;; nand op0, op3 - load op3 to op0 if comparison was false
15896 ;; or op2, op0 - get the non-zero one into the result.
15897 (define_split
15898 [(set (match_operand 0 "register_operand" "")
15899 (if_then_else (match_operator 1 "sse_comparison_operator"
15900 [(match_operand 4 "register_operand" "")
15901 (match_operand 5 "nonimmediate_operand" "")])
15902 (match_operand 2 "register_operand" "")
15903 (match_operand 3 "register_operand" "")))
15904 (clobber (match_operand 6 "" ""))
15905 (clobber (reg:CC 17))]
15906 "SSE_REG_P (operands[0]) && reload_completed"
15907 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
15908 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
15909 (subreg:TI (match_dup 4) 0)))
15910 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
15911 (subreg:TI (match_dup 3) 0)))
15912 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
15913 (subreg:TI (match_dup 7) 0)))]
15914 "
15915 {
15916 PUT_MODE (operands[1], GET_MODE (operands[0]));
15917 if (operands_match_p (operands[0], operands[4]))
15918 operands[6] = operands[4], operands[7] = operands[2];
15919 else
15920 operands[6] = operands[2], operands[7] = operands[4];
15921 }")
15922
15923 ;; Special case of conditional move we can handle effectivly.
15924 ;; Do not brother with the integer/floating point case, since these are
15925 ;; bot considerably slower, unlike in the generic case.
15926 (define_insn "*sse_movsfcc_const0_1"
15927 [(set (match_operand:SF 0 "register_operand" "=x")
15928 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
15929 [(match_operand:SF 4 "register_operand" "0")
15930 (match_operand:SF 5 "nonimmediate_operand" "xm")])
15931 (match_operand:SF 2 "register_operand" "x")
15932 (match_operand:SF 3 "const0_operand" "X")))]
15933 "TARGET_SSE"
15934 "#")
15935
15936 (define_insn "*sse_movsfcc_const0_2"
15937 [(set (match_operand:SF 0 "register_operand" "=x")
15938 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
15939 [(match_operand:SF 4 "register_operand" "0")
15940 (match_operand:SF 5 "nonimmediate_operand" "xm")])
15941 (match_operand:SF 2 "const0_operand" "x")
15942 (match_operand:SF 3 "register_operand" "X")))]
15943 "TARGET_SSE"
15944 "#")
15945
15946 (define_insn "*sse_movsfcc_const0_3"
15947 [(set (match_operand:SF 0 "register_operand" "=x")
15948 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15949 [(match_operand:SF 4 "nonimmediate_operand" "xm")
15950 (match_operand:SF 5 "register_operand" "0")])
15951 (match_operand:SF 2 "register_operand" "x")
15952 (match_operand:SF 3 "const0_operand" "X")))]
15953 "TARGET_SSE"
15954 "#")
15955
15956 (define_insn "*sse_movsfcc_const0_4"
15957 [(set (match_operand:SF 0 "register_operand" "=x")
15958 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15959 [(match_operand:SF 4 "nonimmediate_operand" "xm")
15960 (match_operand:SF 5 "register_operand" "0")])
15961 (match_operand:SF 2 "const0_operand" "x")
15962 (match_operand:SF 3 "register_operand" "X")))]
15963 "TARGET_SSE"
15964 "#")
15965
15966 (define_insn "*sse_movdfcc_const0_1"
15967 [(set (match_operand:SF 0 "register_operand" "=x")
15968 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
15969 [(match_operand:SF 4 "register_operand" "0")
15970 (match_operand:SF 5 "nonimmediate_operand" "xm")])
15971 (match_operand:SF 2 "register_operand" "x")
15972 (match_operand:SF 3 "const0_operand" "X")))]
15973 "TARGET_SSE2"
15974 "#")
15975
15976 (define_insn "*sse_movdfcc_const0_2"
15977 [(set (match_operand:SF 0 "register_operand" "=x")
15978 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
15979 [(match_operand:SF 4 "register_operand" "0")
15980 (match_operand:SF 5 "nonimmediate_operand" "xm")])
15981 (match_operand:SF 2 "const0_operand" "x")
15982 (match_operand:SF 3 "register_operand" "X")))]
15983 "TARGET_SSE2"
15984 "#")
15985
15986 (define_insn "*sse_movdfcc_const0_3"
15987 [(set (match_operand:SF 0 "register_operand" "=x")
15988 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15989 [(match_operand:SF 4 "nonimmediate_operand" "xm")
15990 (match_operand:SF 5 "register_operand" "0")])
15991 (match_operand:SF 2 "register_operand" "x")
15992 (match_operand:SF 3 "const0_operand" "X")))]
15993 "TARGET_SSE2"
15994 "#")
15995
15996 (define_insn "*sse_movdfcc_const0_4"
15997 [(set (match_operand:SF 0 "register_operand" "=x")
15998 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15999 [(match_operand:SF 4 "nonimmediate_operand" "xm")
16000 (match_operand:SF 5 "register_operand" "0")])
16001 (match_operand:SF 2 "const0_operand" "x")
16002 (match_operand:SF 3 "register_operand" "X")))]
16003 "TARGET_SSE2"
16004 "#")
16005
16006 (define_split
16007 [(set (match_operand 0 "register_operand" "")
16008 (if_then_else (match_operator 1 "comparison_operator"
16009 [(match_operand 4 "register_operand" "")
16010 (match_operand 5 "nonimmediate_operand" "")])
16011 (match_operand 2 "nonmemory_operand" "")
16012 (match_operand 3 "nonmemory_operand" "")))]
16013 "SSE_REG_P (operands[0]) && reload_completed
16014 && (const0_operand (operands[2], GET_MODE (operands[0]))
16015 || const0_operand (operands[3], GET_MODE (operands[0])))"
16016 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
16017 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
16018 (subreg:TI (match_dup 7) 0)))]
16019 "
16020 {
16021 PUT_MODE (operands[1], GET_MODE (operands[0]));
16022 if (!sse_comparison_operator (operands[1], VOIDmode))
16023 {
16024 rtx tmp = operands[5];
16025 operands[5] = operands[4];
16026 operands[4] = tmp;
16027 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
16028 }
16029 if (const0_operand (operands[2], GET_MODE (operands[0])))
16030 {
16031 operands[7] = operands[3];
16032 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
16033 0));
16034 }
16035 else
16036 {
16037 operands[7] = operands[2];
16038 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
16039 }
16040 }")
16041
16042 (define_expand "allocate_stack_worker"
16043 [(match_operand:SI 0 "register_operand" "")]
16044 "TARGET_STACK_PROBE"
16045 "
16046 {
16047 if (TARGET_64BIT)
16048 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
16049 else
16050 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
16051 DONE;
16052 }")
16053
16054 (define_insn "allocate_stack_worker_1"
16055 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
16056 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
16057 (clobber (match_dup 0))
16058 (clobber (reg:CC 17))]
16059 "TARGET_STACK_PROBE && !TARGET_64BIT"
16060 "call\\t__alloca"
16061 [(set_attr "type" "multi")
16062 (set_attr "length" "5")])
16063
16064 (define_insn "allocate_stack_worker_rex64"
16065 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
16066 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
16067 (clobber (match_dup 0))
16068 (clobber (reg:CC 17))]
16069 "TARGET_STACK_PROBE && TARGET_64BIT"
16070 "call\\t__alloca"
16071 [(set_attr "type" "multi")
16072 (set_attr "length" "5")])
16073
16074 (define_expand "allocate_stack"
16075 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
16076 (minus:SI (reg:SI 7)
16077 (match_operand:SI 1 "general_operand" "")))
16078 (clobber (reg:CC 17))])
16079 (parallel [(set (reg:SI 7)
16080 (minus:SI (reg:SI 7) (match_dup 1)))
16081 (clobber (reg:CC 17))])]
16082 "TARGET_STACK_PROBE"
16083 "
16084 {
16085 #ifdef CHECK_STACK_LIMIT
16086 if (GET_CODE (operands[1]) == CONST_INT
16087 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16088 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
16089 operands[1]));
16090 else
16091 #endif
16092 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
16093 operands[1])));
16094
16095 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16096 DONE;
16097 }")
16098
16099 (define_expand "builtin_setjmp_receiver"
16100 [(label_ref (match_operand 0 "" ""))]
16101 "flag_pic && !TARGET_64BIT"
16102 "
16103 {
16104 load_pic_register ();
16105 DONE;
16106 }")
16107 \f
16108 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16109
16110 (define_split
16111 [(set (match_operand 0 "register_operand" "")
16112 (match_operator 3 "promotable_binary_operator"
16113 [(match_operand 1 "register_operand" "")
16114 (match_operand 2 "aligned_operand" "")]))
16115 (clobber (reg:CC 17))]
16116 "! TARGET_PARTIAL_REG_STALL && reload_completed
16117 && ((GET_MODE (operands[0]) == HImode
16118 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
16119 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
16120 || (GET_MODE (operands[0]) == QImode
16121 && (TARGET_PROMOTE_QImode || optimize_size)))"
16122 [(parallel [(set (match_dup 0)
16123 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16124 (clobber (reg:CC 17))])]
16125 "operands[0] = gen_lowpart (SImode, operands[0]);
16126 operands[1] = gen_lowpart (SImode, operands[1]);
16127 if (GET_CODE (operands[3]) != ASHIFT)
16128 operands[2] = gen_lowpart (SImode, operands[2]);
16129 PUT_MODE (operands[3], SImode);")
16130
16131 (define_split
16132 [(set (reg 17)
16133 (compare (and (match_operand 1 "aligned_operand" "")
16134 (match_operand 2 "const_int_operand" ""))
16135 (const_int 0)))
16136 (set (match_operand 0 "register_operand" "")
16137 (and (match_dup 1) (match_dup 2)))]
16138 "! TARGET_PARTIAL_REG_STALL && reload_completed
16139 && ix86_match_ccmode (insn, CCNOmode)
16140 && (GET_MODE (operands[0]) == HImode
16141 || (GET_MODE (operands[0]) == QImode
16142 && (TARGET_PROMOTE_QImode || optimize_size)))"
16143 [(parallel [(set (reg:CCNO 17)
16144 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
16145 (const_int 0)))
16146 (set (match_dup 0)
16147 (and:SI (match_dup 1) (match_dup 2)))])]
16148 "operands[2]
16149 = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
16150 & GET_MODE_MASK (GET_MODE (operands[0])),
16151 SImode));
16152 operands[0] = gen_lowpart (SImode, operands[0]);
16153 operands[1] = gen_lowpart (SImode, operands[1]);")
16154
16155 (define_split
16156 [(set (reg 17)
16157 (compare (and (match_operand 0 "aligned_operand" "")
16158 (match_operand 1 "const_int_operand" ""))
16159 (const_int 0)))]
16160 "! TARGET_PARTIAL_REG_STALL && reload_completed
16161 && ix86_match_ccmode (insn, CCNOmode)
16162 && (GET_MODE (operands[0]) == HImode
16163 || (GET_MODE (operands[0]) == QImode
16164 && (TARGET_PROMOTE_QImode || optimize_size)))"
16165 [(set (reg:CCNO 17)
16166 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
16167 (const_int 0)))]
16168 "operands[1]
16169 = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
16170 & GET_MODE_MASK (GET_MODE (operands[0])),
16171 SImode));
16172 operands[0] = gen_lowpart (SImode, operands[0]);")
16173
16174 (define_split
16175 [(set (match_operand 0 "register_operand" "")
16176 (neg (match_operand 1 "register_operand" "")))
16177 (clobber (reg:CC 17))]
16178 "! TARGET_PARTIAL_REG_STALL && reload_completed
16179 && (GET_MODE (operands[0]) == HImode
16180 || (GET_MODE (operands[0]) == QImode
16181 && (TARGET_PROMOTE_QImode || optimize_size)))"
16182 [(parallel [(set (match_dup 0)
16183 (neg:SI (match_dup 1)))
16184 (clobber (reg:CC 17))])]
16185 "operands[0] = gen_lowpart (SImode, operands[0]);
16186 operands[1] = gen_lowpart (SImode, operands[1]);")
16187
16188 (define_split
16189 [(set (match_operand 0 "register_operand" "")
16190 (not (match_operand 1 "register_operand" "")))]
16191 "! TARGET_PARTIAL_REG_STALL && reload_completed
16192 && (GET_MODE (operands[0]) == HImode
16193 || (GET_MODE (operands[0]) == QImode
16194 && (TARGET_PROMOTE_QImode || optimize_size)))"
16195 [(set (match_dup 0)
16196 (not:SI (match_dup 1)))]
16197 "operands[0] = gen_lowpart (SImode, operands[0]);
16198 operands[1] = gen_lowpart (SImode, operands[1]);")
16199
16200 (define_split
16201 [(set (match_operand 0 "register_operand" "")
16202 (if_then_else (match_operator 1 "comparison_operator"
16203 [(reg 17) (const_int 0)])
16204 (match_operand 2 "register_operand" "")
16205 (match_operand 3 "register_operand" "")))]
16206 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16207 && (GET_MODE (operands[0]) == HImode
16208 || (GET_MODE (operands[0]) == QImode
16209 && (TARGET_PROMOTE_QImode || optimize_size)))"
16210 [(set (match_dup 0)
16211 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16212 "operands[0] = gen_lowpart (SImode, operands[0]);
16213 operands[2] = gen_lowpart (SImode, operands[2]);
16214 operands[3] = gen_lowpart (SImode, operands[3]);")
16215
16216 \f
16217 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16218 ;; transform a complex memory operation into two memory to register operations.
16219
16220 ;; Don't push memory operands
16221 (define_peephole2
16222 [(set (match_operand:SI 0 "push_operand" "")
16223 (match_operand:SI 1 "memory_operand" ""))
16224 (match_scratch:SI 2 "r")]
16225 "! optimize_size && ! TARGET_PUSH_MEMORY"
16226 [(set (match_dup 2) (match_dup 1))
16227 (set (match_dup 0) (match_dup 2))]
16228 "")
16229
16230 (define_peephole2
16231 [(set (match_operand:DI 0 "push_operand" "")
16232 (match_operand:DI 1 "memory_operand" ""))
16233 (match_scratch:DI 2 "r")]
16234 "! optimize_size && ! TARGET_PUSH_MEMORY"
16235 [(set (match_dup 2) (match_dup 1))
16236 (set (match_dup 0) (match_dup 2))]
16237 "")
16238
16239 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16240 ;; SImode pushes.
16241 (define_peephole2
16242 [(set (match_operand:SF 0 "push_operand" "")
16243 (match_operand:SF 1 "memory_operand" ""))
16244 (match_scratch:SF 2 "r")]
16245 "! optimize_size && ! TARGET_PUSH_MEMORY"
16246 [(set (match_dup 2) (match_dup 1))
16247 (set (match_dup 0) (match_dup 2))]
16248 "")
16249
16250 (define_peephole2
16251 [(set (match_operand:HI 0 "push_operand" "")
16252 (match_operand:HI 1 "memory_operand" ""))
16253 (match_scratch:HI 2 "r")]
16254 "! optimize_size && ! TARGET_PUSH_MEMORY"
16255 [(set (match_dup 2) (match_dup 1))
16256 (set (match_dup 0) (match_dup 2))]
16257 "")
16258
16259 (define_peephole2
16260 [(set (match_operand:QI 0 "push_operand" "")
16261 (match_operand:QI 1 "memory_operand" ""))
16262 (match_scratch:QI 2 "q")]
16263 "! optimize_size && ! TARGET_PUSH_MEMORY"
16264 [(set (match_dup 2) (match_dup 1))
16265 (set (match_dup 0) (match_dup 2))]
16266 "")
16267
16268 ;; Don't move an immediate directly to memory when the instruction
16269 ;; gets too big.
16270 (define_peephole2
16271 [(match_scratch:SI 1 "r")
16272 (set (match_operand:SI 0 "memory_operand" "")
16273 (const_int 0))]
16274 "! optimize_size
16275 && ! TARGET_USE_MOV0
16276 && TARGET_SPLIT_LONG_MOVES
16277 && get_attr_length (insn) >= ix86_cost->large_insn
16278 && peep2_regno_dead_p (0, FLAGS_REG)"
16279 [(parallel [(set (match_dup 1) (const_int 0))
16280 (clobber (reg:CC 17))])
16281 (set (match_dup 0) (match_dup 1))]
16282 "")
16283
16284 (define_peephole2
16285 [(match_scratch:HI 1 "r")
16286 (set (match_operand:HI 0 "memory_operand" "")
16287 (const_int 0))]
16288 "! optimize_size
16289 && ! TARGET_USE_MOV0
16290 && TARGET_SPLIT_LONG_MOVES
16291 && get_attr_length (insn) >= ix86_cost->large_insn
16292 && peep2_regno_dead_p (0, FLAGS_REG)"
16293 [(parallel [(set (match_dup 2) (const_int 0))
16294 (clobber (reg:CC 17))])
16295 (set (match_dup 0) (match_dup 1))]
16296 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16297
16298 (define_peephole2
16299 [(match_scratch:QI 1 "q")
16300 (set (match_operand:QI 0 "memory_operand" "")
16301 (const_int 0))]
16302 "! optimize_size
16303 && ! TARGET_USE_MOV0
16304 && TARGET_SPLIT_LONG_MOVES
16305 && get_attr_length (insn) >= ix86_cost->large_insn
16306 && peep2_regno_dead_p (0, FLAGS_REG)"
16307 [(parallel [(set (match_dup 2) (const_int 0))
16308 (clobber (reg:CC 17))])
16309 (set (match_dup 0) (match_dup 1))]
16310 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
16311
16312 (define_peephole2
16313 [(match_scratch:SI 2 "r")
16314 (set (match_operand:SI 0 "memory_operand" "")
16315 (match_operand:SI 1 "immediate_operand" ""))]
16316 "! optimize_size
16317 && get_attr_length (insn) >= ix86_cost->large_insn
16318 && TARGET_SPLIT_LONG_MOVES"
16319 [(set (match_dup 2) (match_dup 1))
16320 (set (match_dup 0) (match_dup 2))]
16321 "")
16322
16323 (define_peephole2
16324 [(match_scratch:HI 2 "r")
16325 (set (match_operand:HI 0 "memory_operand" "")
16326 (match_operand:HI 1 "immediate_operand" ""))]
16327 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16328 && TARGET_SPLIT_LONG_MOVES"
16329 [(set (match_dup 2) (match_dup 1))
16330 (set (match_dup 0) (match_dup 2))]
16331 "")
16332
16333 (define_peephole2
16334 [(match_scratch:QI 2 "q")
16335 (set (match_operand:QI 0 "memory_operand" "")
16336 (match_operand:QI 1 "immediate_operand" ""))]
16337 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
16338 && TARGET_SPLIT_LONG_MOVES"
16339 [(set (match_dup 2) (match_dup 1))
16340 (set (match_dup 0) (match_dup 2))]
16341 "")
16342
16343 ;; Don't compare memory with zero, load and use a test instead.
16344 (define_peephole2
16345 [(set (reg 17)
16346 (compare (match_operand:SI 0 "memory_operand" "")
16347 (const_int 0)))
16348 (match_scratch:SI 3 "r")]
16349 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
16350 [(set (match_dup 3) (match_dup 0))
16351 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
16352 "")
16353
16354 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16355 ;; Don't split NOTs with a displacement operand, because resulting XOR
16356 ;; will not be pariable anyway.
16357 ;;
16358 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
16359 ;; represented using a modRM byte. The XOR replacement is long decoded,
16360 ;; so this split helps here as well.
16361 ;;
16362 ;; Note: Can't do this as a regular split because we can't get proper
16363 ;; lifetime information then.
16364
16365 (define_peephole2
16366 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
16367 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
16368 "!optimize_size
16369 && peep2_regno_dead_p (0, FLAGS_REG)
16370 && ((TARGET_PENTIUM
16371 && (GET_CODE (operands[0]) != MEM
16372 || !memory_displacement_operand (operands[0], SImode)))
16373 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
16374 [(parallel [(set (match_dup 0)
16375 (xor:SI (match_dup 1) (const_int -1)))
16376 (clobber (reg:CC 17))])]
16377 "")
16378
16379 (define_peephole2
16380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
16381 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
16382 "!optimize_size
16383 && peep2_regno_dead_p (0, FLAGS_REG)
16384 && ((TARGET_PENTIUM
16385 && (GET_CODE (operands[0]) != MEM
16386 || !memory_displacement_operand (operands[0], HImode)))
16387 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
16388 [(parallel [(set (match_dup 0)
16389 (xor:HI (match_dup 1) (const_int -1)))
16390 (clobber (reg:CC 17))])]
16391 "")
16392
16393 (define_peephole2
16394 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
16395 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
16396 "!optimize_size
16397 && peep2_regno_dead_p (0, FLAGS_REG)
16398 && ((TARGET_PENTIUM
16399 && (GET_CODE (operands[0]) != MEM
16400 || !memory_displacement_operand (operands[0], QImode)))
16401 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
16402 [(parallel [(set (match_dup 0)
16403 (xor:QI (match_dup 1) (const_int -1)))
16404 (clobber (reg:CC 17))])]
16405 "")
16406
16407 ;; Non pairable "test imm, reg" instructions can be translated to
16408 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16409 ;; byte opcode instead of two, have a short form for byte operands),
16410 ;; so do it for other CPUs as well. Given that the value was dead,
16411 ;; this should not create any new dependancies. Pass on the sub-word
16412 ;; versions if we're concerned about partial register stalls.
16413
16414 (define_peephole2
16415 [(set (reg 17)
16416 (compare (and:SI (match_operand:SI 0 "register_operand" "")
16417 (match_operand:SI 1 "immediate_operand" ""))
16418 (const_int 0)))]
16419 "ix86_match_ccmode (insn, CCNOmode)
16420 && (true_regnum (operands[0]) != 0
16421 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
16422 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16423 [(parallel
16424 [(set (reg:CCNO 17)
16425 (compare:CCNO (and:SI (match_dup 0)
16426 (match_dup 1))
16427 (const_int 0)))
16428 (set (match_dup 0)
16429 (and:SI (match_dup 0) (match_dup 1)))])]
16430 "")
16431
16432 ;; We don't need to handle HImode case, because it will be promoted to SImode
16433 ;; on ! TARGET_PARTIAL_REG_STALL
16434
16435 (define_peephole2
16436 [(set (reg 17)
16437 (compare (and:QI (match_operand:QI 0 "register_operand" "")
16438 (match_operand:QI 1 "immediate_operand" ""))
16439 (const_int 0)))]
16440 "! TARGET_PARTIAL_REG_STALL
16441 && ix86_match_ccmode (insn, CCNOmode)
16442 && true_regnum (operands[0]) != 0
16443 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16444 [(parallel
16445 [(set (reg:CCNO 17)
16446 (compare:CCNO (and:QI (match_dup 0)
16447 (match_dup 1))
16448 (const_int 0)))
16449 (set (match_dup 0)
16450 (and:QI (match_dup 0) (match_dup 1)))])]
16451 "")
16452
16453 (define_peephole2
16454 [(set (reg 17)
16455 (compare
16456 (and:SI
16457 (zero_extract:SI
16458 (match_operand 0 "ext_register_operand" "q")
16459 (const_int 8)
16460 (const_int 8))
16461 (match_operand 1 "const_int_operand" "n"))
16462 (const_int 0)))]
16463 "! TARGET_PARTIAL_REG_STALL
16464 && ix86_match_ccmode (insn, CCNOmode)
16465 && true_regnum (operands[0]) != 0
16466 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16467 [(parallel [(set (reg:CCNO 17)
16468 (compare:CCNO
16469 (and:SI
16470 (zero_extract:SI
16471 (match_dup 0)
16472 (const_int 8)
16473 (const_int 8))
16474 (match_dup 1))
16475 (const_int 0)))
16476 (set (zero_extract:SI (match_dup 0)
16477 (const_int 8)
16478 (const_int 8))
16479 (and:SI
16480 (zero_extract:SI
16481 (match_dup 0)
16482 (const_int 8)
16483 (const_int 8))
16484 (match_dup 1)))])]
16485 "")
16486
16487 ;; Don't do logical operations with memory inputs.
16488 (define_peephole2
16489 [(match_scratch:SI 2 "r")
16490 (parallel [(set (match_operand:SI 0 "register_operand" "")
16491 (match_operator:SI 3 "arith_or_logical_operator"
16492 [(match_dup 0)
16493 (match_operand:SI 1 "memory_operand" "")]))
16494 (clobber (reg:CC 17))])]
16495 "! optimize_size && ! TARGET_READ_MODIFY"
16496 [(set (match_dup 2) (match_dup 1))
16497 (parallel [(set (match_dup 0)
16498 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16499 (clobber (reg:CC 17))])]
16500 "")
16501
16502 (define_peephole2
16503 [(match_scratch:SI 2 "r")
16504 (parallel [(set (match_operand:SI 0 "register_operand" "")
16505 (match_operator:SI 3 "arith_or_logical_operator"
16506 [(match_operand:SI 1 "memory_operand" "")
16507 (match_dup 0)]))
16508 (clobber (reg:CC 17))])]
16509 "! optimize_size && ! TARGET_READ_MODIFY"
16510 [(set (match_dup 2) (match_dup 1))
16511 (parallel [(set (match_dup 0)
16512 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16513 (clobber (reg:CC 17))])]
16514 "")
16515
16516 ; Don't do logical operations with memory outputs
16517 ;
16518 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16519 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16520 ; the same decoder scheduling characteristics as the original.
16521
16522 (define_peephole2
16523 [(match_scratch:SI 2 "r")
16524 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16525 (match_operator:SI 3 "arith_or_logical_operator"
16526 [(match_dup 0)
16527 (match_operand:SI 1 "nonmemory_operand" "")]))
16528 (clobber (reg:CC 17))])]
16529 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16530 [(set (match_dup 2) (match_dup 0))
16531 (parallel [(set (match_dup 2)
16532 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16533 (clobber (reg:CC 17))])
16534 (set (match_dup 0) (match_dup 2))]
16535 "")
16536
16537 (define_peephole2
16538 [(match_scratch:SI 2 "r")
16539 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16540 (match_operator:SI 3 "arith_or_logical_operator"
16541 [(match_operand:SI 1 "nonmemory_operand" "")
16542 (match_dup 0)]))
16543 (clobber (reg:CC 17))])]
16544 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
16545 [(set (match_dup 2) (match_dup 0))
16546 (parallel [(set (match_dup 2)
16547 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16548 (clobber (reg:CC 17))])
16549 (set (match_dup 0) (match_dup 2))]
16550 "")
16551
16552 ;; Attempt to always use XOR for zeroing registers.
16553 (define_peephole2
16554 [(set (match_operand 0 "register_operand" "")
16555 (const_int 0))]
16556 "(GET_MODE (operands[0]) == QImode
16557 || GET_MODE (operands[0]) == HImode
16558 || GET_MODE (operands[0]) == SImode
16559 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16560 && (! TARGET_USE_MOV0 || optimize_size)
16561 && peep2_regno_dead_p (0, FLAGS_REG)"
16562 [(parallel [(set (match_dup 0) (const_int 0))
16563 (clobber (reg:CC 17))])]
16564 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16565 true_regnum (operands[0]));")
16566
16567 (define_peephole2
16568 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16569 (const_int 0))]
16570 "(GET_MODE (operands[0]) == QImode
16571 || GET_MODE (operands[0]) == HImode)
16572 && (! TARGET_USE_MOV0 || optimize_size)
16573 && peep2_regno_dead_p (0, FLAGS_REG)"
16574 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16575 (clobber (reg:CC 17))])])
16576
16577 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
16578 (define_peephole2
16579 [(set (match_operand 0 "register_operand" "")
16580 (const_int -1))]
16581 "(GET_MODE (operands[0]) == HImode
16582 || GET_MODE (operands[0]) == SImode
16583 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
16584 && (optimize_size || TARGET_PENTIUM)
16585 && peep2_regno_dead_p (0, FLAGS_REG)"
16586 [(parallel [(set (match_dup 0) (const_int -1))
16587 (clobber (reg:CC 17))])]
16588 "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
16589 true_regnum (operands[0]));")
16590
16591 ;; Attempt to convert simple leas to adds. These can be created by
16592 ;; move expanders.
16593 (define_peephole2
16594 [(set (match_operand:SI 0 "register_operand" "")
16595 (plus:SI (match_dup 0)
16596 (match_operand:SI 1 "nonmemory_operand" "")))]
16597 "peep2_regno_dead_p (0, FLAGS_REG)"
16598 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
16599 (clobber (reg:CC 17))])]
16600 "")
16601
16602 (define_peephole2
16603 [(set (match_operand:SI 0 "register_operand" "")
16604 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16605 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16606 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
16607 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16608 (clobber (reg:CC 17))])]
16609 "operands[2] = gen_lowpart (SImode, operands[2]);")
16610
16611 (define_peephole2
16612 [(set (match_operand:DI 0 "register_operand" "")
16613 (plus:DI (match_dup 0)
16614 (match_operand:DI 1 "x86_64_general_operand" "")))]
16615 "peep2_regno_dead_p (0, FLAGS_REG)"
16616 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
16617 (clobber (reg:CC 17))])]
16618 "")
16619
16620 (define_peephole2
16621 [(set (match_operand:SI 0 "register_operand" "")
16622 (mult:SI (match_dup 0)
16623 (match_operand:SI 1 "const_int_operand" "")))]
16624 "exact_log2 (INTVAL (operands[1])) >= 0
16625 && peep2_regno_dead_p (0, FLAGS_REG)"
16626 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16627 (clobber (reg:CC 17))])]
16628 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16629
16630 (define_peephole2
16631 [(set (match_operand:DI 0 "register_operand" "")
16632 (mult:DI (match_dup 0)
16633 (match_operand:DI 1 "const_int_operand" "")))]
16634 "exact_log2 (INTVAL (operands[1])) >= 0
16635 && peep2_regno_dead_p (0, FLAGS_REG)"
16636 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
16637 (clobber (reg:CC 17))])]
16638 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16639
16640 (define_peephole2
16641 [(set (match_operand:SI 0 "register_operand" "")
16642 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16643 (match_operand:DI 2 "const_int_operand" "")) 0))]
16644 "exact_log2 (INTVAL (operands[1])) >= 0
16645 && REGNO (operands[0]) == REGNO (operands[1])
16646 && peep2_regno_dead_p (0, FLAGS_REG)"
16647 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16648 (clobber (reg:CC 17))])]
16649 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16650
16651 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16652 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
16653 ;; many CPUs it is also faster, since special hardware to avoid esp
16654 ;; dependancies is present.
16655
16656 ;; While some of these converisons may be done using splitters, we use peepholes
16657 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
16658
16659 ;; Convert prologue esp substractions to push.
16660 ;; We need register to push. In order to keep verify_flow_info happy we have
16661 ;; two choices
16662 ;; - use scratch and clobber it in order to avoid dependencies
16663 ;; - use already live register
16664 ;; We can't use the second way right now, since there is no reliable way how to
16665 ;; verify that given register is live. First choice will also most likely in
16666 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16667 ;; call clobbered registers are dead. We may want to use base pointer as an
16668 ;; alternative when no register is available later.
16669
16670 (define_peephole2
16671 [(match_scratch:SI 0 "r")
16672 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
16673 (set (reg:SI 6) (reg:SI 6))
16674 (clobber (reg:CC 17))])]
16675 "optimize_size || !TARGET_SUB_ESP_4"
16676 [(clobber (match_dup 0))
16677 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16678 (set (reg:SI 6) (reg:SI 6))])])
16679
16680 (define_peephole2
16681 [(match_scratch:SI 0 "r")
16682 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
16683 (set (reg:SI 6) (reg:SI 6))
16684 (clobber (reg:CC 17))])]
16685 "optimize_size || !TARGET_SUB_ESP_8"
16686 [(clobber (match_dup 0))
16687 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16688 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16689 (set (reg:SI 6) (reg:SI 6))])])
16690
16691 ;; Convert esp substractions to push.
16692 (define_peephole2
16693 [(match_scratch:SI 0 "r")
16694 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
16695 (clobber (reg:CC 17))])]
16696 "optimize_size || !TARGET_SUB_ESP_4"
16697 [(clobber (match_dup 0))
16698 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
16699
16700 (define_peephole2
16701 [(match_scratch:SI 0 "r")
16702 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
16703 (clobber (reg:CC 17))])]
16704 "optimize_size || !TARGET_SUB_ESP_8"
16705 [(clobber (match_dup 0))
16706 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
16707 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
16708
16709 ;; Convert epilogue deallocator to pop.
16710 (define_peephole2
16711 [(match_scratch:SI 0 "r")
16712 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16713 (set (reg:SI 6) (reg:SI 6))
16714 (clobber (reg:CC 17))])]
16715 "optimize_size || !TARGET_ADD_ESP_4"
16716 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16717 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16718 (set (reg:SI 6) (reg:SI 6))])]
16719 "")
16720
16721 ;; Two pops case is tricky, since pop causes dependency on destination register.
16722 ;; We use two registers if available.
16723 (define_peephole2
16724 [(match_scratch:SI 0 "r")
16725 (match_scratch:SI 1 "r")
16726 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16727 (set (reg:SI 6) (reg:SI 6))
16728 (clobber (reg:CC 17))])]
16729 "optimize_size || !TARGET_ADD_ESP_8"
16730 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16731 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16732 (set (reg:SI 6) (reg:SI 6))])
16733 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
16734 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16735 "")
16736
16737 (define_peephole2
16738 [(match_scratch:SI 0 "r")
16739 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16740 (set (reg:SI 6) (reg:SI 6))
16741 (clobber (reg:CC 17))])]
16742 "optimize_size"
16743 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16744 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16745 (set (reg:SI 6) (reg:SI 6))])
16746 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16747 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16748 "")
16749
16750 ;; Convert esp additions to pop.
16751 (define_peephole2
16752 [(match_scratch:SI 0 "r")
16753 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
16754 (clobber (reg:CC 17))])]
16755 ""
16756 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16757 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16758 "")
16759
16760 ;; Two pops case is tricky, since pop causes dependency on destination register.
16761 ;; We use two registers if available.
16762 (define_peephole2
16763 [(match_scratch:SI 0 "r")
16764 (match_scratch:SI 1 "r")
16765 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16766 (clobber (reg:CC 17))])]
16767 ""
16768 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16769 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
16770 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
16771 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16772 "")
16773
16774 (define_peephole2
16775 [(match_scratch:SI 0 "r")
16776 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
16777 (clobber (reg:CC 17))])]
16778 "optimize_size"
16779 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16780 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
16781 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
16782 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
16783 "")
16784 \f
16785 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16786 ;; required and register dies.
16787 (define_peephole2
16788 [(set (reg 17)
16789 (compare (match_operand:SI 0 "register_operand" "")
16790 (match_operand:SI 1 "incdec_operand" "")))]
16791 "ix86_match_ccmode (insn, CCGCmode)
16792 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16793 [(parallel [(set (reg:CCGC 17)
16794 (compare:CCGC (match_dup 0)
16795 (match_dup 1)))
16796 (clobber (match_dup 0))])]
16797 "")
16798
16799 (define_peephole2
16800 [(set (reg 17)
16801 (compare (match_operand:HI 0 "register_operand" "")
16802 (match_operand:HI 1 "incdec_operand" "")))]
16803 "ix86_match_ccmode (insn, CCGCmode)
16804 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16805 [(parallel [(set (reg:CCGC 17)
16806 (compare:CCGC (match_dup 0)
16807 (match_dup 1)))
16808 (clobber (match_dup 0))])]
16809 "")
16810
16811 (define_peephole2
16812 [(set (reg 17)
16813 (compare (match_operand:QI 0 "register_operand" "")
16814 (match_operand:QI 1 "incdec_operand" "")))]
16815 "ix86_match_ccmode (insn, CCGCmode)
16816 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16817 [(parallel [(set (reg:CCGC 17)
16818 (compare:CCGC (match_dup 0)
16819 (match_dup 1)))
16820 (clobber (match_dup 0))])]
16821 "")
16822
16823 ;; Convert compares with 128 to shorter add -128
16824 (define_peephole2
16825 [(set (reg 17)
16826 (compare (match_operand:SI 0 "register_operand" "")
16827 (const_int 128)))]
16828 "ix86_match_ccmode (insn, CCGCmode)
16829 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16830 [(parallel [(set (reg:CCGC 17)
16831 (compare:CCGC (match_dup 0)
16832 (const_int 128)))
16833 (clobber (match_dup 0))])]
16834 "")
16835
16836 (define_peephole2
16837 [(set (reg 17)
16838 (compare (match_operand:HI 0 "register_operand" "")
16839 (const_int 128)))]
16840 "ix86_match_ccmode (insn, CCGCmode)
16841 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
16842 [(parallel [(set (reg:CCGC 17)
16843 (compare:CCGC (match_dup 0)
16844 (const_int 128)))
16845 (clobber (match_dup 0))])]
16846 "")
16847 \f
16848 (define_peephole2
16849 [(match_scratch:DI 0 "r")
16850 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
16851 (set (reg:DI 6) (reg:DI 6))
16852 (clobber (reg:CC 17))])]
16853 "optimize_size || !TARGET_SUB_ESP_4"
16854 [(clobber (match_dup 0))
16855 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
16856 (set (reg:DI 6) (reg:DI 6))])])
16857
16858 (define_peephole2
16859 [(match_scratch:DI 0 "r")
16860 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
16861 (set (reg:DI 6) (reg:DI 6))
16862 (clobber (reg:CC 17))])]
16863 "optimize_size || !TARGET_SUB_ESP_8"
16864 [(clobber (match_dup 0))
16865 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
16866 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
16867 (set (reg:DI 6) (reg:DI 6))])])
16868
16869 ;; Convert esp substractions to push.
16870 (define_peephole2
16871 [(match_scratch:DI 0 "r")
16872 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
16873 (clobber (reg:CC 17))])]
16874 "optimize_size || !TARGET_SUB_ESP_4"
16875 [(clobber (match_dup 0))
16876 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
16877
16878 (define_peephole2
16879 [(match_scratch:DI 0 "r")
16880 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
16881 (clobber (reg:CC 17))])]
16882 "optimize_size || !TARGET_SUB_ESP_8"
16883 [(clobber (match_dup 0))
16884 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
16885 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
16886
16887 ;; Convert epilogue deallocator to pop.
16888 (define_peephole2
16889 [(match_scratch:DI 0 "r")
16890 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
16891 (set (reg:DI 6) (reg:DI 6))
16892 (clobber (reg:CC 17))])]
16893 "optimize_size || !TARGET_ADD_ESP_4"
16894 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16895 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
16896 (set (reg:DI 6) (reg:DI 6))])]
16897 "")
16898
16899 ;; Two pops case is tricky, since pop causes dependency on destination register.
16900 ;; We use two registers if available.
16901 (define_peephole2
16902 [(match_scratch:DI 0 "r")
16903 (match_scratch:DI 1 "r")
16904 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
16905 (set (reg:DI 6) (reg:DI 6))
16906 (clobber (reg:CC 17))])]
16907 "optimize_size || !TARGET_ADD_ESP_8"
16908 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16909 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
16910 (set (reg:DI 6) (reg:DI 6))])
16911 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
16912 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
16913 "")
16914
16915 (define_peephole2
16916 [(match_scratch:DI 0 "r")
16917 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
16918 (set (reg:DI 6) (reg:DI 6))
16919 (clobber (reg:CC 17))])]
16920 "optimize_size"
16921 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16922 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
16923 (set (reg:DI 6) (reg:DI 6))])
16924 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16925 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
16926 "")
16927
16928 ;; Convert esp additions to pop.
16929 (define_peephole2
16930 [(match_scratch:DI 0 "r")
16931 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
16932 (clobber (reg:CC 17))])]
16933 ""
16934 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16935 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
16936 "")
16937
16938 ;; Two pops case is tricky, since pop causes dependency on destination register.
16939 ;; We use two registers if available.
16940 (define_peephole2
16941 [(match_scratch:DI 0 "r")
16942 (match_scratch:DI 1 "r")
16943 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
16944 (clobber (reg:CC 17))])]
16945 ""
16946 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16947 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
16948 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
16949 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
16950 "")
16951
16952 (define_peephole2
16953 [(match_scratch:DI 0 "r")
16954 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
16955 (clobber (reg:CC 17))])]
16956 "optimize_size"
16957 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16958 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
16959 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
16960 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
16961 "")
16962 \f
16963 ;; Call-value patterns last so that the wildcard operand does not
16964 ;; disrupt insn-recog's switch tables.
16965
16966 (define_insn "*call_value_pop_0"
16967 [(set (match_operand 0 "" "")
16968 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
16969 (match_operand:SI 2 "" "")))
16970 (set (reg:SI 7) (plus:SI (reg:SI 7)
16971 (match_operand:SI 3 "immediate_operand" "")))]
16972 "!TARGET_64BIT"
16973 "*
16974 {
16975 if (SIBLING_CALL_P (insn))
16976 return \"jmp\\t%P1\";
16977 else
16978 return \"call\\t%P1\";
16979 }"
16980 [(set_attr "type" "callv")])
16981
16982 (define_insn "*call_value_pop_1"
16983 [(set (match_operand 0 "" "")
16984 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
16985 (match_operand:SI 2 "" "")))
16986 (set (reg:SI 7) (plus:SI (reg:SI 7)
16987 (match_operand:SI 3 "immediate_operand" "i")))]
16988 "!TARGET_64BIT"
16989 "*
16990 {
16991 if (constant_call_address_operand (operands[1], QImode))
16992 {
16993 if (SIBLING_CALL_P (insn))
16994 return \"jmp\\t%P1\";
16995 else
16996 return \"call\\t%P1\";
16997 }
16998 if (SIBLING_CALL_P (insn))
16999 return \"jmp\\t%A1\";
17000 else
17001 return \"call\\t%A1\";
17002 }"
17003 [(set_attr "type" "callv")])
17004
17005 (define_insn "*call_value_0"
17006 [(set (match_operand 0 "" "")
17007 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17008 (match_operand:SI 2 "" "")))]
17009 "!TARGET_64BIT"
17010 "*
17011 {
17012 if (SIBLING_CALL_P (insn))
17013 return \"jmp\\t%P1\";
17014 else
17015 return \"call\\t%P1\";
17016 }"
17017 [(set_attr "type" "callv")])
17018
17019 (define_insn "*call_value_0_rex64"
17020 [(set (match_operand 0 "" "")
17021 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17022 (match_operand:DI 2 "const_int_operand" "")))]
17023 "TARGET_64BIT"
17024 "*
17025 {
17026 if (SIBLING_CALL_P (insn))
17027 return \"jmp\\t%P1\";
17028 else
17029 return \"call\\t%P1\";
17030 }"
17031 [(set_attr "type" "callv")])
17032
17033 (define_insn "*call_value_1"
17034 [(set (match_operand 0 "" "")
17035 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
17036 (match_operand:SI 2 "" "")))]
17037 "!TARGET_64BIT"
17038 "*
17039 {
17040 if (constant_call_address_operand (operands[1], QImode))
17041 {
17042 if (SIBLING_CALL_P (insn))
17043 return \"jmp\\t%P1\";
17044 else
17045 return \"call\\t%P1\";
17046 }
17047 if (SIBLING_CALL_P (insn))
17048 return \"jmp\\t%*%1\";
17049 else
17050 return \"call\\t%*%1\";
17051 }"
17052 [(set_attr "type" "callv")])
17053
17054 (define_insn "*call_value_1_rex64"
17055 [(set (match_operand 0 "" "")
17056 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17057 (match_operand:DI 2 "" "")))]
17058 "TARGET_64BIT"
17059 "*
17060 {
17061 if (constant_call_address_operand (operands[1], QImode))
17062 {
17063 if (SIBLING_CALL_P (insn))
17064 return \"jmp\\t%P1\";
17065 else
17066 return \"call\\t%P1\";
17067 }
17068 if (SIBLING_CALL_P (insn))
17069 return \"jmp\\t%A1\";
17070 else
17071 return \"call\\t%A1\";
17072 }"
17073 [(set_attr "type" "callv")])
17074 \f
17075 (define_insn "trap"
17076 [(trap_if (const_int 1) (const_int 5))]
17077 ""
17078 "int\\t$5")
17079
17080 ;;; ix86 doesn't have conditional trap instructions, but we fake them
17081 ;;; for the sake of bounds checking. By emitting bounds checks as
17082 ;;; conditional traps rather than as conditional jumps around
17083 ;;; unconditional traps we avoid introducing spurious basic-block
17084 ;;; boundaries and facilitate elimination of redundant checks. In
17085 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
17086 ;;; interrupt 5.
17087 ;;;
17088 ;;; FIXME: Static branch prediction rules for ix86 are such that
17089 ;;; forward conditional branches predict as untaken. As implemented
17090 ;;; below, pseudo conditional traps violate that rule. We should use
17091 ;;; .pushsection/.popsection to place all of the `int 5's in a special
17092 ;;; section loaded at the end of the text segment and branch forward
17093 ;;; there on bounds-failure, and then jump back immediately (in case
17094 ;;; the system chooses to ignore bounds violations, or to report
17095 ;;; violations and continue execution).
17096
17097 (define_expand "conditional_trap"
17098 [(trap_if (match_operator 0 "comparison_operator"
17099 [(match_dup 2) (const_int 0)])
17100 (match_operand 1 "const_int_operand" ""))]
17101 ""
17102 "
17103 {
17104 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
17105 ix86_expand_compare (GET_CODE (operands[0]),
17106 NULL_PTR, NULL_PTR),
17107 operands[1]));
17108 DONE;
17109 }")
17110
17111 (define_insn ""
17112 [(trap_if (match_operator 0 "comparison_operator"
17113 [(reg 17) (const_int 0)])
17114 (match_operand 1 "const_int_operand" ""))]
17115 ""
17116 "*
17117 {
17118 operands[2] = gen_label_rtx ();
17119 output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands);
17120 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
17121 CODE_LABEL_NUMBER (operands[2]));
17122 RET;
17123 }")
17124
17125 ;; Pentium III SIMD instructions.
17126
17127 ;; Moves for SSE/MMX regs.
17128
17129 (define_insn "movv4sf_internal"
17130 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17131 (match_operand:V4SF 1 "general_operand" "xm,x"))]
17132 "TARGET_SSE"
17133 ;; @@@ let's try to use movaps here.
17134 "movaps\\t{%1, %0|%0, %1}"
17135 [(set_attr "type" "sse")])
17136
17137 (define_insn "movv4si_internal"
17138 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
17139 (match_operand:V4SI 1 "general_operand" "xm,x"))]
17140 "TARGET_SSE"
17141 ;; @@@ let's try to use movaps here.
17142 "movaps\\t{%1, %0|%0, %1}"
17143 [(set_attr "type" "sse")])
17144
17145 (define_insn "movv8qi_internal"
17146 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
17147 (match_operand:V8QI 1 "general_operand" "ym,y"))]
17148 "TARGET_MMX"
17149 "movq\\t{%1, %0|%0, %1}"
17150 [(set_attr "type" "mmx")])
17151
17152 (define_insn "movv4hi_internal"
17153 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
17154 (match_operand:V4HI 1 "general_operand" "ym,y"))]
17155 "TARGET_MMX"
17156 "movq\\t{%1, %0|%0, %1}"
17157 [(set_attr "type" "mmx")])
17158
17159 (define_insn "movv2si_internal"
17160 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
17161 (match_operand:V2SI 1 "general_operand" "ym,y"))]
17162 "TARGET_MMX"
17163 "movq\\t{%1, %0|%0, %1}"
17164 [(set_attr "type" "mmx")])
17165
17166 (define_expand "movti"
17167 [(set (match_operand:TI 0 "general_operand" "")
17168 (match_operand:TI 1 "general_operand" ""))]
17169 "TARGET_SSE"
17170 "
17171 {
17172 /* For constants other than zero into memory. We do not know how the
17173 instructions used to build constants modify the upper 64 bits
17174 of the register, once we have that information we may be able
17175 to handle some of them more efficiently. */
17176 if ((reload_in_progress | reload_completed) == 0
17177 && register_operand (operands[0], TImode)
17178 && CONSTANT_P (operands[1]))
17179 {
17180 rtx addr = gen_reg_rtx (Pmode);
17181
17182 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
17183 operands[1] = gen_rtx_MEM (TImode, addr);
17184 }
17185
17186 /* Make operand1 a register if it isn't already. */
17187 if ((reload_in_progress | reload_completed) == 0
17188 && !register_operand (operands[0], TImode)
17189 && !register_operand (operands[1], TImode)
17190 && operands[1] != CONST0_RTX (TImode))
17191 {
17192 rtx temp = force_reg (TImode, operands[1]);
17193 emit_move_insn (operands[0], temp);
17194 DONE;
17195 }
17196 }")
17197
17198 (define_expand "movv4sf"
17199 [(set (match_operand:V4SF 0 "general_operand" "")
17200 (match_operand:V4SF 1 "general_operand" ""))]
17201 "TARGET_SSE"
17202 "
17203 {
17204 /* For constants other than zero into memory. We do not know how the
17205 instructions used to build constants modify the upper 64 bits
17206 of the register, once we have that information we may be able
17207 to handle some of them more efficiently. */
17208 if ((reload_in_progress | reload_completed) == 0
17209 && register_operand (operands[0], V4SFmode)
17210 && CONSTANT_P (operands[1]))
17211 {
17212 rtx addr = gen_reg_rtx (Pmode);
17213
17214 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
17215 operands[1] = gen_rtx_MEM (V4SFmode, addr);
17216 }
17217
17218 /* Make operand1 a register if it isn't already. */
17219 if ((reload_in_progress | reload_completed) == 0
17220 && !register_operand (operands[0], V4SFmode)
17221 && !register_operand (operands[1], V4SFmode)
17222 && operands[1] != CONST0_RTX (V4SFmode))
17223 {
17224 rtx temp = force_reg (V4SFmode, operands[1]);
17225 emit_move_insn (operands[0], temp);
17226 DONE;
17227 }
17228 }")
17229
17230 (define_expand "movv4si"
17231 [(set (match_operand:V4SI 0 "general_operand" "")
17232 (match_operand:V4SI 1 "general_operand" ""))]
17233 "TARGET_MMX"
17234 "
17235 {
17236 /* For constants other than zero into memory. We do not know how the
17237 instructions used to build constants modify the upper 64 bits
17238 of the register, once we have that information we may be able
17239 to handle some of them more efficiently. */
17240 if ((reload_in_progress | reload_completed) == 0
17241 && register_operand (operands[0], V4SImode)
17242 && CONSTANT_P (operands[1]))
17243 {
17244 rtx addr = gen_reg_rtx (Pmode);
17245
17246 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
17247 operands[1] = gen_rtx_MEM (V4SImode, addr);
17248 }
17249
17250 /* Make operand1 a register if it isn't already. */
17251 if ((reload_in_progress | reload_completed) == 0
17252 && !register_operand (operands[0], V4SImode)
17253 && !register_operand (operands[1], V4SImode)
17254 && operands[1] != CONST0_RTX (V4SImode))
17255 {
17256 rtx temp = force_reg (V4SImode, operands[1]);
17257 emit_move_insn (operands[0], temp);
17258 DONE;
17259 }
17260 }")
17261
17262 (define_expand "movv2si"
17263 [(set (match_operand:V2SI 0 "general_operand" "")
17264 (match_operand:V2SI 1 "general_operand" ""))]
17265 "TARGET_MMX"
17266 "
17267 {
17268 /* For constants other than zero into memory. We do not know how the
17269 instructions used to build constants modify the upper 64 bits
17270 of the register, once we have that information we may be able
17271 to handle some of them more efficiently. */
17272 if ((reload_in_progress | reload_completed) == 0
17273 && register_operand (operands[0], V2SImode)
17274 && CONSTANT_P (operands[1]))
17275 {
17276 rtx addr = gen_reg_rtx (Pmode);
17277
17278 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
17279 operands[1] = gen_rtx_MEM (V2SImode, addr);
17280 }
17281
17282 /* Make operand1 a register if it isn't already. */
17283 if ((reload_in_progress | reload_completed) == 0
17284 && !register_operand (operands[0], V2SImode)
17285 && !register_operand (operands[1], V2SImode)
17286 && operands[1] != CONST0_RTX (V2SImode))
17287 {
17288 rtx temp = force_reg (V2SImode, operands[1]);
17289 emit_move_insn (operands[0], temp);
17290 DONE;
17291 }
17292 }")
17293
17294 (define_expand "movv4hi"
17295 [(set (match_operand:V4HI 0 "general_operand" "")
17296 (match_operand:V4HI 1 "general_operand" ""))]
17297 "TARGET_MMX"
17298 "
17299 {
17300 /* For constants other than zero into memory. We do not know how the
17301 instructions used to build constants modify the upper 64 bits
17302 of the register, once we have that information we may be able
17303 to handle some of them more efficiently. */
17304 if ((reload_in_progress | reload_completed) == 0
17305 && register_operand (operands[0], V4HImode)
17306 && CONSTANT_P (operands[1]))
17307 {
17308 rtx addr = gen_reg_rtx (Pmode);
17309
17310 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
17311 operands[1] = gen_rtx_MEM (V4HImode, addr);
17312 }
17313
17314 /* Make operand1 a register if it isn't already. */
17315 if ((reload_in_progress | reload_completed) == 0
17316 && !register_operand (operands[0], V4HImode)
17317 && !register_operand (operands[1], V4HImode)
17318 && operands[1] != CONST0_RTX (V4HImode))
17319 {
17320 rtx temp = force_reg (V4HImode, operands[1]);
17321 emit_move_insn (operands[0], temp);
17322 DONE;
17323 }
17324 }")
17325
17326 (define_expand "movv8qi"
17327 [(set (match_operand:V8QI 0 "general_operand" "")
17328 (match_operand:V8QI 1 "general_operand" ""))]
17329 "TARGET_MMX"
17330 "
17331 {
17332 /* For constants other than zero into memory. We do not know how the
17333 instructions used to build constants modify the upper 64 bits
17334 of the register, once we have that information we may be able
17335 to handle some of them more efficiently. */
17336 if ((reload_in_progress | reload_completed) == 0
17337 && register_operand (operands[0], V8QImode)
17338 && CONSTANT_P (operands[1]))
17339 {
17340 rtx addr = gen_reg_rtx (Pmode);
17341
17342 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
17343 operands[1] = gen_rtx_MEM (V8QImode, addr);
17344 }
17345
17346 /* Make operand1 a register if it isn't already. */
17347 if ((reload_in_progress | reload_completed) == 0
17348 && !register_operand (operands[0], V8QImode)
17349 && !register_operand (operands[1], V8QImode)
17350 && operands[1] != CONST0_RTX (V8QImode))
17351 {
17352 rtx temp = force_reg (V8QImode, operands[1]);
17353 emit_move_insn (operands[0], temp);
17354 DONE;
17355 }
17356 }")
17357
17358 (define_insn_and_split "*pushti"
17359 [(set (match_operand:TI 0 "push_operand" "=<")
17360 (match_operand:TI 1 "nonmemory_operand" "x"))]
17361 "TARGET_SSE"
17362 "#"
17363 ""
17364 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17365 (set (mem:TI (reg:SI 7)) (match_dup 1))]
17366 ""
17367 [(set_attr "type" "sse")])
17368
17369 (define_insn_and_split "*pushv4sf"
17370 [(set (match_operand:V4SF 0 "push_operand" "=<")
17371 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
17372 "TARGET_SSE"
17373 "#"
17374 ""
17375 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17376 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
17377 ""
17378 [(set_attr "type" "sse")])
17379
17380 (define_insn_and_split "*pushv4si"
17381 [(set (match_operand:V4SI 0 "push_operand" "=<")
17382 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
17383 "TARGET_SSE"
17384 "#"
17385 ""
17386 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
17387 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
17388 ""
17389 [(set_attr "type" "sse")])
17390
17391 (define_insn_and_split "*pushv2si"
17392 [(set (match_operand:V2SI 0 "push_operand" "=<")
17393 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
17394 "TARGET_MMX"
17395 "#"
17396 ""
17397 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17398 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
17399 ""
17400 [(set_attr "type" "mmx")])
17401
17402 (define_insn_and_split "*pushv4hi"
17403 [(set (match_operand:V4HI 0 "push_operand" "=<")
17404 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
17405 "TARGET_MMX"
17406 "#"
17407 ""
17408 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17409 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
17410 ""
17411 [(set_attr "type" "mmx")])
17412
17413 (define_insn_and_split "*pushv8qi"
17414 [(set (match_operand:V8QI 0 "push_operand" "=<")
17415 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
17416 "TARGET_MMX"
17417 "#"
17418 ""
17419 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17420 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
17421 ""
17422 [(set_attr "type" "mmx")])
17423
17424 (define_insn "movti_internal"
17425 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
17426 (match_operand:TI 1 "general_operand" "xm,x"))]
17427 "TARGET_SSE"
17428 "@
17429 movaps\\t{%1, %0|%0, %1}
17430 movaps\\t{%1, %0|%0, %1}"
17431 [(set_attr "type" "sse")])
17432
17433 ;; These two patterns are useful for specifying exactly whether to use
17434 ;; movaps or movups
17435 (define_insn "sse_movaps"
17436 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17437 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
17438 "TARGET_SSE"
17439 "@
17440 movaps\\t{%1, %0|%0, %1}
17441 movaps\\t{%1, %0|%0, %1}"
17442 [(set_attr "type" "sse")])
17443
17444 (define_insn "sse_movups"
17445 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17446 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
17447 "TARGET_SSE"
17448 "@
17449 movups\\t{%1, %0|%0, %1}
17450 movups\\t{%1, %0|%0, %1}"
17451 [(set_attr "type" "sse")])
17452
17453
17454 ;; SSE Strange Moves.
17455
17456 (define_insn "sse_movmskps"
17457 [(set (match_operand:SI 0 "register_operand" "=r")
17458 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
17459 "TARGET_SSE"
17460 "movmskps\\t{%1, %0|%0, %1}"
17461 [(set_attr "type" "sse")])
17462
17463 (define_insn "mmx_pmovmskb"
17464 [(set (match_operand:SI 0 "register_operand" "=r")
17465 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
17466 "TARGET_SSE"
17467 "pmovmskb\\t{%1, %0|%0, %1}"
17468 [(set_attr "type" "sse")])
17469
17470 (define_insn "mmx_maskmovq"
17471 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
17472 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
17473 (match_operand:V8QI 2 "register_operand" "y")] 32))]
17474 "TARGET_SSE"
17475 ;; @@@ check ordering of operands in intel/nonintel syntax
17476 "maskmovq\\t{%2, %1|%1, %2}"
17477 [(set_attr "type" "sse")])
17478
17479 (define_insn "sse_movntv4sf"
17480 [(set (match_operand:V4SF 0 "memory_operand" "=m")
17481 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
17482 "TARGET_SSE"
17483 "movntps\\t{%1, %0|%0, %1}"
17484 [(set_attr "type" "sse")])
17485
17486 (define_insn "sse_movntdi"
17487 [(set (match_operand:DI 0 "memory_operand" "=m")
17488 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
17489 "TARGET_SSE"
17490 "movntq\\t{%1, %0|%0, %1}"
17491 [(set_attr "type" "sse")])
17492
17493 (define_insn "sse_movhlps"
17494 [(set (match_operand:V4SF 0 "register_operand" "=x")
17495 (vec_merge:V4SF
17496 (match_operand:V4SF 1 "register_operand" "0")
17497 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17498 (parallel [(const_int 2)
17499 (const_int 3)
17500 (const_int 0)
17501 (const_int 1)]))
17502 (const_int 3)))]
17503 "TARGET_SSE"
17504 "movhlps\\t{%2, %0|%0, %2}"
17505 [(set_attr "type" "sse")])
17506
17507 (define_insn "sse_movlhps"
17508 [(set (match_operand:V4SF 0 "register_operand" "=x")
17509 (vec_merge:V4SF
17510 (match_operand:V4SF 1 "register_operand" "0")
17511 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
17512 (parallel [(const_int 2)
17513 (const_int 3)
17514 (const_int 0)
17515 (const_int 1)]))
17516 (const_int 12)))]
17517 "TARGET_SSE"
17518 "movlhps\\t{%2, %0|%0, %2}"
17519 [(set_attr "type" "sse")])
17520
17521 (define_insn "sse_movhps"
17522 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17523 (vec_merge:V4SF
17524 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17525 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17526 (const_int 12)))]
17527 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17528 "movhps\\t{%2, %0|%0, %2}"
17529 [(set_attr "type" "sse")])
17530
17531 (define_insn "sse_movlps"
17532 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
17533 (vec_merge:V4SF
17534 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
17535 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
17536 (const_int 3)))]
17537 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
17538 "movlps\\t{%2, %0|%0, %2}"
17539 [(set_attr "type" "sse")])
17540
17541 (define_insn "sse_loadss"
17542 [(set (match_operand:V4SF 0 "register_operand" "=x")
17543 (vec_merge:V4SF
17544 (match_operand:V4SF 1 "memory_operand" "m")
17545 (vec_duplicate:V4SF (float:SF (const_int 0)))
17546 (const_int 1)))]
17547 "TARGET_SSE"
17548 "movss\\t{%1, %0|%0, %1}"
17549 [(set_attr "type" "sse")])
17550
17551 (define_insn "sse_movss"
17552 [(set (match_operand:V4SF 0 "register_operand" "=x")
17553 (vec_merge:V4SF
17554 (match_operand:V4SF 1 "register_operand" "0")
17555 (match_operand:V4SF 2 "register_operand" "x")
17556 (const_int 1)))]
17557 "TARGET_SSE"
17558 "movss\\t{%2, %0|%0, %2}"
17559 [(set_attr "type" "sse")])
17560
17561 (define_insn "sse_storess"
17562 [(set (match_operand:SF 0 "memory_operand" "=m")
17563 (vec_select:SF
17564 (match_operand:V4SF 1 "register_operand" "x")
17565 (parallel [(const_int 0)])))]
17566 "TARGET_SSE"
17567 "movss\\t{%1, %0|%0, %1}"
17568 [(set_attr "type" "sse")])
17569
17570 (define_insn "sse_shufps"
17571 [(set (match_operand:V4SF 0 "register_operand" "=x")
17572 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
17573 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
17574 (match_operand:SI 3 "immediate_operand" "i")] 41))]
17575 "TARGET_SSE"
17576 ;; @@@ check operand order for intel/nonintel syntax
17577 "shufps\\t{%3, %2, %0|%0, %2, %3}"
17578 [(set_attr "type" "sse")])
17579
17580
17581 ;; SSE arithmetic
17582
17583 (define_insn "addv4sf3"
17584 [(set (match_operand:V4SF 0 "register_operand" "=x")
17585 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17586 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17587 "TARGET_SSE"
17588 "addps\\t{%2, %0|%0, %2}"
17589 [(set_attr "type" "sse")])
17590
17591 (define_insn "vmaddv4sf3"
17592 [(set (match_operand:V4SF 0 "register_operand" "=x")
17593 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17594 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17595 (match_dup 1)
17596 (const_int 1)))]
17597 "TARGET_SSE"
17598 "addss\\t{%2, %0|%0, %2}"
17599 [(set_attr "type" "sse")])
17600
17601 (define_insn "subv4sf3"
17602 [(set (match_operand:V4SF 0 "register_operand" "=x")
17603 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17604 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17605 "TARGET_SSE"
17606 "subps\\t{%2, %0|%0, %2}"
17607 [(set_attr "type" "sse")])
17608
17609 (define_insn "vmsubv4sf3"
17610 [(set (match_operand:V4SF 0 "register_operand" "=x")
17611 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
17612 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17613 (match_dup 1)
17614 (const_int 1)))]
17615 "TARGET_SSE"
17616 "subss\\t{%2, %0|%0, %2}"
17617 [(set_attr "type" "sse")])
17618
17619 (define_insn "mulv4sf3"
17620 [(set (match_operand:V4SF 0 "register_operand" "=x")
17621 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17622 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17623 "TARGET_SSE"
17624 "mulps\\t{%2, %0|%0, %2}"
17625 [(set_attr "type" "sse")])
17626
17627 (define_insn "vmmulv4sf3"
17628 [(set (match_operand:V4SF 0 "register_operand" "=x")
17629 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
17630 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17631 (match_dup 1)
17632 (const_int 1)))]
17633 "TARGET_SSE"
17634 "mulss\\t{%2, %0|%0, %2}"
17635 [(set_attr "type" "sse")])
17636
17637 (define_insn "divv4sf3"
17638 [(set (match_operand:V4SF 0 "register_operand" "=x")
17639 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
17640 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
17641 "TARGET_SSE"
17642 "divps\\t{%2, %0|%0, %2}"
17643 [(set_attr "type" "sse")])
17644
17645 (define_insn "vmdivv4sf3"
17646 [(set (match_operand:V4SF 0 "register_operand" "=x")
17647 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
17648 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
17649 (match_dup 1)
17650 (const_int 1)))]
17651 "TARGET_SSE"
17652 "divss\\t{%2, %0|%0, %2}"
17653 [(set_attr "type" "sse")])
17654
17655
17656 ;; SSE square root/reciprocal
17657
17658 (define_insn "rcpv4sf2"
17659 [(set (match_operand:V4SF 0 "register_operand" "=x")
17660 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
17661 "TARGET_SSE"
17662 "rcpps\\t{%1, %0|%0, %1}"
17663 [(set_attr "type" "sse")])
17664
17665 (define_insn "vmrcpv4sf2"
17666 [(set (match_operand:V4SF 0 "register_operand" "=x")
17667 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
17668 (match_operand:V4SF 2 "register_operand" "0")
17669 (const_int 1)))]
17670 "TARGET_SSE"
17671 "rcpss\\t{%1, %0|%0, %1}"
17672 [(set_attr "type" "sse")])
17673
17674 (define_insn "rsqrtv4sf2"
17675 [(set (match_operand:V4SF 0 "register_operand" "=x")
17676 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
17677 "TARGET_SSE"
17678 "rsqrtps\\t{%1, %0|%0, %1}"
17679 [(set_attr "type" "sse")])
17680
17681 (define_insn "vmrsqrtv4sf2"
17682 [(set (match_operand:V4SF 0 "register_operand" "=x")
17683 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
17684 (match_operand:V4SF 2 "register_operand" "0")
17685 (const_int 1)))]
17686 "TARGET_SSE"
17687 "rsqrtss\\t{%1, %0|%0, %1}"
17688 [(set_attr "type" "sse")])
17689
17690 (define_insn "sqrtv4sf2"
17691 [(set (match_operand:V4SF 0 "register_operand" "=x")
17692 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
17693 "TARGET_SSE"
17694 "sqrtps\\t{%1, %0|%0, %1}"
17695 [(set_attr "type" "sse")])
17696
17697 (define_insn "vmsqrtv4sf2"
17698 [(set (match_operand:V4SF 0 "register_operand" "=x")
17699 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
17700 (match_operand:V4SF 2 "register_operand" "0")
17701 (const_int 1)))]
17702 "TARGET_SSE"
17703 "sqrtss\\t{%1, %0|%0, %1}"
17704 [(set_attr "type" "sse")])
17705
17706
17707 ;; SSE logical operations.
17708
17709 ;; These are not called andti3 etc. because we really really don't want
17710 ;; the compiler to widen DImode ands to TImode ands and then try to move
17711 ;; into DImode subregs of SSE registers, and them together, and move out
17712 ;; of DImode subregs again!
17713
17714 (define_insn "*sse_andti3_df_1"
17715 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17716 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
17717 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
17718 "TARGET_SSE2"
17719 "andpd\\t{%2, %0|%0, %2}"
17720 [(set_attr "type" "sse")])
17721
17722 (define_insn "*sse_andti3_df_2"
17723 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17724 (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
17725 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
17726 "TARGET_SSE2"
17727 "andpd\\t{%2, %0|%0, %2}"
17728 [(set_attr "type" "sse")])
17729
17730 (define_insn "*sse_andti3_sf_1"
17731 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17732 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
17733 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
17734 "TARGET_SSE"
17735 "andps\\t{%2, %0|%0, %2}"
17736 [(set_attr "type" "sse")])
17737
17738 (define_insn "*sse_andti3_sf_2"
17739 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17740 (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
17741 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17742 "TARGET_SSE"
17743 "andps\\t{%2, %0|%0, %2}"
17744 [(set_attr "type" "sse")])
17745
17746 (define_insn "sse_andti3"
17747 [(set (match_operand:TI 0 "register_operand" "=x")
17748 (and:TI (match_operand:TI 1 "register_operand" "%0")
17749 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17750 "TARGET_SSE && !TARGET_SSE2"
17751 "andps\\t{%2, %0|%0, %2}"
17752 [(set_attr "type" "sse")])
17753
17754 (define_insn "*sse_andti3_sse2"
17755 [(set (match_operand:TI 0 "register_operand" "=x")
17756 (and:TI (match_operand:TI 1 "register_operand" "%0")
17757 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17758 "TARGET_SSE2"
17759 "pand\\t{%2, %0|%0, %2}"
17760 [(set_attr "type" "sse")])
17761
17762 (define_insn "*sse_nandti3_df"
17763 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17764 (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
17765 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
17766 "TARGET_SSE2"
17767 "andnpd\\t{%2, %0|%0, %2}"
17768 [(set_attr "type" "sse")])
17769
17770 (define_insn "*sse_nandti3_sf"
17771 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17772 (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
17773 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17774 "TARGET_SSE"
17775 "andnps\\t{%2, %0|%0, %2}"
17776 [(set_attr "type" "sse")])
17777
17778 (define_insn "sse_nandti3"
17779 [(set (match_operand:TI 0 "register_operand" "=x")
17780 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
17781 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17782 "TARGET_SSE && !TARGET_SSE2"
17783 "andnps\\t{%2, %0|%0, %2}"
17784 [(set_attr "type" "sse")])
17785
17786 (define_insn "*sse_nandti3_sse2"
17787 [(set (match_operand:TI 0 "register_operand" "=x")
17788 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
17789 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17790 "TARGET_SSE2"
17791 "pnand\\t{%2, %0|%0, %2}"
17792 [(set_attr "type" "sse")])
17793
17794 (define_insn "*sse_iorti3_df_1"
17795 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17796 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
17797 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
17798 "TARGET_SSE2"
17799 "orpd\\t{%2, %0|%0, %2}"
17800 [(set_attr "type" "sse")])
17801
17802 (define_insn "*sse_iorti3_df_2"
17803 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17804 (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
17805 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
17806 "TARGET_SSE2"
17807 "orpd\\t{%2, %0|%0, %2}"
17808 [(set_attr "type" "sse")])
17809
17810 (define_insn "*sse_iorti3_sf_1"
17811 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17812 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
17813 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
17814 "TARGET_SSE"
17815 "orps\\t{%2, %0|%0, %2}"
17816 [(set_attr "type" "sse")])
17817
17818 (define_insn "*sse_iorti3_sf_2"
17819 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17820 (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
17821 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17822 "TARGET_SSE"
17823 "orps\\t{%2, %0|%0, %2}"
17824 [(set_attr "type" "sse")])
17825
17826 (define_insn "sse_iorti3"
17827 [(set (match_operand:TI 0 "register_operand" "=x")
17828 (ior:TI (match_operand:TI 1 "register_operand" "%0")
17829 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17830 "TARGET_SSE && !TARGET_SSE2"
17831 "orps\\t{%2, %0|%0, %2}"
17832 [(set_attr "type" "sse")])
17833
17834 (define_insn "*sse_iorti3_sse2"
17835 [(set (match_operand:TI 0 "register_operand" "=x")
17836 (ior:TI (match_operand:TI 1 "register_operand" "%0")
17837 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17838 "TARGET_SSE2"
17839 "por\\t{%2, %0|%0, %2}"
17840 [(set_attr "type" "sse")])
17841
17842 (define_insn "*sse_xorti3_df_1"
17843 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17844 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
17845 (subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
17846 "TARGET_SSE2"
17847 "xorpd\\t{%2, %0|%0, %2}"
17848 [(set_attr "type" "sse")])
17849
17850 (define_insn "*sse_xorti3_df_2"
17851 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
17852 (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
17853 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
17854 "TARGET_SSE2"
17855 "xorpd\\t{%2, %0|%0, %2}"
17856 [(set_attr "type" "sse")])
17857
17858 (define_insn "*sse_xorti3_sf_1"
17859 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17860 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
17861 (subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
17862 "TARGET_SSE"
17863 "xorps\\t{%2, %0|%0, %2}"
17864 [(set_attr "type" "sse")])
17865
17866 (define_insn "*sse_xorti3_sf_2"
17867 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
17868 (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
17869 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17870 "TARGET_SSE"
17871 "xorps\\t{%2, %0|%0, %2}"
17872 [(set_attr "type" "sse")])
17873
17874 (define_insn "sse_xorti3"
17875 [(set (match_operand:TI 0 "register_operand" "=x")
17876 (xor:TI (match_operand:TI 1 "register_operand" "%0")
17877 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17878 "TARGET_SSE && !TARGET_SSE2"
17879 "xorps\\t{%2, %0|%0, %2}"
17880 [(set_attr "type" "sse")])
17881
17882 (define_insn "*sse_xorti3_sse2"
17883 [(set (match_operand:TI 0 "register_operand" "=x")
17884 (xor:TI (match_operand:TI 1 "register_operand" "%0")
17885 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
17886 "TARGET_SSE2"
17887 "pxor\\t{%2, %0|%0, %2}"
17888 [(set_attr "type" "sse")])
17889
17890 ;; Use xor, but don't show input operands so they aren't live before
17891 ;; this insn.
17892 (define_insn "sse_clrti"
17893 [(set (match_operand:TI 0 "register_operand" "=x")
17894 (unspec:TI [(const_int 0)] 45))]
17895 "TARGET_SSE"
17896 "xorps\\t{%0, %0|%0, %0}"
17897 [(set_attr "type" "sse")])
17898
17899
17900 ;; SSE mask-generating compares
17901
17902 (define_insn "maskcmpv4sf3"
17903 [(set (match_operand:V4SI 0 "register_operand" "=x")
17904 (match_operator:V4SI 3 "sse_comparison_operator"
17905 [(match_operand:V4SF 1 "register_operand" "0")
17906 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
17907 "TARGET_SSE"
17908 "cmp%D3ps\\t{%2, %0|%0, %2}"
17909 [(set_attr "type" "sse")])
17910
17911 (define_insn "maskncmpv4sf3"
17912 [(set (match_operand:V4SI 0 "register_operand" "=x")
17913 (not:V4SI
17914 (match_operator:V4SI 3 "sse_comparison_operator"
17915 [(match_operand:V4SF 1 "register_operand" "0")
17916 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
17917 "TARGET_SSE"
17918 "cmpn%D3ps\\t{%2, %0|%0, %2}"
17919 [(set_attr "type" "sse")])
17920
17921 (define_insn "vmmaskcmpv4sf3"
17922 [(set (match_operand:V4SI 0 "register_operand" "=x")
17923 (vec_merge:V4SI
17924 (match_operator:V4SI 3 "sse_comparison_operator"
17925 [(match_operand:V4SF 1 "register_operand" "0")
17926 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
17927 (match_dup 1)
17928 (const_int 1)))]
17929 "TARGET_SSE"
17930 "cmp%D3ss\\t{%2, %0|%0, %2}"
17931 [(set_attr "type" "sse")])
17932
17933 (define_insn "vmmaskncmpv4sf3"
17934 [(set (match_operand:V4SI 0 "register_operand" "=x")
17935 (vec_merge:V4SI
17936 (not:V4SI
17937 (match_operator:V4SI 3 "sse_comparison_operator"
17938 [(match_operand:V4SF 1 "register_operand" "0")
17939 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
17940 (subreg:V4SI (match_dup 1) 0)
17941 (const_int 1)))]
17942 "TARGET_SSE"
17943 "cmp%D3ss\\t{%2, %0|%0, %2}"
17944 [(set_attr "type" "sse")])
17945
17946 (define_insn "sse_comi"
17947 [(set (reg:CCFP 17)
17948 (match_operator:CCFP 2 "sse_comparison_operator"
17949 [(vec_select:SF
17950 (match_operand:V4SF 0 "register_operand" "x")
17951 (parallel [(const_int 0)]))
17952 (vec_select:SF
17953 (match_operand:V4SF 1 "register_operand" "x")
17954 (parallel [(const_int 0)]))]))]
17955 "TARGET_SSE"
17956 "comiss\\t{%2, %0|%0, %2}"
17957 [(set_attr "type" "sse")])
17958
17959 (define_insn "sse_ucomi"
17960 [(set (reg:CCFPU 17)
17961 (match_operator:CCFPU 2 "sse_comparison_operator"
17962 [(vec_select:SF
17963 (match_operand:V4SF 0 "register_operand" "x")
17964 (parallel [(const_int 0)]))
17965 (vec_select:SF
17966 (match_operand:V4SF 1 "register_operand" "x")
17967 (parallel [(const_int 0)]))]))]
17968 "TARGET_SSE"
17969 "ucomiss\\t{%2, %0|%0, %2}"
17970 [(set_attr "type" "sse")])
17971
17972
17973 ;; SSE unpack
17974
17975 (define_insn "sse_unpckhps"
17976 [(set (match_operand:V4SF 0 "register_operand" "=x")
17977 (vec_merge:V4SF
17978 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
17979 (parallel [(const_int 2)
17980 (const_int 0)
17981 (const_int 3)
17982 (const_int 1)]))
17983 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
17984 (parallel [(const_int 0)
17985 (const_int 2)
17986 (const_int 1)
17987 (const_int 3)]))
17988 (const_int 5)))]
17989 "TARGET_SSE"
17990 "unpckhps\\t{%2, %0|%0, %2}"
17991 [(set_attr "type" "sse")])
17992
17993 (define_insn "sse_unpcklps"
17994 [(set (match_operand:V4SF 0 "register_operand" "=x")
17995 (vec_merge:V4SF
17996 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
17997 (parallel [(const_int 0)
17998 (const_int 2)
17999 (const_int 1)
18000 (const_int 3)]))
18001 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
18002 (parallel [(const_int 2)
18003 (const_int 0)
18004 (const_int 3)
18005 (const_int 1)]))
18006 (const_int 5)))]
18007 "TARGET_SSE"
18008 "unpcklps\\t{%2, %0|%0, %2}"
18009 [(set_attr "type" "sse")])
18010
18011
18012 ;; SSE min/max
18013
18014 (define_insn "smaxv4sf3"
18015 [(set (match_operand:V4SF 0 "register_operand" "=x")
18016 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18017 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18018 "TARGET_SSE"
18019 "maxps\\t{%2, %0|%0, %2}"
18020 [(set_attr "type" "sse")])
18021
18022 (define_insn "vmsmaxv4sf3"
18023 [(set (match_operand:V4SF 0 "register_operand" "=x")
18024 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
18025 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18026 (match_dup 1)
18027 (const_int 1)))]
18028 "TARGET_SSE"
18029 "maxss\\t{%2, %0|%0, %2}"
18030 [(set_attr "type" "sse")])
18031
18032 (define_insn "sminv4sf3"
18033 [(set (match_operand:V4SF 0 "register_operand" "=x")
18034 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18035 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
18036 "TARGET_SSE"
18037 "minps\\t{%2, %0|%0, %2}"
18038 [(set_attr "type" "sse")])
18039
18040 (define_insn "vmsminv4sf3"
18041 [(set (match_operand:V4SF 0 "register_operand" "=x")
18042 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
18043 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
18044 (match_dup 1)
18045 (const_int 1)))]
18046 "TARGET_SSE"
18047 "minss\\t{%2, %0|%0, %2}"
18048 [(set_attr "type" "sse")])
18049
18050
18051 ;; SSE <-> integer/MMX conversions
18052
18053 (define_insn "cvtpi2ps"
18054 [(set (match_operand:V4SF 0 "register_operand" "=x")
18055 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18056 (vec_duplicate:V4SF
18057 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
18058 (const_int 12)))]
18059 "TARGET_SSE"
18060 "cvtpi2ps\\t{%2, %0|%0, %2}"
18061 [(set_attr "type" "sse")])
18062
18063 (define_insn "cvtps2pi"
18064 [(set (match_operand:V2SI 0 "register_operand" "=y")
18065 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18066 (parallel
18067 [(const_int 0)
18068 (const_int 1)])))]
18069 "TARGET_SSE"
18070 "cvtps2pi\\t{%1, %0|%0, %1}"
18071 [(set_attr "type" "sse")])
18072
18073 (define_insn "cvttps2pi"
18074 [(set (match_operand:V2SI 0 "register_operand" "=y")
18075 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18076 (parallel
18077 [(const_int 0)
18078 (const_int 1)])))]
18079 "TARGET_SSE"
18080 "cvttps2pi\\t{%1, %0|%0, %1}"
18081 [(set_attr "type" "sse")])
18082
18083 (define_insn "cvtsi2ss"
18084 [(set (match_operand:V4SF 0 "register_operand" "=x")
18085 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
18086 (vec_duplicate:V4SF
18087 (float:SF (match_operand:SI 2 "register_operand" "rm")))
18088 (const_int 15)))]
18089 "TARGET_SSE"
18090 "cvtsi2ss\\t{%2, %0|%0, %2}"
18091 [(set_attr "type" "sse")])
18092
18093 (define_insn "cvtss2si"
18094 [(set (match_operand:SI 0 "register_operand" "=y")
18095 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
18096 (parallel [(const_int 0)])))]
18097 "TARGET_SSE"
18098 "cvtss2si\\t{%1, %0|%0, %1}"
18099 [(set_attr "type" "sse")])
18100
18101 (define_insn "cvttss2si"
18102 [(set (match_operand:SI 0 "register_operand" "=y")
18103 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
18104 (parallel [(const_int 0)])))]
18105 "TARGET_SSE"
18106 "cvttss2si\\t{%1, %0|%0, %1}"
18107 [(set_attr "type" "sse")])
18108
18109
18110 ;; MMX insns
18111
18112 ;; MMX arithmetic
18113
18114 (define_insn "addv8qi3"
18115 [(set (match_operand:V8QI 0 "register_operand" "=y")
18116 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18117 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18118 "TARGET_MMX"
18119 "paddb\\t{%2, %0|%0, %2}"
18120 [(set_attr "type" "mmx")])
18121
18122 (define_insn "addv4hi3"
18123 [(set (match_operand:V4HI 0 "register_operand" "=y")
18124 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18125 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18126 "TARGET_MMX"
18127 "paddw\\t{%2, %0|%0, %2}"
18128 [(set_attr "type" "mmx")])
18129
18130 (define_insn "addv2si3"
18131 [(set (match_operand:V2SI 0 "register_operand" "=y")
18132 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18133 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18134 "TARGET_MMX"
18135 "paddd\\t{%2, %0|%0, %2}"
18136 [(set_attr "type" "mmx")])
18137
18138 (define_insn "ssaddv8qi3"
18139 [(set (match_operand:V8QI 0 "register_operand" "=y")
18140 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18141 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18142 "TARGET_MMX"
18143 "paddsb\\t{%2, %0|%0, %2}"
18144 [(set_attr "type" "mmx")])
18145
18146 (define_insn "ssaddv4hi3"
18147 [(set (match_operand:V4HI 0 "register_operand" "=y")
18148 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18149 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18150 "TARGET_MMX"
18151 "paddsw\\t{%2, %0|%0, %2}"
18152 [(set_attr "type" "mmx")])
18153
18154 (define_insn "usaddv8qi3"
18155 [(set (match_operand:V8QI 0 "register_operand" "=y")
18156 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18157 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18158 "TARGET_MMX"
18159 "paddusb\\t{%2, %0|%0, %2}"
18160 [(set_attr "type" "mmx")])
18161
18162 (define_insn "usaddv4hi3"
18163 [(set (match_operand:V4HI 0 "register_operand" "=y")
18164 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18165 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18166 "TARGET_MMX"
18167 "paddusw\\t{%2, %0|%0, %2}"
18168 [(set_attr "type" "mmx")])
18169
18170 (define_insn "subv8qi3"
18171 [(set (match_operand:V8QI 0 "register_operand" "=y")
18172 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18173 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18174 "TARGET_MMX"
18175 "psubb\\t{%2, %0|%0, %2}"
18176 [(set_attr "type" "mmx")])
18177
18178 (define_insn "subv4hi3"
18179 [(set (match_operand:V4HI 0 "register_operand" "=y")
18180 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18181 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18182 "TARGET_MMX"
18183 "psubw\\t{%2, %0|%0, %2}"
18184 [(set_attr "type" "mmx")])
18185
18186 (define_insn "subv2si3"
18187 [(set (match_operand:V2SI 0 "register_operand" "=y")
18188 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
18189 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18190 "TARGET_MMX"
18191 "psubd\\t{%2, %0|%0, %2}"
18192 [(set_attr "type" "mmx")])
18193
18194 (define_insn "sssubv8qi3"
18195 [(set (match_operand:V8QI 0 "register_operand" "=y")
18196 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18197 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18198 "TARGET_MMX"
18199 "psubsb\\t{%2, %0|%0, %2}"
18200 [(set_attr "type" "mmx")])
18201
18202 (define_insn "sssubv4hi3"
18203 [(set (match_operand:V4HI 0 "register_operand" "=y")
18204 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18205 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18206 "TARGET_MMX"
18207 "psubsw\\t{%2, %0|%0, %2}"
18208 [(set_attr "type" "mmx")])
18209
18210 (define_insn "ussubv8qi3"
18211 [(set (match_operand:V8QI 0 "register_operand" "=y")
18212 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18213 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18214 "TARGET_MMX"
18215 "psubusb\\t{%2, %0|%0, %2}"
18216 [(set_attr "type" "mmx")])
18217
18218 (define_insn "ussubv4hi3"
18219 [(set (match_operand:V4HI 0 "register_operand" "=y")
18220 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
18221 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18222 "TARGET_MMX"
18223 "psubusw\\t{%2, %0|%0, %2}"
18224 [(set_attr "type" "mmx")])
18225
18226 (define_insn "mulv4hi3"
18227 [(set (match_operand:V4HI 0 "register_operand" "=y")
18228 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
18229 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18230 "TARGET_MMX"
18231 "pmullw\\t{%2, %0|%0, %2}"
18232 [(set_attr "type" "mmx")])
18233
18234 (define_insn "smulv4hi3_highpart"
18235 [(set (match_operand:V4HI 0 "register_operand" "=y")
18236 (truncate:V4HI
18237 (lshiftrt:V4SI
18238 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18239 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18240 (const_int 16))))]
18241 "TARGET_MMX"
18242 "pmulhw\\t{%2, %0|%0, %2}"
18243 [(set_attr "type" "mmx")])
18244
18245 (define_insn "umulv4hi3_highpart"
18246 [(set (match_operand:V4HI 0 "register_operand" "=y")
18247 (truncate:V4HI
18248 (lshiftrt:V4SI
18249 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
18250 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
18251 (const_int 16))))]
18252 "TARGET_MMX"
18253 "pmulhuw\\t{%2, %0|%0, %2}"
18254 [(set_attr "type" "mmx")])
18255
18256 (define_insn "mmx_pmaddwd"
18257 [(set (match_operand:V2SI 0 "register_operand" "=y")
18258 (plus:V2SI
18259 (mult:V2SI
18260 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
18261 (parallel [(const_int 0)
18262 (const_int 2)])))
18263 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18264 (parallel [(const_int 0)
18265 (const_int 2)]))))
18266 (mult:V2SI
18267 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
18268 (parallel [(const_int 1)
18269 (const_int 3)])))
18270 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
18271 (parallel [(const_int 1)
18272 (const_int 3)]))))))]
18273 "TARGET_MMX"
18274 "pmaddwd\\t{%2, %0|%0, %2}"
18275 [(set_attr "type" "mmx")])
18276
18277
18278 ;; MMX logical operations
18279 ;; Note we don't want to declare these as regular iordi3 insns to prevent
18280 ;; normal code that also wants to use the FPU from getting broken.
18281 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
18282 (define_insn "mmx_iordi3"
18283 [(set (match_operand:DI 0 "register_operand" "=y")
18284 (unspec:DI
18285 [(ior:DI (match_operand:DI 1 "register_operand" "0")
18286 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18287 "TARGET_MMX"
18288 "por\\t{%2, %0|%0, %2}"
18289 [(set_attr "type" "mmx")])
18290
18291 (define_insn "mmx_xordi3"
18292 [(set (match_operand:DI 0 "register_operand" "=y")
18293 (unspec:DI
18294 [(xor:DI (match_operand:DI 1 "register_operand" "0")
18295 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18296 "TARGET_MMX"
18297 "pxor\\t{%2, %0|%0, %2}"
18298 [(set_attr "type" "mmx")])
18299
18300 ;; Same as pxor, but don't show input operands so that we don't think
18301 ;; they are live.
18302 (define_insn "mmx_clrdi"
18303 [(set (match_operand:DI 0 "register_operand" "=y")
18304 (unspec:DI [(const_int 0)] 45))]
18305 "TARGET_MMX"
18306 "pxor\\t{%0, %0|%0, %0}"
18307 [(set_attr "type" "mmx")])
18308
18309 (define_insn "mmx_anddi3"
18310 [(set (match_operand:DI 0 "register_operand" "=y")
18311 (unspec:DI
18312 [(and:DI (match_operand:DI 1 "register_operand" "0")
18313 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18314 "TARGET_MMX"
18315 "pand\\t{%2, %0|%0, %2}"
18316 [(set_attr "type" "mmx")])
18317
18318 (define_insn "mmx_nanddi3"
18319 [(set (match_operand:DI 0 "register_operand" "=y")
18320 (unspec:DI
18321 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
18322 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
18323 "TARGET_MMX"
18324 "pandn\\t{%2, %0|%0, %2}"
18325 [(set_attr "type" "mmx")])
18326
18327
18328 ;; MMX unsigned averages/sum of absolute differences
18329
18330 (define_insn "mmx_uavgv8qi3"
18331 [(set (match_operand:V8QI 0 "register_operand" "=y")
18332 (ashiftrt:V8QI
18333 (plus:V8QI (plus:V8QI
18334 (match_operand:V8QI 1 "register_operand" "0")
18335 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
18336 (vec_const:V8QI (parallel [(const_int 1)
18337 (const_int 1)
18338 (const_int 1)
18339 (const_int 1)
18340 (const_int 1)
18341 (const_int 1)
18342 (const_int 1)
18343 (const_int 1)])))
18344 (const_int 1)))]
18345 "TARGET_SSE"
18346 "pavgb\\t{%2, %0|%0, %2}"
18347 [(set_attr "type" "sse")])
18348
18349 (define_insn "mmx_uavgv4hi3"
18350 [(set (match_operand:V4HI 0 "register_operand" "=y")
18351 (ashiftrt:V4HI
18352 (plus:V4HI (plus:V4HI
18353 (match_operand:V4HI 1 "register_operand" "0")
18354 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
18355 (vec_const:V4HI (parallel [(const_int 1)
18356 (const_int 1)
18357 (const_int 1)
18358 (const_int 1)])))
18359 (const_int 1)))]
18360 "TARGET_SSE"
18361 "pavgw\\t{%2, %0|%0, %2}"
18362 [(set_attr "type" "sse")])
18363
18364 (define_insn "mmx_psadbw"
18365 [(set (match_operand:V8QI 0 "register_operand" "=y")
18366 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
18367 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
18368 "TARGET_SSE"
18369 "psadbw\\t{%2, %0|%0, %2}"
18370 [(set_attr "type" "sse")])
18371
18372
18373 ;; MMX insert/extract/shuffle
18374
18375 (define_insn "mmx_pinsrw"
18376 [(set (match_operand:V4HI 0 "register_operand" "=y")
18377 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
18378 (vec_duplicate:V4HI
18379 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
18380 (match_operand:SI 3 "immediate_operand" "i")))]
18381 "TARGET_SSE"
18382 "pinsrw\\t{%3, %2, %0|%0, %2, %3}"
18383 [(set_attr "type" "sse")])
18384
18385 (define_insn "mmx_pextrw"
18386 [(set (match_operand:SI 0 "register_operand" "=r")
18387 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
18388 (parallel
18389 [(match_operand:SI 2 "immediate_operand" "i")]))))]
18390 "TARGET_SSE"
18391 "pextrw\\t{%2, %1, %0|%0, %1, %2}"
18392 [(set_attr "type" "sse")])
18393
18394 (define_insn "mmx_pshufw"
18395 [(set (match_operand:V4HI 0 "register_operand" "=y")
18396 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
18397 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
18398 (match_operand:SI 3 "immediate_operand" "i")] 41))]
18399 "TARGET_SSE"
18400 "pshufw\\t{%3, %2, %0|%0, %2, %3}"
18401 [(set_attr "type" "sse")])
18402
18403
18404 ;; MMX mask-generating comparisons
18405
18406 (define_insn "eqv8qi3"
18407 [(set (match_operand:V8QI 0 "register_operand" "=y")
18408 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
18409 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18410 "TARGET_MMX"
18411 "pcmpeqb\\t{%2, %0|%0, %2}"
18412 [(set_attr "type" "mmx")])
18413
18414 (define_insn "eqv4hi3"
18415 [(set (match_operand:V4HI 0 "register_operand" "=y")
18416 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
18417 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18418 "TARGET_MMX"
18419 "pcmpeqw\\t{%2, %0|%0, %2}"
18420 [(set_attr "type" "mmx")])
18421
18422 (define_insn "eqv2si3"
18423 [(set (match_operand:V2SI 0 "register_operand" "=y")
18424 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
18425 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18426 "TARGET_MMX"
18427 "pcmpeqd\\t{%2, %0|%0, %2}"
18428 [(set_attr "type" "mmx")])
18429
18430 (define_insn "gtv8qi3"
18431 [(set (match_operand:V8QI 0 "register_operand" "=y")
18432 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
18433 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18434 "TARGET_MMX"
18435 "pcmpgtb\\t{%2, %0|%0, %2}"
18436 [(set_attr "type" "mmx")])
18437
18438 (define_insn "gtv4hi3"
18439 [(set (match_operand:V4HI 0 "register_operand" "=y")
18440 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18441 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18442 "TARGET_MMX"
18443 "pcmpgtw\\t{%2, %0|%0, %2}"
18444 [(set_attr "type" "mmx")])
18445
18446 (define_insn "gtv2si3"
18447 [(set (match_operand:V2SI 0 "register_operand" "=y")
18448 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18449 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
18450 "TARGET_MMX"
18451 "pcmpgtd\\t{%2, %0|%0, %2}"
18452 [(set_attr "type" "mmx")])
18453
18454
18455 ;; MMX max/min insns
18456
18457 (define_insn "umaxv8qi3"
18458 [(set (match_operand:V8QI 0 "register_operand" "=y")
18459 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
18460 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18461 "TARGET_SSE"
18462 "pmaxub\\t{%2, %0|%0, %2}"
18463 [(set_attr "type" "sse")])
18464
18465 (define_insn "smaxv4hi3"
18466 [(set (match_operand:V4HI 0 "register_operand" "=y")
18467 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
18468 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18469 "TARGET_SSE"
18470 "pmaxsw\\t{%2, %0|%0, %2}"
18471 [(set_attr "type" "sse")])
18472
18473 (define_insn "uminv8qi3"
18474 [(set (match_operand:V8QI 0 "register_operand" "=y")
18475 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
18476 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
18477 "TARGET_SSE"
18478 "pminub\\t{%2, %0|%0, %2}"
18479 [(set_attr "type" "sse")])
18480
18481 (define_insn "sminv4hi3"
18482 [(set (match_operand:V4HI 0 "register_operand" "=y")
18483 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
18484 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
18485 "TARGET_SSE"
18486 "pminsw\\t{%2, %0|%0, %2}"
18487 [(set_attr "type" "sse")])
18488
18489
18490 ;; MMX shifts
18491
18492 (define_insn "ashrv4hi3"
18493 [(set (match_operand:V4HI 0 "register_operand" "=y")
18494 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18495 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18496 "TARGET_MMX"
18497 "psraw\\t{%2, %0|%0, %2}"
18498 [(set_attr "type" "mmx")])
18499
18500 (define_insn "ashrv2si3"
18501 [(set (match_operand:V2SI 0 "register_operand" "=y")
18502 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18503 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18504 "TARGET_MMX"
18505 "psrad\\t{%2, %0|%0, %2}"
18506 [(set_attr "type" "mmx")])
18507
18508 (define_insn "lshrv4hi3"
18509 [(set (match_operand:V4HI 0 "register_operand" "=y")
18510 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
18511 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18512 "TARGET_MMX"
18513 "psrlw\\t{%2, %0|%0, %2}"
18514 [(set_attr "type" "mmx")])
18515
18516 (define_insn "lshrv2si3"
18517 [(set (match_operand:V2SI 0 "register_operand" "=y")
18518 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
18519 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18520 "TARGET_MMX"
18521 "psrld\\t{%2, %0|%0, %2}"
18522 [(set_attr "type" "mmx")])
18523
18524 ;; See logical MMX insns.
18525 (define_insn "mmx_lshrdi3"
18526 [(set (match_operand:DI 0 "register_operand" "=y")
18527 (unspec:DI
18528 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
18529 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
18530 "TARGET_MMX"
18531 "psrlq\\t{%2, %0|%0, %2}"
18532 [(set_attr "type" "mmx")])
18533
18534 (define_insn "ashlv4hi3"
18535 [(set (match_operand:V4HI 0 "register_operand" "=y")
18536 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
18537 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18538 "TARGET_MMX"
18539 "psllw\\t{%2, %0|%0, %2}"
18540 [(set_attr "type" "mmx")])
18541
18542 (define_insn "ashlv2si3"
18543 [(set (match_operand:V2SI 0 "register_operand" "=y")
18544 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
18545 (match_operand:DI 2 "nonmemory_operand" "yi")))]
18546 "TARGET_MMX"
18547 "pslld\\t{%2, %0|%0, %2}"
18548 [(set_attr "type" "mmx")])
18549
18550 ;; See logical MMX insns.
18551 (define_insn "mmx_ashldi3"
18552 [(set (match_operand:DI 0 "register_operand" "=y")
18553 (unspec:DI
18554 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
18555 (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
18556 "TARGET_MMX"
18557 "psllq\\t{%2, %0|%0, %2}"
18558 [(set_attr "type" "mmx")])
18559
18560
18561 ;; MMX pack/unpack insns.
18562
18563 (define_insn "mmx_packsswb"
18564 [(set (match_operand:V8QI 0 "register_operand" "=y")
18565 (vec_concat:V8QI
18566 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
18567 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
18568 "TARGET_MMX"
18569 "packsswb\\t{%2, %0|%0, %2}"
18570 [(set_attr "type" "mmx")])
18571
18572 (define_insn "mmx_packssdw"
18573 [(set (match_operand:V4HI 0 "register_operand" "=y")
18574 (vec_concat:V4HI
18575 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
18576 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
18577 "TARGET_MMX"
18578 "packssdw\\t{%2, %0|%0, %2}"
18579 [(set_attr "type" "mmx")])
18580
18581 (define_insn "mmx_packuswb"
18582 [(set (match_operand:V8QI 0 "register_operand" "=y")
18583 (vec_concat:V8QI
18584 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
18585 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
18586 "TARGET_MMX"
18587 "packuswb\\t{%2, %0|%0, %2}"
18588 [(set_attr "type" "mmx")])
18589
18590 (define_insn "mmx_punpckhbw"
18591 [(set (match_operand:V8QI 0 "register_operand" "=y")
18592 (vec_merge:V8QI
18593 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
18594 (parallel [(const_int 4)
18595 (const_int 0)
18596 (const_int 5)
18597 (const_int 1)
18598 (const_int 6)
18599 (const_int 2)
18600 (const_int 7)
18601 (const_int 3)]))
18602 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
18603 (parallel [(const_int 0)
18604 (const_int 4)
18605 (const_int 1)
18606 (const_int 5)
18607 (const_int 2)
18608 (const_int 6)
18609 (const_int 3)
18610 (const_int 7)]))
18611 (const_int 85)))]
18612 "TARGET_MMX"
18613 "punpckhbw\\t{%2, %0|%0, %2}"
18614 [(set_attr "type" "mmx")])
18615
18616 (define_insn "mmx_punpckhwd"
18617 [(set (match_operand:V4HI 0 "register_operand" "=y")
18618 (vec_merge:V4HI
18619 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
18620 (parallel [(const_int 0)
18621 (const_int 2)
18622 (const_int 1)
18623 (const_int 3)]))
18624 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
18625 (parallel [(const_int 2)
18626 (const_int 0)
18627 (const_int 3)
18628 (const_int 1)]))
18629 (const_int 5)))]
18630 "TARGET_MMX"
18631 "punpckhwd\\t{%2, %0|%0, %2}"
18632 [(set_attr "type" "mmx")])
18633
18634 (define_insn "mmx_punpckhdq"
18635 [(set (match_operand:V2SI 0 "register_operand" "=y")
18636 (vec_merge:V2SI
18637 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
18638 (parallel [(const_int 0)
18639 (const_int 1)]))
18640 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
18641 (parallel [(const_int 1)
18642 (const_int 0)]))
18643 (const_int 1)))]
18644 "TARGET_MMX"
18645 "punpckhdq\\t{%2, %0|%0, %2}"
18646 [(set_attr "type" "mmx")])
18647
18648 (define_insn "mmx_punpcklbw"
18649 [(set (match_operand:V8QI 0 "register_operand" "=y")
18650 (vec_merge:V8QI
18651 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
18652 (parallel [(const_int 0)
18653 (const_int 4)
18654 (const_int 1)
18655 (const_int 5)
18656 (const_int 2)
18657 (const_int 6)
18658 (const_int 3)
18659 (const_int 7)]))
18660 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
18661 (parallel [(const_int 4)
18662 (const_int 0)
18663 (const_int 5)
18664 (const_int 1)
18665 (const_int 6)
18666 (const_int 2)
18667 (const_int 7)
18668 (const_int 3)]))
18669 (const_int 85)))]
18670 "TARGET_MMX"
18671 "punpcklbw\\t{%2, %0|%0, %2}"
18672 [(set_attr "type" "mmx")])
18673
18674 (define_insn "mmx_punpcklwd"
18675 [(set (match_operand:V4HI 0 "register_operand" "=y")
18676 (vec_merge:V4HI
18677 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
18678 (parallel [(const_int 2)
18679 (const_int 0)
18680 (const_int 3)
18681 (const_int 1)]))
18682 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
18683 (parallel [(const_int 0)
18684 (const_int 2)
18685 (const_int 1)
18686 (const_int 3)]))
18687 (const_int 5)))]
18688 "TARGET_MMX"
18689 "punpcklwd\\t{%2, %0|%0, %2}"
18690 [(set_attr "type" "mmx")])
18691
18692 (define_insn "mmx_punpckldq"
18693 [(set (match_operand:V2SI 0 "register_operand" "=y")
18694 (vec_merge:V2SI
18695 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
18696 (parallel [(const_int 1)
18697 (const_int 0)]))
18698 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
18699 (parallel [(const_int 0)
18700 (const_int 1)]))
18701 (const_int 1)))]
18702 "TARGET_MMX"
18703 "punpckldq\\t{%2, %0|%0, %2}"
18704 [(set_attr "type" "mmx")])
18705
18706
18707 ;; Miscellaneous stuff
18708
18709 (define_insn "emms"
18710 [(unspec_volatile [(const_int 0)] 31)
18711 (clobber (reg:XF 8))
18712 (clobber (reg:XF 9))
18713 (clobber (reg:XF 10))
18714 (clobber (reg:XF 11))
18715 (clobber (reg:XF 12))
18716 (clobber (reg:XF 13))
18717 (clobber (reg:XF 14))
18718 (clobber (reg:XF 15))
18719 (clobber (reg:DI 29))
18720 (clobber (reg:DI 30))
18721 (clobber (reg:DI 31))
18722 (clobber (reg:DI 32))
18723 (clobber (reg:DI 33))
18724 (clobber (reg:DI 34))
18725 (clobber (reg:DI 35))
18726 (clobber (reg:DI 36))]
18727 "TARGET_MMX"
18728 "emms"
18729 [(set_attr "type" "mmx")
18730 (set_attr "memory" "unknown")])
18731
18732 (define_insn "ldmxcsr"
18733 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
18734 "TARGET_MMX"
18735 "ldmxcsr\\t%0"
18736 [(set_attr "type" "mmx")])
18737
18738 (define_insn "stmxcsr"
18739 [(set (match_operand:SI 0 "memory_operand" "=m")
18740 (unspec_volatile:SI [(const_int 0)] 40))]
18741 "TARGET_MMX"
18742 "stmxcsr\\t%0"
18743 [(set_attr "type" "mmx")])
18744
18745 (define_expand "sfence"
18746 [(set (match_dup 0)
18747 (unspec:BLK [(match_dup 0)] 44))]
18748 "TARGET_SSE"
18749 "
18750 {
18751 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18752 MEM_VOLATILE_P (operands[0]) = 1;
18753 }")
18754
18755 (define_insn "*sfence_insn"
18756 [(set (match_operand:BLK 0 "" "")
18757 (unspec:BLK [(match_dup 0)] 44))]
18758 "TARGET_SSE"
18759 "sfence"
18760 [(set_attr "type" "sse")
18761 (set_attr "memory" "unknown")])
18762
18763 (define_insn "prefetch"
18764 [(unspec [(match_operand:SI 0 "address_operand" "p")
18765 (match_operand:SI 1 "immediate_operand" "n")] 35)]
18766 "TARGET_SSE"
18767 "*
18768 {
18769 switch (INTVAL (operands[1]))
18770 {
18771 case 0:
18772 return \"prefetchnta\\t%a0\";
18773 case 1:
18774 return \"prefetcht0\\t%a0\";
18775 case 2:
18776 return \"prefetcht1\\t%a0\";
18777 case 3:
18778 return \"prefetcht2\\t%a0\";
18779 default:
18780 abort ();
18781 }
18782 }"
18783 [(set_attr "type" "sse")])
18784
This page took 0.831659 seconds and 4 git commands to generate.