1f341f4ab808b13e5b93ef48d88903a21477491e
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 ;; Free Software Foundation, Inc.
4 ;; Mostly by William Schelter.
5 ;;
6 ;; This file is part of GNU CC.
7 ;;
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA. */
22 ;;
23 ;; The original PO technology requires these to be ordered by speed,
24 ;; so that assigner will pick the fastest.
25 ;;
26 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;;
28 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
29 ;; updates for most instructions.
30 ;;
31 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
32 ;; constraint letters.
33 ;;
34 ;; The special asm out single letter directives following a '%' are:
35 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; operands[1].
37 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
38 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
39 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
40 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
41 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
42 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
43 ;; 'J' Print the appropriate jump operand.
44 ;;
45 ;; 'b' Print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; 'w' Likewise, print the HImode name of the register.
48 ;; 'k' Likewise, print the SImode name of the register.
49 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
50 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;;
52 ;; UNSPEC usage:
53 ;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode.
54 ;; operand 0 is the memory address to scan.
55 ;; operand 1 is a register containing the value to scan for. The mode
56 ;; of the scas opcode will be the same as the mode of this operand.
57 ;; operand 2 is the known alignment of operand 0.
58 ;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.
59 ;; operand 0 is the argument for `sin'.
60 ;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.
61 ;; operand 0 is the argument for `cos'.
62 ;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is
63 ;; always SImode. operand 0 is the size of the stack allocation.
64 ;; 4 This is the source of a fake SET of the frame pointer which is used to
65 ;; prevent insns referencing it being scheduled across the initial
66 ;; decrement of the stack pointer.
67 ;; 5 This is a `bsf' operation.
68 ;; 6 This is the @GOT offset of a PIC address.
69 ;; 7 This is the @GOTOFF offset of a PIC address.
70 ;; 8 This is a reference to a symbol's @PLT address.
71 ;; 9 This is an `fnstsw' operation.
72 ;; 10 This is a `sahf' operation.
73 ;; 11 This is a `fstcw' operation
74 ;; 12 This is behaviour of add when setting carry flag.
75
76 ;; For SSE/MMX support:
77 ;; 30 This is `fix', guaranteed to be truncating.
78 ;; 31 This is a `emms' operation.
79 ;; 32 This is a `maskmov' operation.
80 ;; 33 This is a `movmsk' operation.
81 ;; 34 This is a `non-temporal' move.
82 ;; 35 This is a `prefetch' operation.
83 ;; 36 This is used to distinguish COMISS from UCOMISS.
84 ;; 37 This is a `ldmxcsr' operation.
85 ;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
86 ;; 39 This is a forced `movups' instruction (rather than whatever movti does)
87 ;; 40 This is a `stmxcsr' operation.
88 ;; 41 This is a `shuffle' operation.
89 ;; 42 This is a `rcp' operation.
90 ;; 43 This is a `rsqsrt' operation.
91 ;; 44 This is a `sfence' operation.
92 ;; 45 This is a noop to prevent excessive combiner cleverness.
93
94 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
95 ;; from i386.c.
96
97 \f
98 ;; Processor type. This attribute must exactly match the processor_type
99 ;; enumeration in i386.h.
100 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon"
101 (const (symbol_ref "ix86_cpu")))
102
103 ;; A basic instruction type. Refinements due to arguments to be
104 ;; provided in other attributes.
105 (define_attr "type"
106 "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"
107 (const_string "other"))
108
109 ;; Main data type used by the insn
110 (define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF"
111 (const_string "unknown"))
112
113 ;; Set for i387 operations.
114 (define_attr "i387" ""
115 (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
116 (const_int 1)
117 (const_int 0)))
118
119 ;; The (bounding maximum) length of an instruction immediate.
120 (define_attr "length_immediate" ""
121 (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
122 (const_int 0)
123 (eq_attr "i387" "1")
124 (const_int 0)
125 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
126 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
127 (eq_attr "type" "imov,test")
128 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
129 (eq_attr "type" "call")
130 (if_then_else (match_operand 0 "constant_call_address_operand" "")
131 (const_int 4)
132 (const_int 0))
133 (eq_attr "type" "callv")
134 (if_then_else (match_operand 1 "constant_call_address_operand" "")
135 (const_int 4)
136 (const_int 0))
137 (eq_attr "type" "ibr")
138 (if_then_else (and (ge (minus (match_dup 0) (pc))
139 (const_int -128))
140 (lt (minus (match_dup 0) (pc))
141 (const_int 124)))
142 (const_int 1)
143 (const_int 4))
144 ]
145 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
146
147 ;; The (bounding maximum) length of an instruction address.
148 (define_attr "length_address" ""
149 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
150 (const_int 0)
151 (and (eq_attr "type" "call")
152 (match_operand 1 "constant_call_address_operand" ""))
153 (const_int 0)
154 (and (eq_attr "type" "callv")
155 (match_operand 1 "constant_call_address_operand" ""))
156 (const_int 0)
157 ]
158 (symbol_ref "ix86_attr_length_address_default (insn)")))
159
160 ;; Set when length prefix is used.
161 (define_attr "prefix_data16" ""
162 (if_then_else (eq_attr "mode" "HI")
163 (const_int 1)
164 (const_int 0)))
165
166 ;; Set when string REP prefix is used.
167 (define_attr "prefix_rep" "" (const_int 0))
168
169 ;; Set when 0f opcode prefix is used.
170 (define_attr "prefix_0f" ""
171 (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
172 (const_int 1)
173 (const_int 0)))
174
175 ;; Set when modrm byte is used.
176 (define_attr "modrm" ""
177 (cond [(eq_attr "type" "str,cld")
178 (const_int 0)
179 (eq_attr "i387" "1")
180 (const_int 0)
181 (and (eq_attr "type" "incdec")
182 (ior (match_operand:SI 1 "register_operand" "")
183 (match_operand:HI 1 "register_operand" "")))
184 (const_int 0)
185 (and (eq_attr "type" "push")
186 (not (match_operand 1 "memory_operand" "")))
187 (const_int 0)
188 (and (eq_attr "type" "pop")
189 (not (match_operand 0 "memory_operand" "")))
190 (const_int 0)
191 (and (eq_attr "type" "imov")
192 (and (match_operand 0 "register_operand" "")
193 (match_operand 1 "immediate_operand" "")))
194 (const_int 0)
195 ]
196 (const_int 1)))
197
198 ;; The (bounding maximum) length of an instruction in bytes.
199 (define_attr "length" ""
200 (cond [(eq_attr "type" "other,multi")
201 (const_int 16)
202 ]
203 (plus (plus (attr "modrm")
204 (plus (attr "prefix_0f")
205 (plus (attr "i387")
206 (const_int 1))))
207 (plus (attr "prefix_rep")
208 (plus (attr "prefix_data16")
209 (plus (attr "length_immediate")
210 (attr "length_address")))))))
211
212 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
213 ;; `store' if there is a simple memory reference therein, or `unknown'
214 ;; if the instruction is complex.
215
216 (define_attr "memory" "none,load,store,both,unknown"
217 (cond [(eq_attr "type" "other,multi,str")
218 (const_string "unknown")
219 (eq_attr "type" "lea,fcmov,fpspc,cld")
220 (const_string "none")
221 (eq_attr "type" "push")
222 (if_then_else (match_operand 1 "memory_operand" "")
223 (const_string "both")
224 (const_string "store"))
225 (eq_attr "type" "pop,setcc")
226 (if_then_else (match_operand 0 "memory_operand" "")
227 (const_string "both")
228 (const_string "load"))
229 (eq_attr "type" "icmp,test")
230 (if_then_else (ior (match_operand 0 "memory_operand" "")
231 (match_operand 1 "memory_operand" ""))
232 (const_string "load")
233 (const_string "none"))
234 (eq_attr "type" "ibr")
235 (if_then_else (match_operand 0 "memory_operand" "")
236 (const_string "load")
237 (const_string "none"))
238 (eq_attr "type" "call")
239 (if_then_else (match_operand 0 "constant_call_address_operand" "")
240 (const_string "none")
241 (const_string "load"))
242 (eq_attr "type" "callv")
243 (if_then_else (match_operand 1 "constant_call_address_operand" "")
244 (const_string "none")
245 (const_string "load"))
246 (and (eq_attr "type" "alu1,negnot")
247 (match_operand 1 "memory_operand" ""))
248 (const_string "both")
249 (and (match_operand 0 "memory_operand" "")
250 (match_operand 1 "memory_operand" ""))
251 (const_string "both")
252 (match_operand 0 "memory_operand" "")
253 (const_string "store")
254 (match_operand 1 "memory_operand" "")
255 (const_string "load")
256 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
257 (match_operand 2 "memory_operand" ""))
258 (const_string "load")
259 (and (eq_attr "type" "icmov")
260 (match_operand 3 "memory_operand" ""))
261 (const_string "load")
262 ]
263 (const_string "none")))
264
265 ;; Indicates if an instruction has both an immediate and a displacement.
266
267 (define_attr "imm_disp" "false,true,unknown"
268 (cond [(eq_attr "type" "other,multi")
269 (const_string "unknown")
270 (and (eq_attr "type" "icmp,test,imov")
271 (and (match_operand 0 "memory_displacement_operand" "")
272 (match_operand 1 "immediate_operand" "")))
273 (const_string "true")
274 (and (eq_attr "type" "alu,ishift,imul,idiv")
275 (and (match_operand 0 "memory_displacement_operand" "")
276 (match_operand 2 "immediate_operand" "")))
277 (const_string "true")
278 ]
279 (const_string "false")))
280
281 ;; Indicates if an FP operation has an integer source.
282
283 (define_attr "fp_int_src" "false,true"
284 (const_string "false"))
285
286 ;; Describe a user's asm statement.
287 (define_asm_attributes
288 [(set_attr "length" "128")
289 (set_attr "type" "multi")])
290 \f
291 ;; Pentium Scheduling
292 ;;
293 ;; The Pentium is an in-order core with two integer pipelines.
294
295 ;; True for insns that behave like prefixed insns on the Pentium.
296 (define_attr "pent_prefix" "false,true"
297 (if_then_else (ior (eq_attr "prefix_0f" "1")
298 (ior (eq_attr "prefix_data16" "1")
299 (eq_attr "prefix_rep" "1")))
300 (const_string "true")
301 (const_string "false")))
302
303 ;; Categorize how an instruction slots.
304
305 ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
306 ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
307 ;; rules, because it results in noticeably better code on non-MMX Pentium
308 ;; and doesn't hurt much on MMX. (Prefixed instructions are not very
309 ;; common, so the scheduler usualy has a non-prefixed insn to pair).
310
311 (define_attr "pent_pair" "uv,pu,pv,np"
312 (cond [(eq_attr "imm_disp" "true")
313 (const_string "np")
314 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
315 (and (eq_attr "type" "pop,push")
316 (eq_attr "memory" "!both")))
317 (if_then_else (eq_attr "pent_prefix" "true")
318 (const_string "pu")
319 (const_string "uv"))
320 (eq_attr "type" "ibr")
321 (const_string "pv")
322 (and (eq_attr "type" "ishift")
323 (match_operand 2 "const_int_operand" ""))
324 (const_string "pu")
325 (and (eq_attr "type" "call")
326 (match_operand 0 "constant_call_address_operand" ""))
327 (const_string "pv")
328 (and (eq_attr "type" "callv")
329 (match_operand 1 "constant_call_address_operand" ""))
330 (const_string "pv")
331 ]
332 (const_string "np")))
333
334 ;; Rough readiness numbers. Fine tuning happens in i386.c.
335 ;;
336 ;; u describes pipe U
337 ;; v describes pipe V
338 ;; uv describes either pipe U or V for those that can issue to either
339 ;; np describes not paring
340 ;; fpu describes fpu
341 ;; fpm describes fp insns of different types are not pipelined.
342 ;;
343 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
344
345 (define_function_unit "pent_np" 1 0
346 (and (eq_attr "cpu" "pentium")
347 (eq_attr "type" "imul"))
348 11 11)
349
350 (define_function_unit "pent_mul" 1 1
351 (and (eq_attr "cpu" "pentium")
352 (eq_attr "type" "imul"))
353 11 11)
354
355 ;; Rep movs takes minimally 12 cycles.
356 (define_function_unit "pent_np" 1 0
357 (and (eq_attr "cpu" "pentium")
358 (eq_attr "type" "str"))
359 12 12)
360
361 ; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
362 (define_function_unit "pent_np" 1 0
363 (and (eq_attr "cpu" "pentium")
364 (eq_attr "type" "idiv"))
365 46 46)
366
367 ; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
368 ; 3 cycles for XFmode. Stores takes 2 cycles for SF/DF and 3 for XF.
369 ; fldz and fld1 takes 2 cycles. Only reg-reg moves are pairable.
370 ; The integer <-> fp conversion is not modeled correctly. Fild behaves
371 ; like normal fp operation and fist takes 6 cycles.
372
373 (define_function_unit "fpu" 1 0
374 (and (eq_attr "cpu" "pentium")
375 (and (eq_attr "type" "fmov")
376 (and (eq_attr "memory" "load,store")
377 (eq_attr "mode" "XF"))))
378 3 3)
379
380 (define_function_unit "pent_np" 1 0
381 (and (eq_attr "cpu" "pentium")
382 (and (eq_attr "type" "fmov")
383 (and (eq_attr "memory" "load,store")
384 (eq_attr "mode" "XF"))))
385 3 3)
386
387 (define_function_unit "fpu" 1 0
388 (and (eq_attr "cpu" "pentium")
389 (and (eq_attr "type" "fmov")
390 (ior (match_operand 1 "immediate_operand" "")
391 (eq_attr "memory" "store"))))
392 2 2)
393
394 (define_function_unit "pent_np" 1 0
395 (and (eq_attr "cpu" "pentium")
396 (and (eq_attr "type" "fmov")
397 (ior (match_operand 1 "immediate_operand" "")
398 (eq_attr "memory" "store"))))
399 2 2)
400
401 (define_function_unit "pent_np" 1 0
402 (and (eq_attr "cpu" "pentium")
403 (eq_attr "type" "cld"))
404 2 2)
405
406 (define_function_unit "fpu" 1 0
407 (and (eq_attr "cpu" "pentium")
408 (and (eq_attr "type" "fmov")
409 (eq_attr "memory" "none,load")))
410 1 1)
411
412 ; Read/Modify/Write instructions usually take 3 cycles.
413 (define_function_unit "pent_u" 1 0
414 (and (eq_attr "cpu" "pentium")
415 (and (eq_attr "type" "alu,alu1,ishift")
416 (and (eq_attr "pent_pair" "pu")
417 (eq_attr "memory" "both"))))
418 3 3)
419
420 (define_function_unit "pent_uv" 2 0
421 (and (eq_attr "cpu" "pentium")
422 (and (eq_attr "type" "alu,alu1,ishift")
423 (and (eq_attr "pent_pair" "!np")
424 (eq_attr "memory" "both"))))
425 3 3)
426
427 (define_function_unit "pent_np" 1 0
428 (and (eq_attr "cpu" "pentium")
429 (and (eq_attr "type" "alu,alu1,negnot,ishift")
430 (and (eq_attr "pent_pair" "np")
431 (eq_attr "memory" "both"))))
432 3 3)
433
434 ; Read/Modify or Modify/Write instructions usually take 2 cycles.
435 (define_function_unit "pent_u" 1 0
436 (and (eq_attr "cpu" "pentium")
437 (and (eq_attr "type" "alu,ishift")
438 (and (eq_attr "pent_pair" "pu")
439 (eq_attr "memory" "load,store"))))
440 2 2)
441
442 (define_function_unit "pent_uv" 2 0
443 (and (eq_attr "cpu" "pentium")
444 (and (eq_attr "type" "alu,ishift")
445 (and (eq_attr "pent_pair" "!np")
446 (eq_attr "memory" "load,store"))))
447 2 2)
448
449 (define_function_unit "pent_np" 1 0
450 (and (eq_attr "cpu" "pentium")
451 (and (eq_attr "type" "alu,ishift")
452 (and (eq_attr "pent_pair" "np")
453 (eq_attr "memory" "load,store"))))
454 2 2)
455
456 ; Insns w/o memory operands and move instructions usually take one cycle.
457 (define_function_unit "pent_u" 1 0
458 (and (eq_attr "cpu" "pentium")
459 (eq_attr "pent_pair" "pu"))
460 1 1)
461
462 (define_function_unit "pent_v" 1 0
463 (and (eq_attr "cpu" "pentium")
464 (eq_attr "pent_pair" "pv"))
465 1 1)
466
467 (define_function_unit "pent_uv" 2 0
468 (and (eq_attr "cpu" "pentium")
469 (eq_attr "pent_pair" "!np"))
470 1 1)
471
472 (define_function_unit "pent_np" 1 0
473 (and (eq_attr "cpu" "pentium")
474 (eq_attr "pent_pair" "np"))
475 1 1)
476
477 ; Pairable insns only conflict with other non-pairable insns.
478 (define_function_unit "pent_np" 1 0
479 (and (eq_attr "cpu" "pentium")
480 (and (eq_attr "type" "alu,alu1,ishift")
481 (and (eq_attr "pent_pair" "!np")
482 (eq_attr "memory" "both"))))
483 3 3
484 [(eq_attr "pent_pair" "np")])
485
486 (define_function_unit "pent_np" 1 0
487 (and (eq_attr "cpu" "pentium")
488 (and (eq_attr "type" "alu,alu1,ishift")
489 (and (eq_attr "pent_pair" "!np")
490 (eq_attr "memory" "load,store"))))
491 2 2
492 [(eq_attr "pent_pair" "np")])
493
494 (define_function_unit "pent_np" 1 0
495 (and (eq_attr "cpu" "pentium")
496 (eq_attr "pent_pair" "!np"))
497 1 1
498 [(eq_attr "pent_pair" "np")])
499
500 ; Floating point instructions usually blocks cycle longer when combined with
501 ; integer instructions, because of the inpaired fxch instruction.
502 (define_function_unit "pent_np" 1 0
503 (and (eq_attr "cpu" "pentium")
504 (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
505 2 2
506 [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
507
508 (define_function_unit "fpu" 1 0
509 (and (eq_attr "cpu" "pentium")
510 (eq_attr "type" "fcmp,fxch,fsgn"))
511 1 1)
512
513 ; Addition takes 3 cycles; assume other random cruft does as well.
514 ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
515 (define_function_unit "fpu" 1 0
516 (and (eq_attr "cpu" "pentium")
517 (eq_attr "type" "fop,fop1"))
518 3 1)
519
520 ; Multiplication takes 3 cycles and is only half pipelined.
521 (define_function_unit "fpu" 1 0
522 (and (eq_attr "cpu" "pentium")
523 (eq_attr "type" "fmul"))
524 3 1)
525
526 (define_function_unit "pent_mul" 1 1
527 (and (eq_attr "cpu" "pentium")
528 (eq_attr "type" "fmul"))
529 2 2)
530
531 ; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles.
532 ; They can overlap with integer insns. Only the last two cycles can overlap
533 ; with other fp insns. Only fsin/fcos can overlap with multiplies.
534 ; Only last two cycles of fsin/fcos can overlap with other instructions.
535 (define_function_unit "fpu" 1 0
536 (and (eq_attr "cpu" "pentium")
537 (eq_attr "type" "fdiv"))
538 39 37)
539
540 (define_function_unit "pent_mul" 1 1
541 (and (eq_attr "cpu" "pentium")
542 (eq_attr "type" "fdiv"))
543 39 39)
544
545 (define_function_unit "fpu" 1 0
546 (and (eq_attr "cpu" "pentium")
547 (eq_attr "type" "fpspc"))
548 70 68)
549
550 (define_function_unit "pent_mul" 1 1
551 (and (eq_attr "cpu" "pentium")
552 (eq_attr "type" "fpspc"))
553 70 70)
554 \f
555 ;; Pentium Pro/PII Scheduling
556 ;;
557 ;; The PPro has an out-of-order core, but the instruction decoders are
558 ;; naturally in-order and asymmetric. We get best performance by scheduling
559 ;; for the decoders, for in doing so we give the oo execution unit the
560 ;; most choices.
561
562 ;; Categorize how many uops an ia32 instruction evaluates to:
563 ;; one -- an instruction with 1 uop can be decoded by any of the
564 ;; three decoders.
565 ;; few -- an instruction with 1 to 4 uops can be decoded only by
566 ;; decoder 0.
567 ;; many -- a complex instruction may take an unspecified number of
568 ;; cycles to decode in decoder 0.
569
570 (define_attr "ppro_uops" "one,few,many"
571 (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
572 (const_string "many")
573 (eq_attr "type" "icmov,fcmov,str,cld")
574 (const_string "few")
575 (eq_attr "type" "imov")
576 (if_then_else (eq_attr "memory" "store,both")
577 (const_string "few")
578 (const_string "one"))
579 (eq_attr "memory" "!none")
580 (const_string "few")
581 ]
582 (const_string "one")))
583
584 ;; Rough readiness numbers. Fine tuning happens in i386.c.
585 ;;
586 ;; p0 describes port 0.
587 ;; p01 describes ports 0 and 1 as a pair; alu insns can issue to either.
588 ;; p2 describes port 2 for loads.
589 ;; p34 describes ports 3 and 4 for stores.
590 ;; fpu describes the fpu accessed via port 0.
591 ;; ??? It is less than clear if there are separate fadd and fmul units
592 ;; that could operate in parallel.
593 ;;
594 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
595
596 (define_function_unit "ppro_p0" 1 0
597 (and (eq_attr "cpu" "pentiumpro")
598 (eq_attr "type" "ishift,lea,ibr,cld"))
599 1 1)
600
601 (define_function_unit "ppro_p0" 1 0
602 (and (eq_attr "cpu" "pentiumpro")
603 (eq_attr "type" "imul"))
604 4 1)
605
606 ;; ??? Does the divider lock out the pipe while it works,
607 ;; or is there a disconnected unit?
608 (define_function_unit "ppro_p0" 1 0
609 (and (eq_attr "cpu" "pentiumpro")
610 (eq_attr "type" "idiv"))
611 17 17)
612
613 (define_function_unit "ppro_p0" 1 0
614 (and (eq_attr "cpu" "pentiumpro")
615 (eq_attr "type" "fop,fop1,fsgn"))
616 3 1)
617
618 (define_function_unit "ppro_p0" 1 0
619 (and (eq_attr "cpu" "pentiumpro")
620 (eq_attr "type" "fcmov"))
621 2 1)
622
623 (define_function_unit "ppro_p0" 1 0
624 (and (eq_attr "cpu" "pentiumpro")
625 (eq_attr "type" "fcmp"))
626 1 1)
627
628 (define_function_unit "ppro_p0" 1 0
629 (and (eq_attr "cpu" "pentiumpro")
630 (eq_attr "type" "fmov"))
631 1 1)
632
633 (define_function_unit "ppro_p0" 1 0
634 (and (eq_attr "cpu" "pentiumpro")
635 (eq_attr "type" "fmul"))
636 5 1)
637
638 (define_function_unit "ppro_p0" 1 0
639 (and (eq_attr "cpu" "pentiumpro")
640 (eq_attr "type" "fdiv,fpspc"))
641 56 1)
642
643 (define_function_unit "ppro_p01" 2 0
644 (and (eq_attr "cpu" "pentiumpro")
645 (eq_attr "type" "!imov,fmov"))
646 1 1)
647
648 (define_function_unit "ppro_p01" 2 0
649 (and (and (eq_attr "cpu" "pentiumpro")
650 (eq_attr "type" "imov,fmov"))
651 (eq_attr "memory" "none"))
652 1 1)
653
654 (define_function_unit "ppro_p2" 1 0
655 (and (eq_attr "cpu" "pentiumpro")
656 (ior (eq_attr "type" "pop")
657 (eq_attr "memory" "load,both")))
658 3 1)
659
660 (define_function_unit "ppro_p34" 1 0
661 (and (eq_attr "cpu" "pentiumpro")
662 (ior (eq_attr "type" "push")
663 (eq_attr "memory" "store,both")))
664 1 1)
665
666 (define_function_unit "fpu" 1 0
667 (and (eq_attr "cpu" "pentiumpro")
668 (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
669 1 1)
670
671 (define_function_unit "fpu" 1 0
672 (and (eq_attr "cpu" "pentiumpro")
673 (eq_attr "type" "fmul"))
674 5 2)
675
676 (define_function_unit "fpu" 1 0
677 (and (eq_attr "cpu" "pentiumpro")
678 (eq_attr "type" "fdiv,fpspc"))
679 56 56)
680
681 ;; imul uses the fpu. ??? does it have the same throughput as fmul?
682 (define_function_unit "fpu" 1 0
683 (and (eq_attr "cpu" "pentiumpro")
684 (eq_attr "type" "imul"))
685 4 1)
686 \f
687 ;; AMD K6/K6-2 Scheduling
688 ;;
689 ;; The K6 has similar architecture to PPro. Important difference is, that
690 ;; there are only two decoders and they seems to be much slower than execution
691 ;; units. So we have to pay much more attention to proper decoding for
692 ;; schedulers. We share most of scheduler code for PPro in i386.c
693 ;;
694 ;; The fp unit is not pipelined and do one operation per two cycles including
695 ;; the FXCH.
696 ;;
697 ;; alu describes both ALU units (ALU-X and ALU-Y).
698 ;; alux describes X alu unit
699 ;; fpu describes FPU unit
700 ;; load describes load unit.
701 ;; branch describes branch unit.
702 ;; store decsribes store unit. This unit is not modelled completely and only
703 ;; used to model lea operation. Otherwise it lie outside of the critical
704 ;; path.
705 ;;
706 ;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
707
708 ;; The decoder specification is in the PPro section above!
709
710 ;; Shift instructions and certain arithmetic are issued only to X pipe.
711 (define_function_unit "k6_alux" 1 0
712 (and (eq_attr "cpu" "k6")
713 (eq_attr "type" "ishift,alu1,negnot,cld"))
714 1 1)
715
716 ;; The QI mode arithmetic is issued to X pipe only.
717 (define_function_unit "k6_alux" 1 0
718 (and (eq_attr "cpu" "k6")
719 (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
720 (match_operand:QI 0 "general_operand" "")))
721 1 1)
722
723 (define_function_unit "k6_alu" 2 0
724 (and (eq_attr "cpu" "k6")
725 (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
726 1 1)
727
728 (define_function_unit "k6_alu" 2 0
729 (and (eq_attr "cpu" "k6")
730 (and (eq_attr "type" "imov")
731 (eq_attr "memory" "none")))
732 1 1)
733
734 (define_function_unit "k6_branch" 1 0
735 (and (eq_attr "cpu" "k6")
736 (eq_attr "type" "call,callv,ibr"))
737 1 1)
738
739 ;; Load unit have two cycle latency, but we take care for it in adjust_cost
740 (define_function_unit "k6_load" 1 0
741 (and (eq_attr "cpu" "k6")
742 (ior (eq_attr "type" "pop")
743 (eq_attr "memory" "load,both")))
744 1 1)
745
746 (define_function_unit "k6_load" 1 0
747 (and (eq_attr "cpu" "k6")
748 (and (eq_attr "type" "str")
749 (eq_attr "memory" "load,both")))
750 10 10)
751
752 ;; Lea have two instructions, so latency is probably 2
753 (define_function_unit "k6_store" 1 0
754 (and (eq_attr "cpu" "k6")
755 (eq_attr "type" "lea"))
756 2 1)
757
758 (define_function_unit "k6_store" 1 0
759 (and (eq_attr "cpu" "k6")
760 (eq_attr "type" "str"))
761 10 10)
762
763 (define_function_unit "k6_store" 1 0
764 (and (eq_attr "cpu" "k6")
765 (ior (eq_attr "type" "push")
766 (eq_attr "memory" "store,both")))
767 1 1)
768
769 (define_function_unit "k6_fpu" 1 1
770 (and (eq_attr "cpu" "k6")
771 (eq_attr "type" "fop,fop1,fmov,fcmp"))
772 2 2)
773
774 (define_function_unit "k6_fpu" 1 1
775 (and (eq_attr "cpu" "k6")
776 (eq_attr "type" "fmul"))
777 2 2)
778
779 ;; ??? Guess
780 (define_function_unit "k6_fpu" 1 1
781 (and (eq_attr "cpu" "k6")
782 (eq_attr "type" "fdiv,fpspc"))
783 56 56)
784
785 (define_function_unit "k6_alu" 2 0
786 (and (eq_attr "cpu" "k6")
787 (eq_attr "type" "imul"))
788 2 2)
789
790 (define_function_unit "k6_alux" 1 0
791 (and (eq_attr "cpu" "k6")
792 (eq_attr "type" "imul"))
793 2 2)
794
795 ;; ??? Guess
796 (define_function_unit "k6_alu" 2 0
797 (and (eq_attr "cpu" "k6")
798 (eq_attr "type" "idiv"))
799 17 17)
800
801 (define_function_unit "k6_alux" 1 0
802 (and (eq_attr "cpu" "k6")
803 (eq_attr "type" "idiv"))
804 17 17)
805 \f
806 ;; AMD Athlon Scheduling
807 ;;
808 ;; The Athlon does contain three pipelined FP units, three integer units and
809 ;; three address generation units.
810 ;;
811 ;; The predecode logic is determining boundaries of instructions in the 64
812 ;; byte cache line. So the cache line straddling problem of K6 might be issue
813 ;; here as well, but it is not noted in the documentation.
814 ;;
815 ;; Three DirectPath instructions decoders and only one VectorPath decoder
816 ;; is available. They can decode three DirectPath instructions or one VectorPath
817 ;; instruction per cycle.
818 ;; Decoded macro instructions are then passed to 72 entry instruction control
819 ;; unit, that passes
820 ;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
821 ;;
822 ;; The load/store queue unit is not attached to the schedulers but
823 ;; communicates with all the execution units seperately instead.
824
825 (define_attr "athlon_decode" "direct,vector"
826 (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
827 (const_string "vector")
828 (and (eq_attr "type" "push")
829 (match_operand 1 "memory_operand" ""))
830 (const_string "vector")
831 (and (eq_attr "type" "fmov")
832 (and (eq_attr "memory" "load,store")
833 (eq_attr "mode" "XF")))
834 (const_string "vector")]
835 (const_string "direct")))
836
837 (define_function_unit "athlon_vectordec" 1 0
838 (and (eq_attr "cpu" "athlon")
839 (eq_attr "athlon_decode" "vector"))
840 1 1)
841
842 (define_function_unit "athlon_directdec" 3 0
843 (and (eq_attr "cpu" "athlon")
844 (eq_attr "athlon_decode" "direct"))
845 1 1)
846
847 (define_function_unit "athlon_vectordec" 1 0
848 (and (eq_attr "cpu" "athlon")
849 (eq_attr "athlon_decode" "direct"))
850 1 1 [(eq_attr "athlon_decode" "vector")])
851
852 (define_function_unit "athlon_ieu" 3 0
853 (and (eq_attr "cpu" "athlon")
854 (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
855 1 1)
856
857 (define_function_unit "athlon_ieu" 3 0
858 (and (eq_attr "cpu" "athlon")
859 (eq_attr "type" "str"))
860 15 15)
861
862 (define_function_unit "athlon_ieu" 3 0
863 (and (eq_attr "cpu" "athlon")
864 (eq_attr "type" "imul"))
865 5 0)
866
867 (define_function_unit "athlon_ieu" 3 0
868 (and (eq_attr "cpu" "athlon")
869 (eq_attr "type" "idiv"))
870 42 0)
871
872 (define_function_unit "athlon_muldiv" 1 0
873 (and (eq_attr "cpu" "athlon")
874 (eq_attr "type" "imul"))
875 5 0)
876
877 (define_function_unit "athlon_muldiv" 1 0
878 (and (eq_attr "cpu" "athlon")
879 (eq_attr "type" "idiv"))
880 42 42)
881
882 (define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
883 (cond [(eq_attr "type" "fop,fop1,fcmp")
884 (const_string "add")
885 (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
886 (const_string "mul")
887 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
888 (const_string "store")
889 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
890 (const_string "any")
891 (and (eq_attr "type" "fmov")
892 (ior (match_operand:SI 1 "register_operand" "")
893 (match_operand 1 "immediate_operand" "")))
894 (const_string "store")
895 (eq_attr "type" "fmov")
896 (const_string "muladd")]
897 (const_string "none")))
898
899 ;; We use latencies 1 for definitions. This is OK to model colisions
900 ;; in execution units. The real latencies are modeled in the "fp" pipeline.
901
902 ;; fsin, fcos: 96-192
903 ;; fsincos: 107-211
904 ;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
905 (define_function_unit "athlon_fp" 3 0
906 (and (eq_attr "cpu" "athlon")
907 (eq_attr "type" "fpspc"))
908 100 1)
909
910 ;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
911 (define_function_unit "athlon_fp" 3 0
912 (and (eq_attr "cpu" "athlon")
913 (eq_attr "type" "fdiv"))
914 24 1)
915
916 (define_function_unit "athlon_fp" 3 0
917 (and (eq_attr "cpu" "athlon")
918 (eq_attr "type" "fop,fop1,fmul"))
919 4 1)
920
921 ;; XFmode loads are slow.
922 ;; XFmode store is slow too (8 cycles), but we don't need to model it, because
923 ;; there are no dependent instructions.
924
925 (define_function_unit "athlon_fp" 3 0
926 (and (eq_attr "cpu" "athlon")
927 (and (eq_attr "type" "fmov")
928 (and (eq_attr "memory" "load")
929 (eq_attr "mode" "XF"))))
930 10 1)
931
932 (define_function_unit "athlon_fp" 3 0
933 (and (eq_attr "cpu" "athlon")
934 (eq_attr "type" "fmov,fsgn"))
935 2 1)
936
937 ;; fcmp and ftst instructions
938 (define_function_unit "athlon_fp" 3 0
939 (and (eq_attr "cpu" "athlon")
940 (and (eq_attr "type" "fcmp")
941 (eq_attr "athlon_decode" "direct")))
942 3 1)
943
944 ;; fcmpi instructions.
945 (define_function_unit "athlon_fp" 3 0
946 (and (eq_attr "cpu" "athlon")
947 (and (eq_attr "type" "fcmp")
948 (eq_attr "athlon_decode" "vector")))
949 3 1)
950
951 (define_function_unit "athlon_fp" 3 0
952 (and (eq_attr "cpu" "athlon")
953 (eq_attr "type" "fcmov"))
954 7 1)
955
956 (define_function_unit "athlon_fp_mul" 1 0
957 (and (eq_attr "cpu" "athlon")
958 (eq_attr "athlon_fpunits" "mul"))
959 1 1)
960
961 (define_function_unit "athlon_fp_add" 1 0
962 (and (eq_attr "cpu" "athlon")
963 (eq_attr "athlon_fpunits" "add"))
964 1 1)
965
966 (define_function_unit "athlon_fp_muladd" 2 0
967 (and (eq_attr "cpu" "athlon")
968 (eq_attr "athlon_fpunits" "muladd,mul,add"))
969 1 1)
970
971 (define_function_unit "athlon_fp_store" 1 0
972 (and (eq_attr "cpu" "athlon")
973 (eq_attr "athlon_fpunits" "store"))
974 1 1)
975
976 ;; We don't need to model the Adress Generation Unit, since we don't model
977 ;; the re-order buffer yet and thus we never schedule more than three operations
978 ;; at time. Later we may want to experiment with MD_SCHED macros modeling the
979 ;; decoders independently on the functional units.
980
981 ;(define_function_unit "athlon_agu" 3 0
982 ; (and (eq_attr "cpu" "athlon")
983 ; (and (eq_attr "memory" "!none")
984 ; (eq_attr "athlon_fpunits" "none")))
985 ; 1 1)
986
987 ;; Model load unit to avoid too long sequences of loads. We don't need to
988 ;; model store queue, since it is hardly going to be bottleneck.
989
990 (define_function_unit "athlon_load" 2 0
991 (and (eq_attr "cpu" "athlon")
992 (eq_attr "memory" "load,both"))
993 1 1)
994
995 \f
996 ;; Compare instructions.
997
998 ;; All compare insns have expanders that save the operands away without
999 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
1000 ;; after the cmp) will actually emit the cmpM.
1001
1002 (define_expand "cmpdi"
1003 [(set (reg:CC 17)
1004 (compare:CC (match_operand:DI 0 "general_operand" "")
1005 (match_operand:DI 1 "general_operand" "")))]
1006 ""
1007 "
1008 {
1009 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1010 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1011 operands[0] = force_reg (DImode, operands[0]);
1012 ix86_compare_op0 = operands[0];
1013 ix86_compare_op1 = operands[1];
1014 DONE;
1015 }")
1016
1017 (define_expand "cmpsi"
1018 [(set (reg:CC 17)
1019 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
1020 (match_operand:SI 1 "general_operand" "")))]
1021 ""
1022 "
1023 {
1024 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1025 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1026 operands[0] = force_reg (SImode, operands[0]);
1027 ix86_compare_op0 = operands[0];
1028 ix86_compare_op1 = operands[1];
1029 DONE;
1030 }")
1031
1032 (define_expand "cmphi"
1033 [(set (reg:CC 17)
1034 (compare:CC (match_operand:HI 0 "general_operand" "")
1035 (match_operand:HI 1 "general_operand" "")))]
1036 ""
1037 "
1038 {
1039 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1040 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1041 operands[0] = force_reg (HImode, operands[0]);
1042 ix86_compare_op0 = operands[0];
1043 ix86_compare_op1 = operands[1];
1044 DONE;
1045 }")
1046
1047 (define_expand "cmpqi"
1048 [(set (reg:CC 17)
1049 (compare:CC (match_operand:QI 0 "general_operand" "")
1050 (match_operand:QI 1 "general_operand" "")))]
1051 "TARGET_QIMODE_MATH"
1052 "
1053 {
1054 if ((GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1055 || (CONSTANT_P (operands[0]) && CONSTANT_P (operands[1])))
1056 operands[0] = force_reg (QImode, operands[0]);
1057 ix86_compare_op0 = operands[0];
1058 ix86_compare_op1 = operands[1];
1059 DONE;
1060 }")
1061
1062 (define_insn "*cmpsi_ccno_1"
1063 [(set (reg 17)
1064 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1065 (match_operand:SI 1 "const0_operand" "n,n")))]
1066 "ix86_match_ccmode (insn, CCNOmode)"
1067 "@
1068 test{l}\\t{%0, %0|%0, %0}
1069 cmp{l}\\t{%1, %0|%0, %1}"
1070 [(set_attr "type" "test,icmp")
1071 (set_attr "length_immediate" "0,1")
1072 (set_attr "mode" "SI")])
1073
1074 (define_insn "*cmpsi_minus_1"
1075 [(set (reg 17)
1076 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1077 (match_operand:SI 1 "general_operand" "ri,mr"))
1078 (const_int 0)))]
1079 "ix86_match_ccmode (insn, CCGOCmode)"
1080 "cmp{l}\\t{%1, %0|%0, %1}"
1081 [(set_attr "type" "icmp")
1082 (set_attr "mode" "SI")])
1083
1084 (define_expand "cmpsi_1"
1085 [(set (reg:CC 17)
1086 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1087 (match_operand:SI 1 "general_operand" "ri,mr")))]
1088 ""
1089 "")
1090
1091 (define_insn "*cmpsi_1_insn"
1092 [(set (reg 17)
1093 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1094 (match_operand:SI 1 "general_operand" "ri,mr")))]
1095 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1096 && ix86_match_ccmode (insn, CCmode)"
1097 "cmp{l}\\t{%1, %0|%0, %1}"
1098 [(set_attr "type" "icmp")
1099 (set_attr "mode" "SI")])
1100
1101 (define_insn "*cmphi_ccno_1"
1102 [(set (reg 17)
1103 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1104 (match_operand:HI 1 "const0_operand" "n,n")))]
1105 "ix86_match_ccmode (insn, CCNOmode)"
1106 "@
1107 test{w}\\t{%0, %0|%0, %0}
1108 cmp{w}\\t{%1, %0|%0, %1}"
1109 [(set_attr "type" "test,icmp")
1110 (set_attr "length_immediate" "0,1")
1111 (set_attr "mode" "HI")])
1112
1113 (define_insn "*cmphi_minus_1"
1114 [(set (reg 17)
1115 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1116 (match_operand:HI 1 "general_operand" "ri,mr"))
1117 (const_int 0)))]
1118 "ix86_match_ccmode (insn, CCGOCmode)"
1119 "cmp{w}\\t{%1, %0|%0, %1}"
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "HI")])
1122
1123 (define_insn "*cmphi_1"
1124 [(set (reg 17)
1125 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1126 (match_operand:HI 1 "general_operand" "ri,mr")))]
1127 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1128 && ix86_match_ccmode (insn, CCmode)"
1129 "cmp{w}\\t{%1, %0|%0, %1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "mode" "HI")])
1132
1133 (define_insn "*cmpqi_ccno_1"
1134 [(set (reg 17)
1135 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1136 (match_operand:QI 1 "const0_operand" "n,n")))]
1137 "ix86_match_ccmode (insn, CCNOmode)"
1138 "@
1139 test{b}\\t{%0, %0|%0, %0}
1140 cmp{b}\\t{$0, %0|%0, 0}"
1141 [(set_attr "type" "test,icmp")
1142 (set_attr "length_immediate" "0,1")
1143 (set_attr "mode" "QI")])
1144
1145 (define_insn "*cmpqi_1"
1146 [(set (reg 17)
1147 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1148 (match_operand:QI 1 "general_operand" "qi,mq")))]
1149 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
1150 && ix86_match_ccmode (insn, CCmode)"
1151 "cmp{b}\\t{%1, %0|%0, %1}"
1152 [(set_attr "type" "icmp")
1153 (set_attr "mode" "QI")])
1154
1155 (define_insn "*cmpqi_minus_1"
1156 [(set (reg 17)
1157 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1158 (match_operand:QI 1 "general_operand" "qi,mq"))
1159 (const_int 0)))]
1160 "ix86_match_ccmode (insn, CCGOCmode)"
1161 "cmp{b}\\t{%1, %0|%0, %1}"
1162 [(set_attr "type" "icmp")
1163 (set_attr "mode" "QI")])
1164
1165 (define_insn "*cmpqi_ext_1"
1166 [(set (reg 17)
1167 (compare
1168 (match_operand:QI 0 "general_operand" "qm")
1169 (subreg:QI
1170 (zero_extract:SI
1171 (match_operand 1 "ext_register_operand" "q")
1172 (const_int 8)
1173 (const_int 8)) 0)))]
1174 "ix86_match_ccmode (insn, CCmode)"
1175 "cmp{b}\\t{%h1, %0|%0, %h1}"
1176 [(set_attr "type" "icmp")
1177 (set_attr "mode" "QI")])
1178
1179 (define_insn "*cmpqi_ext_2"
1180 [(set (reg 17)
1181 (compare
1182 (subreg:QI
1183 (zero_extract:SI
1184 (match_operand 0 "ext_register_operand" "q")
1185 (const_int 8)
1186 (const_int 8)) 0)
1187 (match_operand:QI 1 "const0_operand" "n")))]
1188 "ix86_match_ccmode (insn, CCNOmode)"
1189 "test{b}\\t%h0, %h0"
1190 [(set_attr "type" "test")
1191 (set_attr "length_immediate" "0")
1192 (set_attr "mode" "QI")])
1193
1194 (define_expand "cmpqi_ext_3"
1195 [(set (reg:CC 17)
1196 (compare:CC
1197 (subreg:QI
1198 (zero_extract:SI
1199 (match_operand 0 "ext_register_operand" "q")
1200 (const_int 8)
1201 (const_int 8)) 0)
1202 (match_operand:QI 1 "general_operand" "qmn")))]
1203 ""
1204 "")
1205
1206 (define_insn "cmpqi_ext_3_insn"
1207 [(set (reg 17)
1208 (compare
1209 (subreg:QI
1210 (zero_extract:SI
1211 (match_operand 0 "ext_register_operand" "q")
1212 (const_int 8)
1213 (const_int 8)) 0)
1214 (match_operand:QI 1 "general_operand" "qmn")))]
1215 "ix86_match_ccmode (insn, CCmode)"
1216 "cmp{b}\\t{%1, %h0|%h0, %1}"
1217 [(set_attr "type" "icmp")
1218 (set_attr "mode" "QI")])
1219
1220 (define_insn "*cmpqi_ext_4"
1221 [(set (reg 17)
1222 (compare
1223 (subreg:QI
1224 (zero_extract:SI
1225 (match_operand 0 "ext_register_operand" "q")
1226 (const_int 8)
1227 (const_int 8)) 0)
1228 (subreg:QI
1229 (zero_extract:SI
1230 (match_operand 1 "ext_register_operand" "q")
1231 (const_int 8)
1232 (const_int 8)) 0)))]
1233 "ix86_match_ccmode (insn, CCmode)"
1234 "cmp{b}\\t{%h1, %h0|%h0, %h1}"
1235 [(set_attr "type" "icmp")
1236 (set_attr "mode" "QI")])
1237
1238 ;; These implement float point compares.
1239 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1240 ;; which would allow mix and match FP modes on the compares. Which is what
1241 ;; the old patterns did, but with many more of them.
1242
1243 (define_expand "cmpxf"
1244 [(set (reg:CC 17)
1245 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
1246 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
1247 "TARGET_80387"
1248 "
1249 {
1250 ix86_compare_op0 = operands[0];
1251 ix86_compare_op1 = operands[1];
1252 DONE;
1253 }")
1254
1255 (define_expand "cmptf"
1256 [(set (reg:CC 17)
1257 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
1258 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
1259 "TARGET_80387"
1260 "
1261 {
1262 ix86_compare_op0 = operands[0];
1263 ix86_compare_op1 = operands[1];
1264 DONE;
1265 }")
1266
1267 (define_expand "cmpdf"
1268 [(set (reg:CC 17)
1269 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
1270 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
1271 "TARGET_80387 || TARGET_SSE2"
1272 "
1273 {
1274 ix86_compare_op0 = operands[0];
1275 ix86_compare_op1 = operands[1];
1276 DONE;
1277 }")
1278
1279 (define_expand "cmpsf"
1280 [(set (reg:CC 17)
1281 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
1282 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
1283 "TARGET_80387 || TARGET_SSE"
1284 "
1285 {
1286 ix86_compare_op0 = operands[0];
1287 ix86_compare_op1 = operands[1];
1288 DONE;
1289 }")
1290
1291 ;; FP compares, step 1:
1292 ;; Set the FP condition codes.
1293 ;;
1294 ;; CCFPmode compare with exceptions
1295 ;; CCFPUmode compare with no exceptions
1296
1297 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
1298 ;; and that fp moves clobber the condition codes, and that there is
1299 ;; currently no way to describe this fact to reg-stack. So there are
1300 ;; no splitters yet for this.
1301
1302 ;; %%% YIKES! This scheme does not retain a strong connection between
1303 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
1304 ;; work! Only allow tos/mem with tos in op 0.
1305 ;;
1306 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
1307 ;; things aren't as bad as they sound...
1308
1309 (define_insn "*cmpfp_0"
1310 [(set (match_operand:HI 0 "register_operand" "=a")
1311 (unspec:HI
1312 [(compare:CCFP (match_operand 1 "register_operand" "f")
1313 (match_operand 2 "const0_operand" "X"))] 9))]
1314 "TARGET_80387
1315 && FLOAT_MODE_P (GET_MODE (operands[1]))
1316 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1317 "*
1318 {
1319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1320 return \"ftst\;fnstsw\\t%0\;fstp\\t%y0\";
1321 else
1322 return \"ftst\;fnstsw\\t%0\";
1323 }"
1324 [(set_attr "type" "multi")
1325 (set_attr "mode" "unknownfp")])
1326
1327 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1328 ;; used to manage the reg stack popping would not be preserved.
1329
1330 (define_insn "*cmpfp_2_sf"
1331 [(set (reg:CCFP 18)
1332 (compare:CCFP
1333 (match_operand:SF 0 "register_operand" "f")
1334 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
1335 "TARGET_80387"
1336 "* return output_fp_compare (insn, operands, 0, 0);"
1337 [(set_attr "type" "fcmp")
1338 (set_attr "mode" "SF")])
1339
1340 (define_insn "*cmpfp_2_sf_1"
1341 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (unspec:HI
1343 [(compare:CCFP
1344 (match_operand:SF 1 "register_operand" "f")
1345 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
1346 "TARGET_80387"
1347 "* return output_fp_compare (insn, operands, 2, 0);"
1348 [(set_attr "type" "fcmp")
1349 (set_attr "mode" "SF")])
1350
1351 (define_insn "*cmpfp_2_df"
1352 [(set (reg:CCFP 18)
1353 (compare:CCFP
1354 (match_operand:DF 0 "register_operand" "f")
1355 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
1356 "TARGET_80387"
1357 "* return output_fp_compare (insn, operands, 0, 0);"
1358 [(set_attr "type" "fcmp")
1359 (set_attr "mode" "DF")])
1360
1361 (define_insn "*cmpfp_2_df_1"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1363 (unspec:HI
1364 [(compare:CCFP
1365 (match_operand:DF 1 "register_operand" "f")
1366 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
1367 "TARGET_80387"
1368 "* return output_fp_compare (insn, operands, 2, 0);"
1369 [(set_attr "type" "multi")
1370 (set_attr "mode" "DF")])
1371
1372 (define_insn "*cmpfp_2_xf"
1373 [(set (reg:CCFP 18)
1374 (compare:CCFP
1375 (match_operand:XF 0 "register_operand" "f")
1376 (match_operand:XF 1 "register_operand" "f")))]
1377 "TARGET_80387"
1378 "* return output_fp_compare (insn, operands, 0, 0);"
1379 [(set_attr "type" "fcmp")
1380 (set_attr "mode" "XF")])
1381
1382 (define_insn "*cmpfp_2_tf"
1383 [(set (reg:CCFP 18)
1384 (compare:CCFP
1385 (match_operand:TF 0 "register_operand" "f")
1386 (match_operand:TF 1 "register_operand" "f")))]
1387 "TARGET_80387"
1388 "* return output_fp_compare (insn, operands, 0, 0);"
1389 [(set_attr "type" "fcmp")
1390 (set_attr "mode" "XF")])
1391
1392 (define_insn "*cmpfp_2_xf_1"
1393 [(set (match_operand:HI 0 "register_operand" "=a")
1394 (unspec:HI
1395 [(compare:CCFP
1396 (match_operand:XF 1 "register_operand" "f")
1397 (match_operand:XF 2 "register_operand" "f"))] 9))]
1398 "TARGET_80387"
1399 "* return output_fp_compare (insn, operands, 2, 0);"
1400 [(set_attr "type" "multi")
1401 (set_attr "mode" "XF")])
1402
1403 (define_insn "*cmpfp_2_tf_1"
1404 [(set (match_operand:HI 0 "register_operand" "=a")
1405 (unspec:HI
1406 [(compare:CCFP
1407 (match_operand:TF 1 "register_operand" "f")
1408 (match_operand:TF 2 "register_operand" "f"))] 9))]
1409 "TARGET_80387"
1410 "* return output_fp_compare (insn, operands, 2, 0);"
1411 [(set_attr "type" "multi")
1412 (set_attr "mode" "XF")])
1413
1414 (define_insn "*cmpfp_2u"
1415 [(set (reg:CCFPU 18)
1416 (compare:CCFPU
1417 (match_operand 0 "register_operand" "f")
1418 (match_operand 1 "register_operand" "f")))]
1419 "TARGET_80387
1420 && FLOAT_MODE_P (GET_MODE (operands[0]))
1421 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1422 "* return output_fp_compare (insn, operands, 0, 1);"
1423 [(set_attr "type" "fcmp")
1424 (set_attr "mode" "unknownfp")])
1425
1426 (define_insn "*cmpfp_2u_1"
1427 [(set (match_operand:HI 0 "register_operand" "=a")
1428 (unspec:HI
1429 [(compare:CCFPU
1430 (match_operand 1 "register_operand" "f")
1431 (match_operand 2 "register_operand" "f"))] 9))]
1432 "TARGET_80387
1433 && FLOAT_MODE_P (GET_MODE (operands[1]))
1434 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1435 "* return output_fp_compare (insn, operands, 2, 1);"
1436 [(set_attr "type" "multi")
1437 (set_attr "mode" "unknownfp")])
1438
1439 ;; Patterns to match the SImode-in-memory ficom instructions.
1440 ;;
1441 ;; %%% Play games with accepting gp registers, as otherwise we have to
1442 ;; force them to memory during rtl generation, which is no good. We
1443 ;; can get rid of this once we teach reload to do memory input reloads
1444 ;; via pushes.
1445
1446 (define_insn "*ficom_1"
1447 [(set (reg:CCFP 18)
1448 (compare:CCFP
1449 (match_operand 0 "register_operand" "f,f")
1450 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
1451 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
1452 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
1453 "#")
1454
1455 ;; Split the not-really-implemented gp register case into a
1456 ;; push-op-pop sequence.
1457 ;;
1458 ;; %%% This is most efficient, but am I gonna get in trouble
1459 ;; for separating cc0_setter and cc0_user?
1460
1461 (define_split
1462 [(set (reg:CCFP 18)
1463 (compare:CCFP
1464 (match_operand:SF 0 "register_operand" "")
1465 (float (match_operand:SI 1 "register_operand" ""))))]
1466 "0 && TARGET_80387 && reload_completed"
1467 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
1468 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
1469 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1470 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1471 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1472 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1473
1474 ;; FP compares, step 2
1475 ;; Move the fpsw to ax.
1476
1477 (define_insn "x86_fnstsw_1"
1478 [(set (match_operand:HI 0 "register_operand" "=a")
1479 (unspec:HI [(reg 18)] 9))]
1480 "TARGET_80387"
1481 "fnstsw\\t%0"
1482 [(set_attr "length" "2")
1483 (set_attr "mode" "SI")
1484 (set_attr "i387" "1")
1485 (set_attr "ppro_uops" "few")])
1486
1487 ;; FP compares, step 3
1488 ;; Get ax into flags, general case.
1489
1490 (define_insn "x86_sahf_1"
1491 [(set (reg:CC 17)
1492 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
1493 ""
1494 "sahf"
1495 [(set_attr "length" "1")
1496 (set_attr "athlon_decode" "vector")
1497 (set_attr "mode" "SI")
1498 (set_attr "ppro_uops" "one")])
1499
1500 ;; Pentium Pro can do steps 1 through 3 in one go.
1501
1502 (define_insn "*cmpfp_i"
1503 [(set (reg:CCFP 17)
1504 (compare:CCFP (match_operand 0 "register_operand" "f")
1505 (match_operand 1 "register_operand" "f")))]
1506 "TARGET_80387 && TARGET_CMOVE
1507 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1508 && FLOAT_MODE_P (GET_MODE (operands[0]))
1509 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1510 "* return output_fp_compare (insn, operands, 1, 0);"
1511 [(set_attr "type" "fcmp")
1512 (set_attr "mode" "unknownfp")
1513 (set_attr "athlon_decode" "vector")])
1514
1515 (define_insn "*cmpfp_i_sse"
1516 [(set (reg:CCFP 17)
1517 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1518 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1519 "TARGET_80387
1520 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1522 "* return output_fp_compare (insn, operands, 1, 0);"
1523 [(set_attr "type" "fcmp,sse")
1524 (set_attr "mode" "unknownfp")
1525 (set_attr "athlon_decode" "vector")])
1526
1527 (define_insn "*cmpfp_i_sse_only"
1528 [(set (reg:CCFP 17)
1529 (compare:CCFP (match_operand 0 "register_operand" "x")
1530 (match_operand 1 "nonimmediate_operand" "xm")))]
1531 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1532 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1533 "* return output_fp_compare (insn, operands, 1, 0);"
1534 [(set_attr "type" "sse")
1535 (set_attr "mode" "unknownfp")
1536 (set_attr "athlon_decode" "vector")])
1537
1538 (define_insn "*cmpfp_iu"
1539 [(set (reg:CCFPU 17)
1540 (compare:CCFPU (match_operand 0 "register_operand" "f")
1541 (match_operand 1 "register_operand" "f")))]
1542 "TARGET_80387 && TARGET_CMOVE
1543 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && FLOAT_MODE_P (GET_MODE (operands[0]))
1545 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1546 "* return output_fp_compare (insn, operands, 1, 1);"
1547 [(set_attr "type" "fcmp")
1548 (set_attr "mode" "unknownfp")
1549 (set_attr "athlon_decode" "vector")])
1550
1551 (define_insn "*cmpfp_iu_sse"
1552 [(set (reg:CCFPU 17)
1553 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1554 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1555 "TARGET_80387
1556 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1557 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1558 "* return output_fp_compare (insn, operands, 1, 1);"
1559 [(set_attr "type" "fcmp,sse")
1560 (set_attr "mode" "unknownfp")
1561 (set_attr "athlon_decode" "vector")])
1562
1563 (define_insn "*cmpfp_iu_sse_only"
1564 [(set (reg:CCFPU 17)
1565 (compare:CCFPU (match_operand 0 "register_operand" "x")
1566 (match_operand 1 "nonimmediate_operand" "xm")))]
1567 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1568 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1569 "* return output_fp_compare (insn, operands, 1, 1);"
1570 [(set_attr "type" "sse")
1571 (set_attr "mode" "unknownfp")
1572 (set_attr "athlon_decode" "vector")])
1573 \f
1574 ;; Move instructions.
1575
1576 ;; General case of fullword move.
1577
1578 (define_expand "movsi"
1579 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1580 (match_operand:SI 1 "general_operand" ""))]
1581 ""
1582 "ix86_expand_move (SImode, operands); DONE;")
1583
1584 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1585 ;; general_operand.
1586 ;;
1587 ;; %%% We don't use a post-inc memory reference because x86 is not a
1588 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1589 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1590 ;; targets without our curiosities, and it is just as easy to represent
1591 ;; this differently.
1592
1593 (define_insn "*pushsi2"
1594 [(set (match_operand:SI 0 "push_operand" "=<")
1595 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1596 ""
1597 "push{l}\\t%1"
1598 [(set_attr "type" "push")
1599 (set_attr "mode" "SI")])
1600
1601 (define_insn "*pushsi2_prologue"
1602 [(set (match_operand:SI 0 "push_operand" "=<")
1603 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1604 (set (reg:SI 6) (reg:SI 6))]
1605 ""
1606 "push{l}\\t%1"
1607 [(set_attr "type" "push")
1608 (set_attr "mode" "SI")])
1609
1610 (define_insn "*popsi1_epilogue"
1611 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1612 (mem:SI (reg:SI 7)))
1613 (set (reg:SI 7)
1614 (plus:SI (reg:SI 7) (const_int 4)))
1615 (set (reg:SI 6) (reg:SI 6))]
1616 ""
1617 "pop{l}\\t%0"
1618 [(set_attr "type" "pop")
1619 (set_attr "mode" "SI")])
1620
1621 (define_insn "popsi1"
1622 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1623 (mem:SI (reg:SI 7)))
1624 (set (reg:SI 7)
1625 (plus:SI (reg:SI 7) (const_int 4)))]
1626 ""
1627 "pop{l}\\t%0"
1628 [(set_attr "type" "pop")
1629 (set_attr "mode" "SI")])
1630
1631 (define_insn "*movsi_xor"
1632 [(set (match_operand:SI 0 "register_operand" "=r")
1633 (match_operand:SI 1 "const0_operand" "i"))
1634 (clobber (reg:CC 17))]
1635 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1636 "xor{l}\\t{%0, %0|%0, %0}"
1637 [(set_attr "type" "alu1")
1638 (set_attr "mode" "SI")
1639 (set_attr "length_immediate" "0")])
1640
1641 (define_insn "*movsi_or"
1642 [(set (match_operand:SI 0 "register_operand" "=r")
1643 (match_operand:SI 1 "immediate_operand" "i"))
1644 (clobber (reg:CC 17))]
1645 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1646 && INTVAL (operands[1]) == -1
1647 && (TARGET_PENTIUM || optimize_size)"
1648 "*
1649 {
1650 operands[1] = constm1_rtx;
1651 return \"or{l}\\t{%1, %0|%0, %1}\";
1652 }"
1653 [(set_attr "type" "alu1")
1654 (set_attr "mode" "SI")
1655 (set_attr "length_immediate" "1")])
1656
1657 (define_insn "*movsi_1"
1658 [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!r")
1659 (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,r,*y"))]
1660 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1661 "*
1662 {
1663 switch (get_attr_type (insn))
1664 {
1665 case TYPE_MMX:
1666 return \"movd\\t{%1, %0|%0, %1}\";
1667
1668 case TYPE_LEA:
1669 return \"lea{l}\\t{%1, %0|%0, %1}\";
1670
1671 default:
1672 if (flag_pic && SYMBOLIC_CONST (operands[1]))
1673 abort();
1674 return \"mov{l}\\t{%1, %0|%0, %1}\";
1675 }
1676 }"
1677 [(set (attr "type")
1678 (cond [(ior (match_operand:SI 0 "mmx_reg_operand" "")
1679 (match_operand:SI 1 "mmx_reg_operand" ""))
1680 (const_string "mmx")
1681 (and (ne (symbol_ref "flag_pic") (const_int 0))
1682 (match_operand:SI 1 "symbolic_operand" ""))
1683 (const_string "lea")
1684 ]
1685 (const_string "imov")))
1686 (set_attr "modrm" "0,*,0,*,*,*")
1687 (set_attr "mode" "SI")])
1688
1689 (define_insn "*swapsi"
1690 [(set (match_operand:SI 0 "register_operand" "+r")
1691 (match_operand:SI 1 "register_operand" "+r"))
1692 (set (match_dup 1)
1693 (match_dup 0))]
1694 ""
1695 "xchg{l}\\t%1, %0"
1696 [(set_attr "type" "imov")
1697 (set_attr "pent_pair" "np")
1698 (set_attr "athlon_decode" "vector")
1699 (set_attr "mode" "SI")
1700 (set_attr "modrm" "0")
1701 (set_attr "ppro_uops" "few")])
1702
1703 (define_expand "movhi"
1704 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1705 (match_operand:HI 1 "general_operand" ""))]
1706 ""
1707 "ix86_expand_move (HImode, operands); DONE;")
1708
1709 (define_insn "*pushhi2"
1710 [(set (match_operand:HI 0 "push_operand" "=<,<")
1711 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1712 ""
1713 "@
1714 push{w}\\t{|WORD PTR }%1
1715 push{w}\\t%1"
1716 [(set_attr "type" "push")
1717 (set_attr "mode" "HI")])
1718
1719 (define_insn "*pophi1"
1720 [(set (match_operand:HI 0 "nonimmediate_operand" "=r*m")
1721 (mem:HI (reg:SI 7)))
1722 (set (reg:SI 7)
1723 (plus:SI (reg:SI 7) (const_int 2)))]
1724 ""
1725 "pop{w}\\t%0"
1726 [(set_attr "type" "pop")
1727 (set_attr "mode" "HI")])
1728
1729 (define_insn "*movhi_1"
1730 [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
1731 (match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
1732 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1733 "*
1734 {
1735 switch (get_attr_type (insn))
1736 {
1737 case TYPE_IMOVX:
1738 /* movzwl is faster than movw on p2 due to partial word stalls,
1739 though not as fast as an aligned movl. */
1740 return \"movz{wl|x}\\t{%1, %k0|%k0, %1}\";
1741 default:
1742 if (get_attr_mode (insn) == MODE_SI)
1743 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1744 else
1745 return \"mov{w}\\t{%1, %0|%0, %1}\";
1746 }
1747 }"
1748 [(set (attr "type")
1749 (cond [(and (eq_attr "alternative" "0,1")
1750 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1751 (const_int 0))
1752 (eq (symbol_ref "TARGET_HIMODE_MATH")
1753 (const_int 0))))
1754 (const_string "imov")
1755 (and (eq_attr "alternative" "2,3,4")
1756 (match_operand:HI 1 "aligned_operand" ""))
1757 (const_string "imov")
1758 (and (ne (symbol_ref "TARGET_MOVX")
1759 (const_int 0))
1760 (eq_attr "alternative" "0,1,3,4"))
1761 (const_string "imovx")
1762 ]
1763 (const_string "imov")))
1764 (set (attr "mode")
1765 (cond [(eq_attr "type" "imovx")
1766 (const_string "SI")
1767 (and (eq_attr "alternative" "2,3,4")
1768 (match_operand:HI 1 "aligned_operand" ""))
1769 (const_string "SI")
1770 (and (eq_attr "alternative" "0,1")
1771 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1772 (const_int 0))
1773 (eq (symbol_ref "TARGET_HIMODE_MATH")
1774 (const_int 0))))
1775 (const_string "SI")
1776 ]
1777 (const_string "HI")))
1778 (set_attr "modrm" "0,*,*,0,*,*")])
1779
1780 (define_insn "*swaphi_1"
1781 [(set (match_operand:HI 0 "register_operand" "+r")
1782 (match_operand:HI 1 "register_operand" "+r"))
1783 (set (match_dup 1)
1784 (match_dup 0))]
1785 "TARGET_PARTIAL_REG_STALL"
1786 "xchg{w}\\t%1, %0"
1787 [(set_attr "type" "imov")
1788 (set_attr "pent_pair" "np")
1789 (set_attr "mode" "HI")
1790 (set_attr "modrm" "0")
1791 (set_attr "ppro_uops" "few")])
1792
1793 (define_insn "*swaphi_2"
1794 [(set (match_operand:HI 0 "register_operand" "+r")
1795 (match_operand:HI 1 "register_operand" "+r"))
1796 (set (match_dup 1)
1797 (match_dup 0))]
1798 "! TARGET_PARTIAL_REG_STALL"
1799 "xchg{l}\\t%k1, %k0"
1800 [(set_attr "type" "imov")
1801 (set_attr "pent_pair" "np")
1802 (set_attr "mode" "SI")
1803 (set_attr "modrm" "0")
1804 (set_attr "ppro_uops" "few")])
1805
1806 (define_expand "movstricthi"
1807 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1808 (match_operand:HI 1 "general_operand" ""))]
1809 "! TARGET_PARTIAL_REG_STALL"
1810 "
1811 {
1812 /* Don't generate memory->memory moves, go through a register */
1813 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1814 operands[1] = force_reg (HImode, operands[1]);
1815 }")
1816
1817 (define_insn "*movstricthi_1"
1818 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1819 (match_operand:HI 1 "general_operand" "rn,m"))]
1820 "! TARGET_PARTIAL_REG_STALL
1821 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1822 "mov{w}\\t{%1, %0|%0, %1}"
1823 [(set_attr "type" "imov")
1824 (set_attr "mode" "HI")])
1825
1826 (define_insn "*movstricthi_xor"
1827 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1828 (match_operand:HI 1 "const0_operand" "i"))
1829 (clobber (reg:CC 17))]
1830 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1831 "xor{w}\\t{%0, %0|%0, %0}"
1832 [(set_attr "type" "alu1")
1833 (set_attr "mode" "HI")
1834 (set_attr "length_immediate" "0")])
1835
1836 (define_expand "movqi"
1837 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1838 (match_operand:QI 1 "general_operand" ""))]
1839 ""
1840 "ix86_expand_move (QImode, operands); DONE;")
1841
1842 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1843 ;; "push a byte". But actually we use pushw, which has the effect
1844 ;; of rounding the amount pushed up to a halfword.
1845
1846 (define_insn "*pushqi2"
1847 [(set (match_operand:QI 0 "push_operand" "=<,<")
1848 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1849 ""
1850 "@
1851 push{w}\\t{|word ptr }%1
1852 push{w}\\t%w1"
1853 [(set_attr "type" "push")
1854 (set_attr "mode" "HI")])
1855
1856 (define_insn "*popqi1"
1857 [(set (match_operand:QI 0 "nonimmediate_operand" "=r*m")
1858 (mem:QI (reg:SI 7)))
1859 (set (reg:SI 7)
1860 (plus:SI (reg:SI 7) (const_int 2)))]
1861 ""
1862 "pop{w}\\t%0"
1863 [(set_attr "type" "pop")
1864 (set_attr "mode" "HI")])
1865
1866 ;; Situation is quite tricky about when to choose full sized (SImode) move
1867 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1868 ;; partial register dependency machines (such as AMD Athlon), where QImode
1869 ;; moves issue extra dependency and for partial register stalls machines
1870 ;; that don't use QImode patterns (and QImode move cause stall on the next
1871 ;; instruction).
1872 ;;
1873 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1874 ;; register stall machines with, where we use QImode instructions, since
1875 ;; partial register stall can be caused there. Then we use movzx.
1876 (define_insn "*movqi_1"
1877 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1878 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1879 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1880 "*
1881 {
1882 switch (get_attr_type (insn))
1883 {
1884 case TYPE_IMOVX:
1885 if (!QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1886 abort ();
1887 return \"movz{bl|x}\\t{%1, %k0|%k0, %1}\";
1888 default:
1889 if (get_attr_mode (insn) == MODE_SI)
1890 return \"mov{l}\\t{%k1, %k0|%k0, %k1}\";
1891 else
1892 return \"mov{b}\\t{%1, %0|%0, %1}\";
1893 }
1894 }"
1895 [(set (attr "type")
1896 (cond [(and (eq_attr "alternative" "3")
1897 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1898 (const_int 0))
1899 (eq (symbol_ref "TARGET_QIMODE_MATH")
1900 (const_int 0))))
1901 (const_string "imov")
1902 (eq_attr "alternative" "3,5")
1903 (const_string "imovx")
1904 (and (ne (symbol_ref "TARGET_MOVX")
1905 (const_int 0))
1906 (eq_attr "alternative" "2"))
1907 (const_string "imovx")
1908 ]
1909 (const_string "imov")))
1910 (set (attr "mode")
1911 (cond [(eq_attr "alternative" "3,4,5")
1912 (const_string "SI")
1913 (eq_attr "alternative" "6")
1914 (const_string "QI")
1915 (eq_attr "type" "imovx")
1916 (const_string "SI")
1917 (and (eq_attr "type" "imov")
1918 (and (eq_attr "alternative" "0,1,2")
1919 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1920 (const_int 0))))
1921 (const_string "SI")
1922 ;; Avoid partial register stalls when not using QImode arithmetic
1923 (and (eq_attr "type" "imov")
1924 (and (eq_attr "alternative" "0,1,2")
1925 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1926 (const_int 0))
1927 (eq (symbol_ref "TARGET_QIMODE_MATH")
1928 (const_int 0)))))
1929 (const_string "SI")
1930 ]
1931 (const_string "QI")))])
1932
1933 (define_expand "reload_outqi"
1934 [(parallel [(match_operand:QI 0 "" "=m")
1935 (match_operand:QI 1 "register_operand" "r")
1936 (match_operand:QI 2 "register_operand" "=&q")])]
1937 ""
1938 "
1939 {
1940 rtx op0, op1, op2;
1941 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1942
1943 if (reg_overlap_mentioned_p (op2, op0))
1944 abort ();
1945 if (! q_regs_operand (op1, QImode))
1946 {
1947 emit_insn (gen_movqi (op2, op1));
1948 op1 = op2;
1949 }
1950 emit_insn (gen_movqi (op0, op1));
1951 DONE;
1952 }")
1953
1954 (define_insn "*swapqi"
1955 [(set (match_operand:QI 0 "register_operand" "+r")
1956 (match_operand:QI 1 "register_operand" "+r"))
1957 (set (match_dup 1)
1958 (match_dup 0))]
1959 ""
1960 "xchg{b}\\t%1, %0"
1961 [(set_attr "type" "imov")
1962 (set_attr "pent_pair" "np")
1963 (set_attr "mode" "QI")
1964 (set_attr "modrm" "0")
1965 (set_attr "ppro_uops" "few")])
1966
1967 (define_expand "movstrictqi"
1968 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1969 (match_operand:QI 1 "general_operand" ""))]
1970 "! TARGET_PARTIAL_REG_STALL"
1971 "
1972 {
1973 /* Don't generate memory->memory moves, go through a register */
1974 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1975 operands[1] = force_reg (QImode, operands[1]);
1976 }")
1977
1978 (define_insn "*movstrictqi_1"
1979 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1980 (match_operand:QI 1 "general_operand" "*qn,m"))]
1981 "! TARGET_PARTIAL_REG_STALL
1982 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1983 "mov{b}\\t{%1, %0|%0, %1}"
1984 [(set_attr "type" "imov")
1985 (set_attr "mode" "QI")])
1986
1987 (define_insn "*movstrictqi_xor"
1988 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1989 (match_operand:QI 1 "const0_operand" "i"))
1990 (clobber (reg:CC 17))]
1991 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1992 "xor{b}\\t{%0, %0|%0, %0}"
1993 [(set_attr "type" "alu1")
1994 (set_attr "mode" "QI")
1995 (set_attr "length_immediate" "0")])
1996
1997 (define_insn "*movsi_extv_1"
1998 [(set (match_operand:SI 0 "register_operand" "=r")
1999 (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
2000 (const_int 8)
2001 (const_int 8)))]
2002 ""
2003 "movs{bl|x}\\t{%h1, %0|%0, %h1}"
2004 [(set_attr "type" "imovx")
2005 (set_attr "mode" "SI")])
2006
2007 (define_insn "*movhi_extv_1"
2008 [(set (match_operand:HI 0 "register_operand" "=r")
2009 (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
2010 (const_int 8)
2011 (const_int 8)))]
2012 ""
2013 "movs{bl|x}\\t{%h1, %k0|%k0, %h1}"
2014 [(set_attr "type" "imovx")
2015 (set_attr "mode" "SI")])
2016
2017 (define_insn "*movqi_extv_1"
2018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
2019 (sign_extract:QI (match_operand:SI 1 "register_operand" "q,q")
2020 (const_int 8)
2021 (const_int 8)))]
2022 ""
2023 "*
2024 {
2025 switch (get_attr_type (insn))
2026 {
2027 case TYPE_IMOVX:
2028 return \"movs{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2029 default:
2030 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2031 }
2032 }"
2033 [(set (attr "type")
2034 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2035 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2036 (ne (symbol_ref "TARGET_MOVX")
2037 (const_int 0))))
2038 (const_string "imovx")
2039 (const_string "imov")))
2040 (set (attr "mode")
2041 (if_then_else (eq_attr "type" "imovx")
2042 (const_string "SI")
2043 (const_string "QI")))])
2044
2045 (define_insn "*movsi_extzv_1"
2046 [(set (match_operand:SI 0 "register_operand" "=r")
2047 (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
2048 (const_int 8)
2049 (const_int 8)))]
2050 ""
2051 "movz{bl|x}\\t{%h1, %0|%0, %h1}"
2052 [(set_attr "type" "imovx")
2053 (set_attr "mode" "SI")])
2054
2055 (define_insn "*movqi_extzv_1"
2056 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
2057 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
2058 (const_int 8)
2059 (const_int 8)) 0))]
2060 ""
2061 "*
2062 {
2063 switch (get_attr_type (insn))
2064 {
2065 case TYPE_IMOVX:
2066 return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
2067 default:
2068 return \"mov{b}\\t{%h1, %0|%0, %h1}\";
2069 }
2070 }"
2071 [(set (attr "type")
2072 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2073 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2074 (ne (symbol_ref "TARGET_MOVX")
2075 (const_int 0))))
2076 (const_string "imovx")
2077 (const_string "imov")))
2078 (set (attr "mode")
2079 (if_then_else (eq_attr "type" "imovx")
2080 (const_string "SI")
2081 (const_string "QI")))])
2082
2083 (define_insn "*movsi_insv_1"
2084 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
2085 (const_int 8)
2086 (const_int 8))
2087 (match_operand:SI 1 "nonimmediate_operand" "qm"))]
2088 ""
2089 "mov{b}\\t{%b1, %h0|%h0, %b1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "mode" "QI")])
2092
2093 (define_insn "*movqi_insv_2"
2094 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
2095 (const_int 8)
2096 (const_int 8))
2097 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
2098 (const_int 8))
2099 (const_int 255)))]
2100 ""
2101 "mov{b}\\t{%h1, %h0|%h0, %h1}"
2102 [(set_attr "type" "imov")
2103 (set_attr "mode" "QI")])
2104
2105 (define_expand "movdi"
2106 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2107 (match_operand:DI 1 "general_operand" ""))]
2108 ""
2109 "ix86_expand_move (DImode, operands); DONE;")
2110
2111 (define_insn "*pushdi"
2112 [(set (match_operand:DI 0 "push_operand" "=<")
2113 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2114 ""
2115 "#")
2116
2117 (define_insn "*movdi_2"
2118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y")
2119 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m"))]
2120 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
2121 "@
2122 #
2123 #
2124 movq\\t{%1, %0|%0, %1}
2125 movq\\t{%1, %0|%0, %1}"
2126 [(set_attr "type" "*,*,mmx,mmx")])
2127
2128 (define_split
2129 [(set (match_operand:DI 0 "push_operand" "")
2130 (match_operand:DI 1 "general_operand" ""))]
2131 "reload_completed && ! MMX_REG_P (operands[1])"
2132 [(const_int 0)]
2133 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2134
2135 ;; %%% This multiword shite has got to go.
2136 (define_split
2137 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2138 (match_operand:DI 1 "general_operand" ""))]
2139 "reload_completed && ! MMX_REG_P (operands[0]) && ! MMX_REG_P (operands[1])"
2140 [(set (match_dup 2) (match_dup 5))
2141 (set (match_dup 3) (match_dup 6))]
2142 "if (ix86_split_long_move (operands)) DONE;")
2143
2144 (define_expand "movsf"
2145 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2146 (match_operand:SF 1 "general_operand" ""))]
2147 ""
2148 "ix86_expand_move (SFmode, operands); DONE;")
2149
2150 (define_insn "*pushsf"
2151 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2152 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2153 ""
2154 "*
2155 {
2156 switch (which_alternative)
2157 {
2158 case 0:
2159 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2160 operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
2161 operands[2] = stack_pointer_rtx;
2162 operands[3] = GEN_INT (4);
2163 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2164 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2165 else
2166 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2167
2168 case 1:
2169 return \"push{l}\\t%1\";
2170 case 2:
2171 return \"#\";
2172
2173 default:
2174 abort ();
2175 }
2176 }"
2177 [(set_attr "type" "multi,push,multi")
2178 (set_attr "mode" "SF,SI,SF")])
2179
2180 (define_split
2181 [(set (match_operand:SF 0 "push_operand" "")
2182 (match_operand:SF 1 "memory_operand" ""))]
2183 "reload_completed
2184 && GET_CODE (operands[1]) == MEM
2185 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2186 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2187 [(set (match_dup 0)
2188 (match_dup 1))]
2189 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2190
2191
2192 ;; %%% Kill this when call knows how to work this out.
2193 (define_split
2194 [(set (match_operand:SF 0 "push_operand" "")
2195 (match_operand:SF 1 "register_operand" ""))]
2196 "ANY_FP_REGNO_P (REGNO (operands[1]))"
2197 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2198 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2199
2200 (define_insn "*movsf_1"
2201 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,m")
2202 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,xm#rf,x#rf"))]
2203 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2204 && (reload_in_progress || reload_completed
2205 || GET_CODE (operands[1]) != CONST_DOUBLE
2206 || memory_operand (operands[0], SFmode))"
2207 "*
2208 {
2209 switch (which_alternative)
2210 {
2211 case 0:
2212 if (REG_P (operands[1])
2213 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2214 return \"fstp\\t%y0\";
2215 else if (STACK_TOP_P (operands[0]))
2216 return \"fld%z1\\t%y1\";
2217 else
2218 return \"fst\\t%y0\";
2219
2220 case 1:
2221 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2222 return \"fstp%z0\\t%y0\";
2223 else
2224 return \"fst%z0\\t%y0\";
2225
2226 case 2:
2227 switch (standard_80387_constant_p (operands[1]))
2228 {
2229 case 1:
2230 return \"fldz\";
2231 case 2:
2232 return \"fld1\";
2233 }
2234 abort();
2235
2236 case 3:
2237 case 4:
2238 return \"mov{l}\\t{%1, %0|%0, %1}\";
2239 case 5:
2240 case 6:
2241 return \"movss\\t{%1, %0|%0, %1}\";
2242
2243 default:
2244 abort();
2245 }
2246 }"
2247 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse")
2248 (set_attr "mode" "SF,SF,SF,SI,SI,SF,SF")])
2249
2250 (define_split
2251 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2252 (match_operand:SF 1 "memory_operand" ""))]
2253 "reload_completed
2254 && GET_CODE (operands[1]) == MEM
2255 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2256 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2257 && !(SSE_REG_P (operands[0])
2258 || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
2259 && (!(FP_REG_P (operands[0]) ||
2260 (GET_CODE (operands[0]) == SUBREG
2261 && FP_REG_P (SUBREG_REG (operands[0]))))
2262 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2263 [(set (match_dup 0)
2264 (match_dup 1))]
2265 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2266
2267 (define_insn "*swapsf"
2268 [(set (match_operand:SF 0 "register_operand" "+f")
2269 (match_operand:SF 1 "register_operand" "+f"))
2270 (set (match_dup 1)
2271 (match_dup 0))]
2272 "reload_completed || !TARGET_SSE2"
2273 "*
2274 {
2275 if (STACK_TOP_P (operands[0]))
2276 return \"fxch\\t%1\";
2277 else
2278 return \"fxch\\t%0\";
2279 }"
2280 [(set_attr "type" "fxch")
2281 (set_attr "mode" "SF")])
2282
2283 (define_expand "movdf"
2284 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2285 (match_operand:DF 1 "general_operand" ""))]
2286 ""
2287 "ix86_expand_move (DFmode, operands); DONE;")
2288
2289 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2290 ;; Size of pushdf using integer insturctions is 2+2*memory operand size
2291 ;; On the average, pushdf using integers can be still shorter. Allow this
2292 ;; pattern for optimize_size too.
2293
2294 (define_insn "*pushdf_nointeger"
2295 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2296 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2297 "!TARGET_INTEGER_DFMODE_MOVES"
2298 "*
2299 {
2300 switch (which_alternative)
2301 {
2302 case 0:
2303 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2304 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2305 operands[2] = stack_pointer_rtx;
2306 operands[3] = GEN_INT (8);
2307 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2308 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2309 else
2310 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2311
2312 case 1:
2313 case 2:
2314 case 3:
2315 return \"#\";
2316
2317 default:
2318 abort ();
2319 }
2320 }"
2321 [(set_attr "type" "multi")
2322 (set_attr "mode" "DF,SI,SI,DF")])
2323
2324 (define_insn "*pushdf_integer"
2325 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2326 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2327 "TARGET_INTEGER_DFMODE_MOVES"
2328 "*
2329 {
2330 switch (which_alternative)
2331 {
2332 case 0:
2333 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2334 operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
2335 operands[2] = stack_pointer_rtx;
2336 operands[3] = GEN_INT (8);
2337 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2338 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2339 else
2340 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2341
2342 case 1:
2343 case 2:
2344 return \"#\";
2345
2346 default:
2347 abort ();
2348 }
2349 }"
2350 [(set_attr "type" "multi")
2351 (set_attr "mode" "DF,SI,DF")])
2352
2353 ;; %%% Kill this when call knows how to work this out.
2354 (define_split
2355 [(set (match_operand:DF 0 "push_operand" "")
2356 (match_operand:DF 1 "register_operand" ""))]
2357 "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
2358 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2359 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2360 "")
2361
2362 (define_split
2363 [(set (match_operand:DF 0 "push_operand" "")
2364 (match_operand:DF 1 "general_operand" ""))]
2365 "reload_completed"
2366 [(const_int 0)]
2367 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2368
2369 ;; Moving is usually shorter when only FP registers are used. This separate
2370 ;; movdf pattern avoids the use of integer registers for FP operations
2371 ;; when optimizing for size.
2372
2373 (define_insn "*movdf_nointeger"
2374 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,m")
2375 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,Ym#f,Y#f"))]
2376 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2377 && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
2378 && (reload_in_progress || reload_completed
2379 || GET_CODE (operands[1]) != CONST_DOUBLE
2380 || memory_operand (operands[0], DFmode))"
2381 "*
2382 {
2383 switch (which_alternative)
2384 {
2385 case 0:
2386 if (REG_P (operands[1])
2387 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2388 return \"fstp\\t%y0\";
2389 else if (STACK_TOP_P (operands[0]))
2390 return \"fld%z1\\t%y1\";
2391 else
2392 return \"fst\\t%y0\";
2393
2394 case 1:
2395 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2396 return \"fstp%z0\\t%y0\";
2397 else
2398 return \"fst%z0\\t%y0\";
2399
2400 case 2:
2401 switch (standard_80387_constant_p (operands[1]))
2402 {
2403 case 1:
2404 return \"fldz\";
2405 case 2:
2406 return \"fld1\";
2407 }
2408 abort();
2409
2410 case 3:
2411 case 4:
2412 return \"#\";
2413 case 5:
2414 case 6:
2415 return \"movsd\\t{%1, %0|%0, %1}\";
2416
2417 default:
2418 abort();
2419 }
2420 }"
2421 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
2422 (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
2423
2424 (define_insn "*movdf_integer"
2425 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,m")
2426 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,Ym#rf,Y#rf"))]
2427 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2428 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2429 && (reload_in_progress || reload_completed
2430 || GET_CODE (operands[1]) != CONST_DOUBLE
2431 || memory_operand (operands[0], DFmode))"
2432 "*
2433 {
2434 switch (which_alternative)
2435 {
2436 case 0:
2437 if (REG_P (operands[1])
2438 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2439 return \"fstp\\t%y0\";
2440 else if (STACK_TOP_P (operands[0]))
2441 return \"fld%z1\\t%y1\";
2442 else
2443 return \"fst\\t%y0\";
2444
2445 case 1:
2446 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2447 return \"fstp%z0\\t%y0\";
2448 else
2449 return \"fst%z0\\t%y0\";
2450
2451 case 2:
2452 switch (standard_80387_constant_p (operands[1]))
2453 {
2454 case 1:
2455 return \"fldz\";
2456 case 2:
2457 return \"fld1\";
2458 }
2459 abort();
2460
2461 case 3:
2462 case 4:
2463 return \"#\";
2464
2465 case 5:
2466 case 6:
2467 return \"movsd\\t{%1, %0|%0, %1}\";
2468
2469 default:
2470 abort();
2471 }
2472 }"
2473 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
2474 (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
2475
2476 (define_split
2477 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2478 (match_operand:DF 1 "general_operand" ""))]
2479 "reload_completed
2480 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2481 && ! (ANY_FP_REG_P (operands[0]) ||
2482 (GET_CODE (operands[0]) == SUBREG
2483 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2484 && ! (ANY_FP_REG_P (operands[1]) ||
2485 (GET_CODE (operands[1]) == SUBREG
2486 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2487 [(set (match_dup 2) (match_dup 5))
2488 (set (match_dup 3) (match_dup 6))]
2489 "if (ix86_split_long_move (operands)) DONE;")
2490
2491 (define_split
2492 [(set (match_operand:DF 0 "register_operand" "")
2493 (match_operand:DF 1 "memory_operand" ""))]
2494 "reload_completed
2495 && GET_CODE (operands[1]) == MEM
2496 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2497 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2498 && !(SSE_REG_P (operands[0])
2499 || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
2500 && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2501 [(set (match_dup 0)
2502 (match_dup 1))]
2503 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2504
2505 (define_insn "*swapdf"
2506 [(set (match_operand:DF 0 "register_operand" "+f")
2507 (match_operand:DF 1 "register_operand" "+f"))
2508 (set (match_dup 1)
2509 (match_dup 0))]
2510 "reload_completed || !TARGET_SSE2"
2511 "*
2512 {
2513 if (STACK_TOP_P (operands[0]))
2514 return \"fxch\\t%1\";
2515 else
2516 return \"fxch\\t%0\";
2517 }"
2518 [(set_attr "type" "fxch")
2519 (set_attr "mode" "DF")])
2520
2521 (define_expand "movxf"
2522 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2523 (match_operand:XF 1 "general_operand" ""))]
2524 ""
2525 "ix86_expand_move (XFmode, operands); DONE;")
2526
2527 (define_expand "movtf"
2528 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2529 (match_operand:TF 1 "general_operand" ""))]
2530 ""
2531 "ix86_expand_move (TFmode, operands); DONE;")
2532
2533 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2534 ;; Size of pushdf using integer insturctions is 3+3*memory operand size
2535 ;; Pushing using integer instructions is longer except for constants
2536 ;; and direct memory references.
2537 ;; (assuming that any given constant is pushed only once, but this ought to be
2538 ;; handled elsewhere).
2539
2540 (define_insn "*pushxf_nointeger"
2541 [(set (match_operand:XF 0 "push_operand" "=<,<,<")
2542 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2543 "optimize_size"
2544 "*
2545 {
2546 switch (which_alternative)
2547 {
2548 case 0:
2549 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2550 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2551 operands[2] = stack_pointer_rtx;
2552 operands[3] = GEN_INT (12);
2553 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2554 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2555 else
2556 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2557
2558 case 1:
2559 case 2:
2560 return \"#\";
2561
2562 default:
2563 abort ();
2564 }
2565 }"
2566 [(set_attr "type" "multi")
2567 (set_attr "mode" "XF,SI,SI")])
2568
2569 (define_insn "*pushtf_nointeger"
2570 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2571 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2572 "optimize_size"
2573 "*
2574 {
2575 switch (which_alternative)
2576 {
2577 case 0:
2578 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2579 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2580 operands[2] = stack_pointer_rtx;
2581 operands[3] = GEN_INT (16);
2582 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2583 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2584 else
2585 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2586
2587 case 1:
2588 case 2:
2589 return \"#\";
2590
2591 default:
2592 abort ();
2593 }
2594 }"
2595 [(set_attr "type" "multi")
2596 (set_attr "mode" "XF,SI,SI")])
2597
2598 (define_insn "*pushxf_integer"
2599 [(set (match_operand:XF 0 "push_operand" "=<,<")
2600 (match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2601 "!optimize_size"
2602 "*
2603 {
2604 switch (which_alternative)
2605 {
2606 case 0:
2607 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2608 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2609 operands[2] = stack_pointer_rtx;
2610 operands[3] = GEN_INT (12);
2611 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2612 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2613 else
2614 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2615
2616 case 1:
2617 return \"#\";
2618
2619 default:
2620 abort ();
2621 }
2622 }"
2623 [(set_attr "type" "multi")
2624 (set_attr "mode" "XF,SI")])
2625
2626 (define_insn "*pushtf_integer"
2627 [(set (match_operand:TF 0 "push_operand" "=<,<")
2628 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2629 "!optimize_size"
2630 "*
2631 {
2632 switch (which_alternative)
2633 {
2634 case 0:
2635 /* %%% We loose REG_DEAD notes for controling pops if we split late. */
2636 operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
2637 operands[2] = stack_pointer_rtx;
2638 operands[3] = GEN_INT (16);
2639 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2640 return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
2641 else
2642 return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
2643
2644 case 1:
2645 return \"#\";
2646
2647 default:
2648 abort ();
2649 }
2650 }"
2651 [(set_attr "type" "multi")
2652 (set_attr "mode" "XF,SI")])
2653
2654 (define_split
2655 [(set (match_operand 0 "push_operand" "")
2656 (match_operand 1 "general_operand" ""))]
2657 "reload_completed
2658 && (GET_MODE (operands[0]) == XFmode
2659 || GET_MODE (operands[0]) == TFmode
2660 || GET_MODE (operands[0]) == DFmode)
2661 && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
2662 [(const_int 0)]
2663 "if (!ix86_split_long_move (operands)) abort (); DONE;")
2664
2665 (define_split
2666 [(set (match_operand:XF 0 "push_operand" "")
2667 (match_operand:XF 1 "register_operand" ""))]
2668 "ANY_FP_REGNO_P (REGNO (operands[1]))"
2669 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2670 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2671
2672 (define_split
2673 [(set (match_operand:TF 0 "push_operand" "")
2674 (match_operand:TF 1 "register_operand" ""))]
2675 "ANY_FP_REGNO_P (REGNO (operands[1]))"
2676 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2677 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2678
2679 ;; Do not use integer registers when optimizing for size
2680 (define_insn "*movxf_nointeger"
2681 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2682 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2683 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2684 && optimize_size
2685 && (reload_in_progress || reload_completed
2686 || GET_CODE (operands[1]) != CONST_DOUBLE
2687 || memory_operand (operands[0], XFmode))"
2688 "*
2689 {
2690 switch (which_alternative)
2691 {
2692 case 0:
2693 if (REG_P (operands[1])
2694 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2695 return \"fstp\\t%y0\";
2696 else if (STACK_TOP_P (operands[0]))
2697 return \"fld%z1\\t%y1\";
2698 else
2699 return \"fst\\t%y0\";
2700
2701 case 1:
2702 /* There is no non-popping store to memory for XFmode. So if
2703 we need one, follow the store with a load. */
2704 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2705 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2706 else
2707 return \"fstp%z0\\t%y0\";
2708
2709 case 2:
2710 switch (standard_80387_constant_p (operands[1]))
2711 {
2712 case 1:
2713 return \"fldz\";
2714 case 2:
2715 return \"fld1\";
2716 }
2717 break;
2718
2719 case 3: case 4:
2720 return \"#\";
2721 }
2722 abort();
2723 }"
2724 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2725 (set_attr "mode" "XF,XF,XF,SI,SI")])
2726
2727 (define_insn "*movtf_nointeger"
2728 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2729 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2730 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2731 && optimize_size
2732 && (reload_in_progress || reload_completed
2733 || GET_CODE (operands[1]) != CONST_DOUBLE
2734 || memory_operand (operands[0], TFmode))"
2735 "*
2736 {
2737 switch (which_alternative)
2738 {
2739 case 0:
2740 if (REG_P (operands[1])
2741 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2742 return \"fstp\\t%y0\";
2743 else if (STACK_TOP_P (operands[0]))
2744 return \"fld%z1\\t%y1\";
2745 else
2746 return \"fst\\t%y0\";
2747
2748 case 1:
2749 /* There is no non-popping store to memory for XFmode. So if
2750 we need one, follow the store with a load. */
2751 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2752 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2753 else
2754 return \"fstp%z0\\t%y0\";
2755
2756 case 2:
2757 switch (standard_80387_constant_p (operands[1]))
2758 {
2759 case 1:
2760 return \"fldz\";
2761 case 2:
2762 return \"fld1\";
2763 }
2764 break;
2765
2766 case 3: case 4:
2767 return \"#\";
2768 }
2769 abort();
2770 }"
2771 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2772 (set_attr "mode" "XF,XF,XF,SI,SI")])
2773
2774 (define_insn "*movxf_integer"
2775 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2776 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2777 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778 && !optimize_size
2779 && (reload_in_progress || reload_completed
2780 || GET_CODE (operands[1]) != CONST_DOUBLE
2781 || memory_operand (operands[0], XFmode))"
2782 "*
2783 {
2784 switch (which_alternative)
2785 {
2786 case 0:
2787 if (REG_P (operands[1])
2788 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2789 return \"fstp\\t%y0\";
2790 else if (STACK_TOP_P (operands[0]))
2791 return \"fld%z1\\t%y1\";
2792 else
2793 return \"fst\\t%y0\";
2794
2795 case 1:
2796 /* There is no non-popping store to memory for XFmode. So if
2797 we need one, follow the store with a load. */
2798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2799 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2800 else
2801 return \"fstp%z0\\t%y0\";
2802
2803 case 2:
2804 switch (standard_80387_constant_p (operands[1]))
2805 {
2806 case 1:
2807 return \"fldz\";
2808 case 2:
2809 return \"fld1\";
2810 }
2811 break;
2812
2813 case 3: case 4:
2814 return \"#\";
2815 }
2816 abort();
2817 }"
2818 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2819 (set_attr "mode" "XF,XF,XF,SI,SI")])
2820
2821 (define_insn "*movtf_integer"
2822 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2823 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2824 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2825 && !optimize_size
2826 && (reload_in_progress || reload_completed
2827 || GET_CODE (operands[1]) != CONST_DOUBLE
2828 || memory_operand (operands[0], TFmode))"
2829 "*
2830 {
2831 switch (which_alternative)
2832 {
2833 case 0:
2834 if (REG_P (operands[1])
2835 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2836 return \"fstp\\t%y0\";
2837 else if (STACK_TOP_P (operands[0]))
2838 return \"fld%z1\\t%y1\";
2839 else
2840 return \"fst\\t%y0\";
2841
2842 case 1:
2843 /* There is no non-popping store to memory for XFmode. So if
2844 we need one, follow the store with a load. */
2845 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2846 return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
2847 else
2848 return \"fstp%z0\\t%y0\";
2849
2850 case 2:
2851 switch (standard_80387_constant_p (operands[1]))
2852 {
2853 case 1:
2854 return \"fldz\";
2855 case 2:
2856 return \"fld1\";
2857 }
2858 break;
2859
2860 case 3: case 4:
2861 return \"#\";
2862 }
2863 abort();
2864 }"
2865 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2866 (set_attr "mode" "XF,XF,XF,SI,SI")])
2867
2868 (define_split
2869 [(set (match_operand 0 "nonimmediate_operand" "")
2870 (match_operand 1 "general_operand" ""))]
2871 "reload_completed
2872 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2873 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2874 && ! (ANY_FP_REG_P (operands[0]) ||
2875 (GET_CODE (operands[0]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2877 && ! (ANY_FP_REG_P (operands[1]) ||
2878 (GET_CODE (operands[1]) == SUBREG
2879 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2880 [(set (match_dup 2) (match_dup 5))
2881 (set (match_dup 3) (match_dup 6))
2882 (set (match_dup 4) (match_dup 7))]
2883 "if (ix86_split_long_move (operands)) DONE;")
2884
2885 (define_split
2886 [(set (match_operand 0 "register_operand" "")
2887 (match_operand 1 "memory_operand" ""))]
2888 "reload_completed
2889 && GET_CODE (operands[1]) == MEM
2890 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
2891 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2892 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2893 && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
2894 [(set (match_dup 0)
2895 (match_dup 1))]
2896 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2897
2898 (define_insn "swapxf"
2899 [(set (match_operand:XF 0 "register_operand" "+f")
2900 (match_operand:XF 1 "register_operand" "+f"))
2901 (set (match_dup 1)
2902 (match_dup 0))]
2903 ""
2904 "*
2905 {
2906 if (STACK_TOP_P (operands[0]))
2907 return \"fxch\\t%1\";
2908 else
2909 return \"fxch\\t%0\";
2910 }"
2911 [(set_attr "type" "fxch")
2912 (set_attr "mode" "XF")])
2913
2914 (define_insn "swaptf"
2915 [(set (match_operand:TF 0 "register_operand" "+f")
2916 (match_operand:TF 1 "register_operand" "+f"))
2917 (set (match_dup 1)
2918 (match_dup 0))]
2919 ""
2920 "*
2921 {
2922 if (STACK_TOP_P (operands[0]))
2923 return \"fxch\\t%1\";
2924 else
2925 return \"fxch\\t%0\";
2926 }"
2927 [(set_attr "type" "fxch")
2928 (set_attr "mode" "XF")])
2929 \f
2930 ;; Zero extension instructions
2931
2932 (define_expand "zero_extendhisi2"
2933 [(set (match_operand:SI 0 "register_operand" "")
2934 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2935 ""
2936 "
2937 {
2938 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2939 {
2940 operands[1] = force_reg (HImode, operands[1]);
2941 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2942 DONE;
2943 }
2944 }")
2945
2946 (define_insn "zero_extendhisi2_and"
2947 [(set (match_operand:SI 0 "register_operand" "=r")
2948 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2949 (clobber (reg:CC 17))]
2950 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2951 "#"
2952 [(set_attr "type" "alu1")
2953 (set_attr "mode" "SI")])
2954
2955 (define_split
2956 [(set (match_operand:SI 0 "register_operand" "")
2957 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2958 (clobber (reg:CC 17))]
2959 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2960 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2961 (clobber (reg:CC 17))])]
2962 "")
2963
2964 (define_insn "*zero_extendhisi2_movzwl"
2965 [(set (match_operand:SI 0 "register_operand" "=r")
2966 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2967 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2968 "movz{wl|x}\\t{%1, %0|%0, %1}"
2969 [(set_attr "type" "imovx")
2970 (set_attr "mode" "SI")])
2971
2972 (define_expand "zero_extendqihi2"
2973 [(parallel
2974 [(set (match_operand:HI 0 "register_operand" "")
2975 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2976 (clobber (reg:CC 17))])]
2977 ""
2978 "")
2979
2980 (define_insn "*zero_extendqihi2_and"
2981 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2982 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2983 (clobber (reg:CC 17))]
2984 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2985 "#"
2986 [(set_attr "type" "alu1")
2987 (set_attr "mode" "HI")])
2988
2989 (define_insn "*zero_extendqihi2_movzbw_and"
2990 [(set (match_operand:HI 0 "register_operand" "=r,r")
2991 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2992 (clobber (reg:CC 17))]
2993 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2994 "#"
2995 [(set_attr "type" "imovx,alu1")
2996 (set_attr "mode" "HI")])
2997
2998 (define_insn "*zero_extendqihi2_movzbw"
2999 [(set (match_operand:HI 0 "register_operand" "=r")
3000 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3001 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3002 "movz{bw|x}\\t{%1, %0|%0, %1}"
3003 [(set_attr "type" "imovx")
3004 (set_attr "mode" "HI")])
3005
3006 ;; For the movzbw case strip only the clobber
3007 (define_split
3008 [(set (match_operand:HI 0 "register_operand" "")
3009 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3010 (clobber (reg:CC 17))]
3011 "reload_completed
3012 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3013 && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
3014 [(set (match_operand:HI 0 "register_operand" "")
3015 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3016
3017 ;; When source and destination does not overlap, clear destination
3018 ;; first and then do the movb
3019 (define_split
3020 [(set (match_operand:HI 0 "register_operand" "")
3021 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3022 (clobber (reg:CC 17))]
3023 "reload_completed
3024 && QI_REG_P (operands[0])
3025 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3026 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3027 [(set (match_dup 0) (const_int 0))
3028 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3029 "operands[2] = gen_lowpart (QImode, operands[0]);")
3030
3031 ;; Rest is handled by single and.
3032 (define_split
3033 [(set (match_operand:HI 0 "register_operand" "")
3034 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3035 (clobber (reg:CC 17))]
3036 "reload_completed
3037 && true_regnum (operands[0]) == true_regnum (operands[1])"
3038 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3039 (clobber (reg:CC 17))])]
3040 "")
3041
3042 (define_expand "zero_extendqisi2"
3043 [(parallel
3044 [(set (match_operand:SI 0 "register_operand" "")
3045 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3046 (clobber (reg:CC 17))])]
3047 ""
3048 "")
3049
3050 (define_insn "*zero_extendqisi2_and"
3051 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3052 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3053 (clobber (reg:CC 17))]
3054 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3055 "#"
3056 [(set_attr "type" "alu1")
3057 (set_attr "mode" "SI")])
3058
3059 (define_insn "*zero_extendqisi2_movzbw_and"
3060 [(set (match_operand:SI 0 "register_operand" "=r,r")
3061 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3062 (clobber (reg:CC 17))]
3063 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3064 "#"
3065 [(set_attr "type" "imovx,alu1")
3066 (set_attr "mode" "SI")])
3067
3068 (define_insn "*zero_extendqisi2_movzbw"
3069 [(set (match_operand:SI 0 "register_operand" "=r")
3070 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3071 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3072 "movz{bl|x}\\t{%1, %0|%0, %1}"
3073 [(set_attr "type" "imovx")
3074 (set_attr "mode" "SI")])
3075
3076 ;; For the movzbl case strip only the clobber
3077 (define_split
3078 [(set (match_operand:SI 0 "register_operand" "")
3079 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3080 (clobber (reg:CC 17))]
3081 "reload_completed
3082 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3083 && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
3084 [(set (match_dup 0)
3085 (zero_extend:SI (match_dup 1)))])
3086
3087 ;; When source and destination does not overlap, clear destination
3088 ;; first and then do the movb
3089 (define_split
3090 [(set (match_operand:SI 0 "register_operand" "")
3091 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092 (clobber (reg:CC 17))]
3093 "reload_completed
3094 && QI_REG_P (operands[0])
3095 && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3096 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3097 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3098 [(set (match_dup 0) (const_int 0))
3099 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3100 "operands[2] = gen_lowpart (QImode, operands[0]);")
3101
3102 ;; Rest is handled by single and.
3103 (define_split
3104 [(set (match_operand:SI 0 "register_operand" "")
3105 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3106 (clobber (reg:CC 17))]
3107 "reload_completed
3108 && true_regnum (operands[0]) == true_regnum (operands[1])"
3109 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3110 (clobber (reg:CC 17))])]
3111 "")
3112
3113 ;; %%% Kill me once multi-word ops are sane.
3114 (define_insn "zero_extendsidi2"
3115 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3116 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))
3117 (clobber (reg:CC 17))]
3118 ""
3119 "#"
3120 [(set_attr "mode" "SI")])
3121
3122 (define_split
3123 [(set (match_operand:DI 0 "register_operand" "")
3124 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3125 (clobber (reg:CC 17))]
3126 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])"
3127 [(set (match_dup 4) (const_int 0))]
3128 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3129
3130 (define_split
3131 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3132 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3133 (clobber (reg:CC 17))]
3134 "reload_completed"
3135 [(set (match_dup 3) (match_dup 1))
3136 (set (match_dup 4) (const_int 0))]
3137 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3138 \f
3139 ;; Sign extension instructions
3140
3141 (define_insn "extendsidi2"
3142 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3143 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3144 (clobber (reg:CC 17))
3145 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3146 ""
3147 "#")
3148
3149 ;; Extend to memory case when source register does die.
3150 (define_split
3151 [(set (match_operand:DI 0 "memory_operand" "")
3152 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3153 (clobber (reg:CC 17))
3154 (clobber (match_operand:SI 2 "register_operand" ""))]
3155 "(reload_completed
3156 && dead_or_set_p (insn, operands[1])
3157 && !reg_mentioned_p (operands[1], operands[0]))"
3158 [(set (match_dup 3) (match_dup 1))
3159 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3160 (clobber (reg:CC 17))])
3161 (set (match_dup 4) (match_dup 1))]
3162 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3163
3164 ;; Extend to memory case when source register does not die.
3165 (define_split
3166 [(set (match_operand:DI 0 "memory_operand" "")
3167 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3168 (clobber (reg:CC 17))
3169 (clobber (match_operand:SI 2 "register_operand" ""))]
3170 "reload_completed"
3171 [(const_int 0)]
3172 "
3173 {
3174 split_di (&operands[0], 1, &operands[3], &operands[4]);
3175
3176 emit_move_insn (operands[3], operands[1]);
3177
3178 /* Generate a cltd if possible and doing so it profitable. */
3179 if (true_regnum (operands[1]) == 0
3180 && true_regnum (operands[2]) == 1
3181 && (optimize_size || TARGET_USE_CLTD))
3182 {
3183 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3184 }
3185 else
3186 {
3187 emit_move_insn (operands[2], operands[1]);
3188 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3189 }
3190 emit_move_insn (operands[4], operands[2]);
3191 DONE;
3192 }")
3193
3194 ;; Extend to register case. Optimize case where source and destination
3195 ;; registers match and cases where we can use cltd.
3196 (define_split
3197 [(set (match_operand:DI 0 "register_operand" "")
3198 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3199 (clobber (reg:CC 17))
3200 (clobber (match_scratch:SI 2 ""))]
3201 "reload_completed"
3202 [(const_int 0)]
3203 "
3204 {
3205 split_di (&operands[0], 1, &operands[3], &operands[4]);
3206
3207 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3208 emit_move_insn (operands[3], operands[1]);
3209
3210 /* Generate a cltd if possible and doing so it profitable. */
3211 if (true_regnum (operands[3]) == 0
3212 && (optimize_size || TARGET_USE_CLTD))
3213 {
3214 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3215 DONE;
3216 }
3217
3218 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3219 emit_move_insn (operands[4], operands[1]);
3220
3221 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3222 DONE;
3223 }")
3224
3225 (define_insn "extendhisi2"
3226 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3227 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3228 ""
3229 "*
3230 {
3231 switch (get_attr_prefix_0f (insn))
3232 {
3233 case 0:
3234 return \"{cwtl|cwde}\";
3235 default:
3236 return \"movs{wl|x}\\t{%1,%0|%0, %1}\";
3237 }
3238 }"
3239 [(set_attr "type" "imovx")
3240 (set_attr "mode" "SI")
3241 (set (attr "prefix_0f")
3242 ;; movsx is short decodable while cwtl is vector decoded.
3243 (if_then_else (and (eq_attr "cpu" "!k6")
3244 (eq_attr "alternative" "0"))
3245 (const_string "0")
3246 (const_string "1")))
3247 (set (attr "modrm")
3248 (if_then_else (eq_attr "prefix_0f" "0")
3249 (const_string "0")
3250 (const_string "1")))])
3251
3252 (define_insn "extendqihi2"
3253 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3254 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3255 ""
3256 "*
3257 {
3258 switch (get_attr_prefix_0f (insn))
3259 {
3260 case 0:
3261 return \"{cbtw|cbw}\";
3262 default:
3263 return \"movs{bw|x}\\t{%1,%0|%0, %1}\";
3264 }
3265 }"
3266 [(set_attr "type" "imovx")
3267 (set_attr "mode" "HI")
3268 (set (attr "prefix_0f")
3269 ;; movsx is short decodable while cwtl is vector decoded.
3270 (if_then_else (and (eq_attr "cpu" "!k6")
3271 (eq_attr "alternative" "0"))
3272 (const_string "0")
3273 (const_string "1")))
3274 (set (attr "modrm")
3275 (if_then_else (eq_attr "prefix_0f" "0")
3276 (const_string "0")
3277 (const_string "1")))])
3278
3279 (define_insn "extendqisi2"
3280 [(set (match_operand:SI 0 "register_operand" "=r")
3281 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3282 ""
3283 "movs{bl|x}\\t{%1,%0|%0, %1}"
3284 [(set_attr "type" "imovx")
3285 (set_attr "mode" "SI")])
3286 \f
3287 ;; Conversions between float and double.
3288
3289 ;; These are all no-ops in the model used for the 80387. So just
3290 ;; emit moves.
3291
3292 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3293 (define_insn "*dummy_extendsfdf2"
3294 [(set (match_operand:DF 0 "push_operand" "=<")
3295 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3296 "0"
3297 "#")
3298
3299 (define_split
3300 [(set (match_operand:DF 0 "push_operand" "")
3301 (float_extend:DF (match_operand:SF 1 "register_operand" "")))]
3302 "FP_REGNO_P (REGNO (operands[1]))"
3303 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3304 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3305
3306 (define_insn "*dummy_extendsfxf2"
3307 [(set (match_operand:XF 0 "push_operand" "=<")
3308 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3309 "0"
3310 "#")
3311
3312 (define_split
3313 [(set (match_operand:XF 0 "push_operand" "")
3314 (float_extend:XF (match_operand:SF 1 "register_operand" "")))]
3315 "FP_REGNO_P (REGNO (operands[1]))"
3316 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3317 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3318
3319 (define_insn "*dummy_extendsftf2"
3320 [(set (match_operand:TF 0 "push_operand" "=<")
3321 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3322 "0"
3323 "#")
3324
3325 (define_split
3326 [(set (match_operand:TF 0 "push_operand" "")
3327 (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3328 "FP_REGNO_P (REGNO (operands[1]))"
3329 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3330 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3331
3332 (define_insn "*dummy_extenddfxf2"
3333 [(set (match_operand:XF 0 "push_operand" "=<")
3334 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3335 "0"
3336 "#")
3337
3338 (define_split
3339 [(set (match_operand:XF 0 "push_operand" "")
3340 (float_extend:XF (match_operand:DF 1 "register_operand" "")))]
3341 "FP_REGNO_P (REGNO (operands[1]))"
3342 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3343 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3344
3345 (define_insn "*dummy_extenddftf2"
3346 [(set (match_operand:TF 0 "push_operand" "=<")
3347 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3348 "0"
3349 "#")
3350
3351 (define_split
3352 [(set (match_operand:TF 0 "push_operand" "")
3353 (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3354 "FP_REGNO_P (REGNO (operands[1]))"
3355 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3356 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3357
3358 (define_expand "extendsfdf2"
3359 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3360 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
3361 "TARGET_80387 || TARGET_SSE2"
3362 "
3363 {
3364 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3365 operands[1] = force_reg (SFmode, operands[1]);
3366 }")
3367
3368 (define_insn "*extendsfdf2_1"
3369 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3370 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3371 "(TARGET_80387 || TARGET_SSE2)
3372 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3373 "*
3374 {
3375 switch (which_alternative)
3376 {
3377 case 0:
3378 if (REG_P (operands[1])
3379 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3380 return \"fstp\\t%y0\";
3381 else if (STACK_TOP_P (operands[0]))
3382 return \"fld%z1\\t%y1\";
3383 else
3384 return \"fst\\t%y0\";
3385
3386 case 1:
3387 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3388 return \"fstp%z0\\t%y0\";
3389
3390 else
3391 return \"fst%z0\\t%y0\";
3392 case 2:
3393 return \"cvtss2sd\\t{%1, %0|%0, %1}\";
3394
3395 default:
3396 abort ();
3397 }
3398 }"
3399 [(set_attr "type" "fmov,fmov,sse")
3400 (set_attr "mode" "SF,XF,DF")])
3401
3402 (define_insn "*extendsfdf2_1_sse_only"
3403 [(set (match_operand:DF 0 "register_operand" "=Y")
3404 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3405 "!TARGET_80387 && TARGET_SSE2
3406 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3407 "cvtss2sd\\t{%1, %0|%0, %1}"
3408 [(set_attr "type" "sse")
3409 (set_attr "mode" "DF")])
3410
3411 (define_expand "extendsfxf2"
3412 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3413 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
3414 "TARGET_80387"
3415 "
3416 {
3417 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3418 operands[1] = force_reg (SFmode, operands[1]);
3419 }")
3420
3421 (define_insn "*extendsfxf2_1"
3422 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3423 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3424 "TARGET_80387
3425 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3426 "*
3427 {
3428 switch (which_alternative)
3429 {
3430 case 0:
3431 if (REG_P (operands[1])
3432 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3433 return \"fstp\\t%y0\";
3434 else if (STACK_TOP_P (operands[0]))
3435 return \"fld%z1\\t%y1\";
3436 else
3437 return \"fst\\t%y0\";
3438
3439 case 1:
3440 /* There is no non-popping store to memory for XFmode. So if
3441 we need one, follow the store with a load. */
3442 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3443 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3444 else
3445 return \"fstp%z0\\t%y0\";
3446
3447 default:
3448 abort ();
3449 }
3450 }"
3451 [(set_attr "type" "fmov")
3452 (set_attr "mode" "SF,XF")])
3453
3454 (define_expand "extendsftf2"
3455 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3456 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3457 "TARGET_80387"
3458 "
3459 {
3460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3461 operands[1] = force_reg (SFmode, operands[1]);
3462 }")
3463
3464 (define_insn "*extendsftf2_1"
3465 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3466 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3467 "TARGET_80387
3468 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3469 "*
3470 {
3471 switch (which_alternative)
3472 {
3473 case 0:
3474 if (REG_P (operands[1])
3475 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3476 return \"fstp\\t%y0\";
3477 else if (STACK_TOP_P (operands[0]))
3478 return \"fld%z1\\t%y1\";
3479 else
3480 return \"fst\\t%y0\";
3481
3482 case 1:
3483 /* There is no non-popping store to memory for XFmode. So if
3484 we need one, follow the store with a load. */
3485 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3486 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3487 else
3488 return \"fstp%z0\\t%y0\";
3489
3490 default:
3491 abort ();
3492 }
3493 }"
3494 [(set_attr "type" "fmov")
3495 (set_attr "mode" "SF,XF")])
3496
3497 (define_expand "extenddfxf2"
3498 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3499 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
3500 "TARGET_80387"
3501 "
3502 {
3503 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3504 operands[1] = force_reg (DFmode, operands[1]);
3505 }")
3506
3507 (define_insn "*extenddfxf2_1"
3508 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3509 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3510 "TARGET_80387
3511 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3512 "*
3513 {
3514 switch (which_alternative)
3515 {
3516 case 0:
3517 if (REG_P (operands[1])
3518 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3519 return \"fstp\\t%y0\";
3520 else if (STACK_TOP_P (operands[0]))
3521 return \"fld%z1\\t%y1\";
3522 else
3523 return \"fst\\t%y0\";
3524
3525 case 1:
3526 /* There is no non-popping store to memory for XFmode. So if
3527 we need one, follow the store with a load. */
3528 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3529 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3530 else
3531 return \"fstp%z0\\t%y0\";
3532
3533 default:
3534 abort ();
3535 }
3536 }"
3537 [(set_attr "type" "fmov")
3538 (set_attr "mode" "DF,XF")])
3539
3540 (define_expand "extenddftf2"
3541 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3542 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3543 "TARGET_80387"
3544 "
3545 {
3546 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3547 operands[1] = force_reg (DFmode, operands[1]);
3548 }")
3549
3550 (define_insn "*extenddftf2_1"
3551 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3552 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3553 "TARGET_80387
3554 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3555 "*
3556 {
3557 switch (which_alternative)
3558 {
3559 case 0:
3560 if (REG_P (operands[1])
3561 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3562 return \"fstp\\t%y0\";
3563 else if (STACK_TOP_P (operands[0]))
3564 return \"fld%z1\\t%y1\";
3565 else
3566 return \"fst\\t%y0\";
3567
3568 case 1:
3569 /* There is no non-popping store to memory for XFmode. So if
3570 we need one, follow the store with a load. */
3571 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3572 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3573 else
3574 return \"fstp%z0\\t%y0\";
3575
3576 default:
3577 abort ();
3578 }
3579 }"
3580 [(set_attr "type" "fmov")
3581 (set_attr "mode" "DF,XF")])
3582
3583 ;; %%% This seems bad bad news.
3584 ;; This cannot output into an f-reg because there is no way to be sure
3585 ;; of truncating in that case. Otherwise this is just like a simple move
3586 ;; insn. So we pretend we can output to a reg in order to get better
3587 ;; register preferencing, but we really use a stack slot.
3588
3589 (define_expand "truncdfsf2"
3590 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3591 (float_truncate:SF
3592 (match_operand:DF 1 "register_operand" "")))
3593 (clobber (match_dup 2))])]
3594 "TARGET_80387 || TARGET_SSE2"
3595 "
3596 if (TARGET_80387)
3597 operands[2] = assign_386_stack_local (SFmode, 0);
3598 else
3599 {
3600 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3601 DONE;
3602 }
3603 ")
3604
3605 (define_insn "*truncdfsf2_1"
3606 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f")
3607 (float_truncate:SF
3608 (match_operand:DF 1 "register_operand" "f,0")))
3609 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3610 "TARGET_80387 && !TARGET_SSE2"
3611 "*
3612 {
3613 switch (which_alternative)
3614 {
3615 case 0:
3616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617 return \"fstp%z0\\t%y0\";
3618 else
3619 return \"fst%z0\\t%y0\";
3620 case 1:
3621 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3622 }
3623 abort ();
3624 }"
3625 [(set_attr "type" "fmov,multi")
3626 (set_attr "mode" "SF,SF")])
3627
3628 (define_insn "*truncdfsf2_1_sse"
3629 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,Y")
3630 (float_truncate:SF
3631 (match_operand:DF 1 "nonimmediate_operand" "f,0,mY")))
3632 (clobber (match_operand:SF 2 "memory_operand" "=X,m,X"))]
3633 "TARGET_80387 && TARGET_SSE2"
3634 "*
3635 {
3636 switch (which_alternative)
3637 {
3638 case 0:
3639 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3640 return \"fstp%z0\\t%y0\";
3641 else
3642 return \"fst%z0\\t%y0\";
3643 case 1:
3644 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3645 case 2:
3646 case 3:
3647 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
3648 }
3649 abort ();
3650 }"
3651 [(set_attr "type" "fmov,multi,sse")
3652 (set_attr "mode" "SF,SF,DF")])
3653
3654 (define_insn "*truncdfsf2_2"
3655 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y")
3656 (float_truncate:SF
3657 (match_operand:DF 1 "nonimmediate_operand" "f,mY")))]
3658 "TARGET_80387 && TARGET_SSE2"
3659 "*
3660 {
3661 switch (which_alternative)
3662 {
3663 case 0:
3664 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3665 return \"fstp%z0\\t%y0\";
3666 else
3667 return \"fst%z0\\t%y0\";
3668 case 1:
3669 case 2:
3670 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
3671 }
3672 }"
3673 [(set_attr "type" "fmov,sse")
3674 (set_attr "mode" "SF,DF")])
3675
3676 (define_insn "truncdfsf2_3"
3677 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3678 (float_truncate:SF
3679 (match_operand:DF 1 "register_operand" "f")))]
3680 "TARGET_80387"
3681 "*
3682 {
3683 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3684 return \"fstp%z0\\t%y0\";
3685 else
3686 return \"fst%z0\\t%y0\";
3687 }"
3688 [(set_attr "type" "fmov")
3689 (set_attr "mode" "SF")])
3690
3691 (define_insn "truncdfsf2_sse_only"
3692 [(set (match_operand:SF 0 "register_operand" "=Y")
3693 (float_truncate:SF
3694 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3695 "!TARGET_80387 && TARGET_SSE2"
3696 "cvtsd2ss\\t{%1, %0|%0, %1}"
3697 [(set_attr "type" "sse")
3698 (set_attr "mode" "DF")])
3699
3700 (define_split
3701 [(set (match_operand:SF 0 "memory_operand" "")
3702 (float_truncate:SF
3703 (match_operand:DF 1 "register_operand" "")))
3704 (clobber (match_operand:SF 2 "memory_operand" ""))]
3705 "TARGET_80387"
3706 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3707 "")
3708
3709 (define_split
3710 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3711 (float_truncate:SF
3712 (match_operand:DF 1 "nonimmediate_operand" "")))
3713 (clobber (match_operand 2 "" ""))]
3714 "TARGET_80387 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
3715 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3716 "")
3717
3718 (define_split
3719 [(set (match_operand:SF 0 "register_operand" "")
3720 (float_truncate:SF
3721 (match_operand:DF 1 "register_operand" "")))
3722 (clobber (match_operand:SF 2 "memory_operand" ""))]
3723 "TARGET_80387 && reload_completed
3724 && FP_REG_P (operands[0])"
3725 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3726 (set (match_dup 0) (match_dup 2))]
3727 "")
3728
3729 (define_expand "truncxfsf2"
3730 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3731 (float_truncate:SF
3732 (match_operand:XF 1 "register_operand" "")))
3733 (clobber (match_dup 2))])]
3734 "TARGET_80387"
3735 "operands[2] = assign_386_stack_local (SFmode, 0);")
3736
3737 (define_insn "*truncxfsf2_1"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3739 (float_truncate:SF
3740 (match_operand:XF 1 "register_operand" "f,0")))
3741 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3742 "TARGET_80387"
3743 "*
3744 {
3745 switch (which_alternative)
3746 {
3747 case 0:
3748 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3749 return \"fstp%z0\\t%y0\";
3750 else
3751 return \"fst%z0\\t%y0\";
3752 case 1:
3753 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3754 }
3755 abort ();
3756 }"
3757 [(set_attr "type" "fmov,multi")
3758 (set_attr "mode" "SF")])
3759
3760 (define_insn "*truncxfsf2_2"
3761 [(set (match_operand:SF 0 "memory_operand" "=m")
3762 (float_truncate:SF
3763 (match_operand:XF 1 "register_operand" "f")))]
3764 "TARGET_80387"
3765 "*
3766 {
3767 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768 return \"fstp%z0\\t%y0\";
3769 else
3770 return \"fst%z0\\t%y0\";
3771 }"
3772 [(set_attr "type" "fmov")
3773 (set_attr "mode" "SF")])
3774
3775 (define_split
3776 [(set (match_operand:SF 0 "memory_operand" "")
3777 (float_truncate:SF
3778 (match_operand:XF 1 "register_operand" "")))
3779 (clobber (match_operand:SF 2 "memory_operand" ""))]
3780 "TARGET_80387"
3781 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3782 "")
3783
3784 (define_split
3785 [(set (match_operand:SF 0 "register_operand" "")
3786 (float_truncate:SF
3787 (match_operand:XF 1 "register_operand" "")))
3788 (clobber (match_operand:SF 2 "memory_operand" ""))]
3789 "TARGET_80387 && reload_completed"
3790 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3791 (set (match_dup 0) (match_dup 2))]
3792 "")
3793
3794 (define_expand "trunctfsf2"
3795 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3796 (float_truncate:SF
3797 (match_operand:TF 1 "register_operand" "")))
3798 (clobber (match_dup 2))])]
3799 "TARGET_80387"
3800 "operands[2] = assign_386_stack_local (SFmode, 0);")
3801
3802 (define_insn "*trunctfsf2_1"
3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3804 (float_truncate:SF
3805 (match_operand:TF 1 "register_operand" "f,0")))
3806 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3807 "TARGET_80387"
3808 "*
3809 {
3810 switch (which_alternative)
3811 {
3812 case 0:
3813 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3814 return \"fstp%z0\\t%y0\";
3815 else
3816 return \"fst%z0\\t%y0\";
3817 case 1:
3818 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3819 }
3820 abort ();
3821 }"
3822 [(set_attr "type" "fmov,multi")
3823 (set_attr "mode" "SF")])
3824
3825 (define_insn "*truncxfsf2_2"
3826 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3827 (float_truncate:SF
3828 (match_operand:TF 1 "register_operand" "f")))]
3829 "TARGET_80387"
3830 "*
3831 {
3832 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3833 return \"fstp%z0\\t%y0\";
3834 else
3835 return \"fst%z0\\t%y0\";
3836 }"
3837 [(set_attr "type" "fmov")
3838 (set_attr "mode" "SF")])
3839
3840 (define_split
3841 [(set (match_operand:SF 0 "memory_operand" "")
3842 (float_truncate:SF
3843 (match_operand:TF 1 "register_operand" "")))
3844 (clobber (match_operand:SF 2 "memory_operand" ""))]
3845 "TARGET_80387"
3846 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3847 "")
3848
3849 (define_split
3850 [(set (match_operand:SF 0 "register_operand" "")
3851 (float_truncate:SF
3852 (match_operand:TF 1 "register_operand" "")))
3853 (clobber (match_operand:SF 2 "memory_operand" ""))]
3854 "TARGET_80387 && reload_completed"
3855 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3856 (set (match_dup 0) (match_dup 2))]
3857 "")
3858
3859
3860 (define_expand "truncxfdf2"
3861 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3862 (float_truncate:DF
3863 (match_operand:XF 1 "register_operand" "")))
3864 (clobber (match_dup 2))])]
3865 "TARGET_80387"
3866 "operands[2] = assign_386_stack_local (DFmode, 0);")
3867
3868 (define_insn "*truncxfdf2_1"
3869 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3870 (float_truncate:DF
3871 (match_operand:XF 1 "register_operand" "f,0")))
3872 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3873 "TARGET_80387"
3874 "*
3875 {
3876 switch (which_alternative)
3877 {
3878 case 0:
3879 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3880 return \"fstp%z0\\t%y0\";
3881 else
3882 return \"fst%z0\\t%y0\";
3883 case 1:
3884 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3885 }
3886 abort ();
3887 }"
3888 [(set_attr "type" "fmov,multi")
3889 (set_attr "mode" "DF")])
3890
3891 (define_insn "*truncxfdf2_2"
3892 [(set (match_operand:DF 0 "memory_operand" "=m")
3893 (float_truncate:DF
3894 (match_operand:XF 1 "register_operand" "f")))]
3895 "TARGET_80387"
3896 "*
3897 {
3898 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3899 return \"fstp%z0\\t%y0\";
3900 else
3901 return \"fst%z0\\t%y0\";
3902 }"
3903 [(set_attr "type" "fmov")
3904 (set_attr "mode" "DF")])
3905
3906 (define_split
3907 [(set (match_operand:DF 0 "memory_operand" "")
3908 (float_truncate:DF
3909 (match_operand:XF 1 "register_operand" "")))
3910 (clobber (match_operand:DF 2 "memory_operand" ""))]
3911 "TARGET_80387"
3912 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3913 "")
3914
3915 (define_split
3916 [(set (match_operand:DF 0 "register_operand" "")
3917 (float_truncate:DF
3918 (match_operand:XF 1 "register_operand" "")))
3919 (clobber (match_operand:DF 2 "memory_operand" ""))]
3920 "TARGET_80387 && reload_completed"
3921 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3922 (set (match_dup 0) (match_dup 2))]
3923 "")
3924
3925 (define_expand "trunctfdf2"
3926 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3927 (float_truncate:DF
3928 (match_operand:TF 1 "register_operand" "")))
3929 (clobber (match_dup 2))])]
3930 "TARGET_80387"
3931 "operands[2] = assign_386_stack_local (DFmode, 0);")
3932
3933 (define_insn "*trunctfdf2_1"
3934 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3935 (float_truncate:DF
3936 (match_operand:TF 1 "register_operand" "f,0")))
3937 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3938 "TARGET_80387"
3939 "*
3940 {
3941 switch (which_alternative)
3942 {
3943 case 0:
3944 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3945 return \"fstp%z0\\t%y0\";
3946 else
3947 return \"fst%z0\\t%y0\";
3948 case 1:
3949 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3950 }
3951 abort ();
3952 }"
3953 [(set_attr "type" "fmov,multi")
3954 (set_attr "mode" "DF")])
3955
3956 (define_insn "*truncxfdf2_2"
3957 [(set (match_operand:DF 0 "memory_operand" "=m")
3958 (float_truncate:DF
3959 (match_operand:TF 1 "register_operand" "f")))]
3960 "TARGET_80387"
3961 "*
3962 {
3963 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3964 return \"fstp%z0\\t%y0\";
3965 else
3966 return \"fst%z0\\t%y0\";
3967 }"
3968 [(set_attr "type" "fmov")
3969 (set_attr "mode" "DF")])
3970
3971 (define_split
3972 [(set (match_operand:DF 0 "memory_operand" "")
3973 (float_truncate:DF
3974 (match_operand:TF 1 "register_operand" "")))
3975 (clobber (match_operand:DF 2 "memory_operand" ""))]
3976 "TARGET_80387"
3977 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3978 "")
3979
3980 (define_split
3981 [(set (match_operand:DF 0 "register_operand" "")
3982 (float_truncate:DF
3983 (match_operand:TF 1 "register_operand" "")))
3984 (clobber (match_operand:DF 2 "memory_operand" ""))]
3985 "TARGET_80387 && reload_completed"
3986 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3987 (set (match_dup 0) (match_dup 2))]
3988 "")
3989
3990 \f
3991 ;; %%% Break up all these bad boys.
3992
3993 ;; Signed conversion to DImode.
3994
3995 (define_expand "fix_truncxfdi2"
3996 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3997 (fix:DI (match_operand:XF 1 "register_operand" "")))
3998 (clobber (match_dup 2))
3999 (clobber (match_dup 3))
4000 (clobber (match_scratch:SI 4 ""))
4001 (clobber (match_scratch:XF 5 ""))])]
4002 "TARGET_80387"
4003 "operands[2] = assign_386_stack_local (SImode, 0);
4004 operands[3] = assign_386_stack_local (DImode, 1);")
4005
4006 (define_expand "fix_trunctfdi2"
4007 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4008 (fix:DI (match_operand:TF 1 "register_operand" "")))
4009 (clobber (match_dup 2))
4010 (clobber (match_dup 3))
4011 (clobber (match_scratch:SI 4 ""))
4012 (clobber (match_scratch:TF 5 ""))])]
4013 "TARGET_80387"
4014 "operands[2] = assign_386_stack_local (SImode, 0);
4015 operands[3] = assign_386_stack_local (DImode, 1);")
4016
4017 (define_expand "fix_truncdfdi2"
4018 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4019 (fix:DI (match_operand:DF 1 "register_operand" "")))
4020 (clobber (match_dup 2))
4021 (clobber (match_dup 3))
4022 (clobber (match_scratch:SI 4 ""))
4023 (clobber (match_scratch:DF 5 ""))])]
4024 "TARGET_80387"
4025 "operands[2] = assign_386_stack_local (SImode, 0);
4026 operands[3] = assign_386_stack_local (DImode, 1);")
4027
4028 (define_expand "fix_truncsfdi2"
4029 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4030 (fix:DI (match_operand:SF 1 "register_operand" "")))
4031 (clobber (match_dup 2))
4032 (clobber (match_dup 3))
4033 (clobber (match_scratch:SI 4 ""))
4034 (clobber (match_scratch:SF 5 ""))])]
4035 "TARGET_80387"
4036 "operands[2] = assign_386_stack_local (SImode, 0);
4037 operands[3] = assign_386_stack_local (DImode, 1);")
4038
4039 (define_insn "*fix_truncdi_1"
4040 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4041 (fix:DI (match_operand 1 "register_operand" "f,f")))
4042 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4043 (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
4044 (clobber (match_scratch:SI 4 "=&r,&r"))
4045 (clobber (match_scratch 5 "=&f,&f"))]
4046 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
4047 "* return output_fix_trunc (insn, operands);"
4048 [(set_attr "type" "multi")])
4049
4050 (define_split
4051 [(set (match_operand:DI 0 "register_operand" "")
4052 (fix:DI (match_operand 1 "register_operand" "")))
4053 (clobber (match_operand:SI 2 "memory_operand" ""))
4054 (clobber (match_operand:DI 3 "memory_operand" ""))
4055 (clobber (match_scratch:SI 4 ""))
4056 (clobber (match_scratch 5 ""))]
4057 "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
4058 [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
4059 (clobber (match_dup 2))
4060 (clobber (match_dup 3))
4061 (clobber (match_dup 4))
4062 (clobber (match_dup 5))])
4063 (set (match_dup 0) (match_dup 3))]
4064 "")
4065
4066 ;; Signed conversion to SImode.
4067
4068 (define_expand "fix_truncxfsi2"
4069 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4070 (fix:SI (match_operand:XF 1 "register_operand" "")))
4071 (clobber (match_dup 2))
4072 (clobber (match_dup 3))
4073 (clobber (match_scratch:SI 4 ""))])]
4074 "TARGET_80387"
4075 "operands[2] = assign_386_stack_local (SImode, 0);
4076 operands[3] = assign_386_stack_local (SImode, 1);")
4077
4078 (define_expand "fix_trunctfsi2"
4079 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4080 (fix:SI (match_operand:TF 1 "register_operand" "")))
4081 (clobber (match_dup 2))
4082 (clobber (match_dup 3))
4083 (clobber (match_scratch:SI 4 ""))])]
4084 "TARGET_80387"
4085 "operands[2] = assign_386_stack_local (SImode, 0);
4086 operands[3] = assign_386_stack_local (SImode, 1);")
4087
4088 (define_expand "fix_truncdfsi2"
4089 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090 (fix:SI (match_operand:DF 1 "register_operand" "")))
4091 (clobber (match_dup 2))
4092 (clobber (match_dup 3))
4093 (clobber (match_scratch:SI 4 ""))])]
4094 "TARGET_80387 || TARGET_SSE2"
4095 "
4096 {
4097 if (TARGET_SSE2)
4098 {
4099 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4100 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4101 if (out != operands[0])
4102 emit_move_insn (operands[0], out);
4103 DONE;
4104 }
4105 else
4106 {
4107 operands[2] = assign_386_stack_local (SImode, 0);
4108 operands[3] = assign_386_stack_local (SImode, 1);
4109 }
4110 }")
4111
4112 (define_expand "fix_truncsfsi2"
4113 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4114 (fix:SI (match_operand:SF 1 "register_operand" "")))
4115 (clobber (match_dup 2))
4116 (clobber (match_dup 3))
4117 (clobber (match_scratch:SI 4 ""))])]
4118 "TARGET_80387 || TARGET_SSE"
4119 "
4120 {
4121 if (TARGET_SSE2)
4122 {
4123 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4124 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4125 if (out != operands[0])
4126 emit_move_insn (operands[0], out);
4127 DONE;
4128 }
4129 else
4130 {
4131 operands[2] = assign_386_stack_local (SImode, 0);
4132 operands[3] = assign_386_stack_local (SImode, 1);
4133 }
4134 }")
4135
4136 (define_insn "*fix_truncsi_1"
4137 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4138 (fix:SI (match_operand 1 "register_operand" "f,f")))
4139 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4140 (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
4141 (clobber (match_scratch:SI 4 "=&r,r"))]
4142 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4143 && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4144 "* return output_fix_trunc (insn, operands);"
4145 [(set_attr "type" "multi")])
4146
4147 ;; When SSE available, it is always faster to use it!
4148 (define_insn "fix_truncsfsi_sse"
4149 [(set (match_operand:SI 0 "register_operand" "=r")
4150 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4151 "TARGET_SSE"
4152 "cvttss2si\\t{%1, %0|%0, %1}"
4153 [(set_attr "type" "sse")])
4154
4155 (define_insn "fix_truncdfsi_sse"
4156 [(set (match_operand:SI 0 "register_operand" "=r")
4157 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4158 "TARGET_SSE2"
4159 "cvttsd2si\\t{%1, %0|%0, %1}"
4160 [(set_attr "type" "sse")])
4161
4162 (define_split
4163 [(set (match_operand:SI 0 "register_operand" "")
4164 (fix:SI (match_operand 1 "register_operand" "")))
4165 (clobber (match_operand:SI 2 "memory_operand" ""))
4166 (clobber (match_operand:SI 3 "memory_operand" ""))
4167 (clobber (match_scratch:SI 4 ""))]
4168 "reload_completed"
4169 [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
4170 (clobber (match_dup 2))
4171 (clobber (match_dup 3))
4172 (clobber (match_dup 4))])
4173 (set (match_dup 0) (match_dup 3))]
4174 "")
4175
4176 ;; Signed conversion to HImode.
4177
4178 (define_expand "fix_truncxfhi2"
4179 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4180 (fix:HI (match_operand:XF 1 "register_operand" "")))
4181 (clobber (match_dup 2))
4182 (clobber (match_dup 3))
4183 (clobber (match_scratch:SI 4 ""))])]
4184 "TARGET_80387"
4185 "operands[2] = assign_386_stack_local (SImode, 0);
4186 operands[3] = assign_386_stack_local (HImode, 1);")
4187
4188 (define_expand "fix_trunctfhi2"
4189 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4190 (fix:HI (match_operand:TF 1 "register_operand" "")))
4191 (clobber (match_dup 2))
4192 (clobber (match_dup 3))
4193 (clobber (match_scratch:SI 4 ""))])]
4194 "TARGET_80387"
4195 "operands[2] = assign_386_stack_local (SImode, 0);
4196 operands[3] = assign_386_stack_local (HImode, 1);")
4197
4198 (define_expand "fix_truncdfhi2"
4199 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4200 (fix:HI (match_operand:DF 1 "register_operand" "")))
4201 (clobber (match_dup 2))
4202 (clobber (match_dup 3))
4203 (clobber (match_scratch:SI 4 ""))])]
4204 "TARGET_80387 && !TARGET_SSE2"
4205 "operands[2] = assign_386_stack_local (SImode, 0);
4206 operands[3] = assign_386_stack_local (HImode, 1);")
4207
4208 (define_expand "fix_truncsfhi2"
4209 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4210 (fix:HI (match_operand:SF 1 "register_operand" "")))
4211 (clobber (match_dup 2))
4212 (clobber (match_dup 3))
4213 (clobber (match_scratch:SI 4 ""))])]
4214 "TARGET_80387 && !TARGET_SSE"
4215 "operands[2] = assign_386_stack_local (SImode, 0);
4216 operands[3] = assign_386_stack_local (HImode, 1);")
4217
4218 (define_insn "*fix_trunchi_1"
4219 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4220 (fix:HI (match_operand 1 "register_operand" "f,f")))
4221 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4222 (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
4223 (clobber (match_scratch:SI 4 "=&r,r"))]
4224 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4225 && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4226 "* return output_fix_trunc (insn, operands);"
4227 [(set_attr "type" "multi")])
4228
4229 (define_split
4230 [(set (match_operand:HI 0 "register_operand" "")
4231 (fix:HI (match_operand 1 "register_operand" "")))
4232 (clobber (match_operand:SI 2 "memory_operand" ""))
4233 (clobber (match_operand:HI 3 "memory_operand" ""))
4234 (clobber (match_scratch:SI 4 ""))]
4235 "reload_completed"
4236 [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
4237 (clobber (match_dup 2))
4238 (clobber (match_dup 3))
4239 (clobber (match_dup 4))])
4240 (set (match_dup 0) (match_dup 3))]
4241 "")
4242
4243 ;; %%% Kill these when reload knows how to do it.
4244 (define_split
4245 [(set (match_operand 0 "register_operand" "")
4246 (fix (match_operand 1 "register_operand" "")))]
4247 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1]))
4248 && FP_REG_P (operands[1])"
4249 [(const_int 0)]
4250 "
4251 {
4252 operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]);
4253 operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]);
4254 emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
4255 emit_move_insn (operands[0], operands[2]);
4256 ix86_free_from_memory (GET_MODE (operands[0]));
4257 DONE;
4258 }")
4259
4260 ;; %% Not used yet.
4261 (define_insn "x86_fnstcw_1"
4262 [(set (match_operand:HI 0 "memory_operand" "=m")
4263 (unspec:HI [(reg:HI 18)] 11))]
4264 "TARGET_80387"
4265 "fnstcw\\t%0"
4266 [(set_attr "length" "2")
4267 (set_attr "mode" "HI")
4268 (set_attr "i387" "1")
4269 (set_attr "ppro_uops" "few")])
4270
4271 (define_insn "x86_fldcw_1"
4272 [(set (reg:HI 18)
4273 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
4274 "TARGET_80387"
4275 "fldcw\\t%0"
4276 [(set_attr "length" "2")
4277 (set_attr "mode" "HI")
4278 (set_attr "i387" "1")
4279 (set_attr "athlon_decode" "vector")
4280 (set_attr "ppro_uops" "few")])
4281 \f
4282 ;; Conversion between fixed point and floating point.
4283
4284 ;; Even though we only accept memory inputs, the backend _really_
4285 ;; wants to be able to do this between registers.
4286
4287 (define_insn "floathisf2"
4288 [(set (match_operand:SF 0 "register_operand" "=f,f")
4289 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4290 "TARGET_80387 && !TARGET_SSE"
4291 "@
4292 fild%z1\\t%1
4293 #"
4294 [(set_attr "type" "fmov,multi")
4295 (set_attr "mode" "SF")
4296 (set_attr "fp_int_src" "true")])
4297
4298 (define_expand "floatsisf2"
4299 [(set (match_operand:SF 0 "register_operand" "")
4300 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4301 "TARGET_SSE || TARGET_80387"
4302 "")
4303
4304 (define_insn "*floatsisf2_i387"
4305 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4306 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4307 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4308 "@
4309 fild%z1\\t%1
4310 #
4311 cvtsi2ss\\t{%1, %0|%0, %1}"
4312 [(set_attr "type" "fmov,multi,sse")
4313 (set_attr "mode" "SF")
4314 (set_attr "fp_int_src" "true")])
4315
4316 (define_insn "*floatsisf2_sse"
4317 [(set (match_operand:SF 0 "register_operand" "=x")
4318 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4319 "TARGET_80387 && TARGET_SSE"
4320 "cvtsi2ss\\t{%1, %0|%0, %1}"
4321 [(set_attr "type" "sse")
4322 (set_attr "mode" "SF")
4323 (set_attr "fp_int_src" "true")])
4324
4325 (define_insn "floatdisf2"
4326 [(set (match_operand:SF 0 "register_operand" "=f,f")
4327 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4328 "TARGET_80387"
4329 "@
4330 fild%z1\\t%1
4331 #"
4332 [(set_attr "type" "fmov,multi")
4333 (set_attr "mode" "SF")
4334 (set_attr "fp_int_src" "true")])
4335
4336 (define_insn "floathidf2"
4337 [(set (match_operand:DF 0 "register_operand" "=f,f")
4338 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4339 "TARGET_80387 && !TARGET_SSE2"
4340 "@
4341 fild%z1\\t%1
4342 #"
4343 [(set_attr "type" "fmov,multi")
4344 (set_attr "mode" "DF")
4345 (set_attr "fp_int_src" "true")])
4346
4347 (define_expand "floatsidf2"
4348 [(set (match_operand:DF 0 "register_operand" "")
4349 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4350 ""
4351 "")
4352
4353 (define_insn "*floatsidf2_i387"
4354 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4355 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4356 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4357 "@
4358 fild%z1\\t%1
4359 #
4360 cvtsi2sd\\t{%1, %0|%0, %1}"
4361 [(set_attr "type" "fmov,multi,sse")
4362 (set_attr "mode" "DF")
4363 (set_attr "fp_int_src" "true")])
4364
4365 (define_insn "*floatsidf2_sse"
4366 [(set (match_operand:DF 0 "register_operand" "=Y")
4367 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4368 "TARGET_SSE2"
4369 "cvtsi2sd\\t{%1, %0|%0, %1}"
4370 [(set_attr "type" "sse")
4371 (set_attr "mode" "DF")
4372 (set_attr "fp_int_src" "true")])
4373
4374 (define_insn "floatdidf2"
4375 [(set (match_operand:DF 0 "register_operand" "=f,f")
4376 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4377 "TARGET_80387 && TARGET_SSE2"
4378 "@
4379 fild%z1\\t%1
4380 #"
4381 [(set_attr "type" "fmov,multi")
4382 (set_attr "mode" "DF")
4383 (set_attr "fp_int_src" "true")])
4384
4385 (define_insn "floathixf2"
4386 [(set (match_operand:XF 0 "register_operand" "=f,f")
4387 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4388 "TARGET_80387"
4389 "@
4390 fild%z1\\t%1
4391 #"
4392 [(set_attr "type" "fmov,multi")
4393 (set_attr "mode" "XF")
4394 (set_attr "fp_int_src" "true")])
4395
4396 (define_insn "floathitf2"
4397 [(set (match_operand:TF 0 "register_operand" "=f,f")
4398 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4399 "TARGET_80387"
4400 "@
4401 fild%z1\\t%1
4402 #"
4403 [(set_attr "type" "fmov,multi")
4404 (set_attr "mode" "XF")
4405 (set_attr "fp_int_src" "true")])
4406
4407 (define_insn "floatsixf2"
4408 [(set (match_operand:XF 0 "register_operand" "=f,f")
4409 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4410 "TARGET_80387"
4411 "@
4412 fild%z1\\t%1
4413 #"
4414 [(set_attr "type" "fmov,multi")
4415 (set_attr "mode" "XF")
4416 (set_attr "fp_int_src" "true")])
4417
4418 (define_insn "floatsitf2"
4419 [(set (match_operand:TF 0 "register_operand" "=f,f")
4420 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4421 "TARGET_80387"
4422 "@
4423 fild%z1\\t%1
4424 #"
4425 [(set_attr "type" "fmov,multi")
4426 (set_attr "mode" "XF")
4427 (set_attr "fp_int_src" "true")])
4428
4429 (define_insn "floatdixf2"
4430 [(set (match_operand:XF 0 "register_operand" "=f,f")
4431 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4432 "TARGET_80387"
4433 "@
4434 fild%z1\\t%1
4435 #"
4436 [(set_attr "type" "fmov,multi")
4437 (set_attr "mode" "XF")
4438 (set_attr "fp_int_src" "true")])
4439
4440 (define_insn "floatditf2"
4441 [(set (match_operand:TF 0 "register_operand" "=f,f")
4442 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4443 "TARGET_80387"
4444 "@
4445 fild%z1\\t%1
4446 #"
4447 [(set_attr "type" "fmov,multi")
4448 (set_attr "mode" "XF")
4449 (set_attr "fp_int_src" "true")])
4450
4451 ;; %%% Kill these when reload knows how to do it.
4452 (define_split
4453 [(set (match_operand 0 "register_operand" "")
4454 (float (match_operand 1 "register_operand" "")))]
4455 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4456 [(const_int 0)]
4457 "
4458 {
4459 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4460 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4461 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4462 ix86_free_from_memory (GET_MODE (operands[1]));
4463 DONE;
4464 }")
4465 \f
4466 ;; Add instructions
4467
4468 ;; %%% define_expand from the very first?
4469 ;; %%% splits for addsidi3
4470 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4471 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4472 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4473
4474 (define_insn "adddi3"
4475 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4476 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4477 (match_operand:DI 2 "general_operand" "roiF,riF")))
4478 (clobber (reg:CC 17))]
4479 ""
4480 "#")
4481
4482 (define_split
4483 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4484 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4485 (match_operand:DI 2 "general_operand" "")))
4486 (clobber (reg:CC 17))]
4487 "reload_completed"
4488 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
4489 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4490 (parallel [(set (match_dup 3)
4491 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4492 (match_dup 4))
4493 (match_dup 5)))
4494 (clobber (reg:CC 17))])]
4495 "split_di (operands+0, 1, operands+0, operands+3);
4496 split_di (operands+1, 1, operands+1, operands+4);
4497 split_di (operands+2, 1, operands+2, operands+5);")
4498
4499 (define_insn "*addsi3_carry"
4500 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4501 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4502 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4503 (match_operand:SI 2 "general_operand" "ri,rm")))
4504 (clobber (reg:CC 17))]
4505 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4506 "adc{l}\\t{%2, %0|%0, %2}"
4507 [(set_attr "type" "alu")
4508 (set_attr "pent_pair" "pu")
4509 (set_attr "mode" "SI")
4510 (set_attr "ppro_uops" "few")])
4511
4512 (define_insn "*addsi3_cc"
4513 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4514 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
4515 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4516 (plus:SI (match_dup 1) (match_dup 2)))]
4517 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4518 "add{l}\\t{%2, %0|%0, %2}"
4519 [(set_attr "type" "alu")
4520 (set_attr "mode" "SI")])
4521
4522 (define_insn "addqi3_cc"
4523 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4524 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
4525 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4526 (plus:QI (match_dup 1) (match_dup 2)))]
4527 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4528 "add{b}\\t{%2, %0|%0, %2}"
4529 [(set_attr "type" "alu")
4530 (set_attr "mode" "QI")])
4531
4532 (define_expand "addsi3"
4533 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4534 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4535 (match_operand:SI 2 "general_operand" "")))
4536 (clobber (reg:CC 17))])]
4537 ""
4538 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4539
4540 (define_insn "*lea_0"
4541 [(set (match_operand:SI 0 "register_operand" "=r")
4542 (match_operand:SI 1 "address_operand" "p"))]
4543 ""
4544 "lea{l}\\t{%a1, %0|%0, %a1}"
4545 [(set_attr "type" "lea")
4546 (set_attr "mode" "SI")])
4547
4548 ;; The lea patterns for non-Pmodes needs to be matched by several
4549 ;; insns converted to real lea by splitters.
4550
4551 (define_insn_and_split "*lea_general_1"
4552 [(set (match_operand 0 "register_operand" "=r")
4553 (plus (plus (match_operand 1 "register_operand" "r")
4554 (match_operand 2 "register_operand" "r"))
4555 (match_operand 3 "immediate_operand" "i")))]
4556 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4557 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4558 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4559 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4560 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4561 || GET_MODE (operands[3]) == VOIDmode)"
4562 "#"
4563 "&& reload_completed"
4564 [(const_int 0)]
4565 "
4566 {
4567 rtx pat;
4568 operands[0] = gen_lowpart (SImode, operands[0]);
4569 operands[1] = gen_lowpart (Pmode, operands[1]);
4570 operands[2] = gen_lowpart (Pmode, operands[2]);
4571 operands[3] = gen_lowpart (Pmode, operands[3]);
4572 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4573 operands[3]);
4574 if (Pmode != SImode)
4575 pat = gen_rtx_SUBREG (SImode, pat, 0);
4576 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4577 DONE;
4578 }"
4579 [(set_attr "type" "lea")
4580 (set_attr "mode" "SI")])
4581
4582 (define_insn_and_split "*lea_general_2"
4583 [(set (match_operand 0 "register_operand" "=r")
4584 (plus (mult (match_operand 1 "register_operand" "r")
4585 (match_operand 2 "const248_operand" "i"))
4586 (match_operand 3 "nonmemory_operand" "ri")))]
4587 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4588 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4589 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4590 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4591 || GET_MODE (operands[3]) == VOIDmode)"
4592 "#"
4593 "&& reload_completed"
4594 [(const_int 0)]
4595 "
4596 {
4597 rtx pat;
4598 operands[0] = gen_lowpart (SImode, operands[0]);
4599 operands[1] = gen_lowpart (Pmode, operands[1]);
4600 operands[3] = gen_lowpart (Pmode, operands[3]);
4601 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4602 operands[3]);
4603 if (Pmode != SImode)
4604 pat = gen_rtx_SUBREG (SImode, pat, 0);
4605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4606 DONE;
4607 }"
4608 [(set_attr "type" "lea")
4609 (set_attr "mode" "SI")])
4610
4611 (define_insn_and_split "*lea_general_3"
4612 [(set (match_operand 0 "register_operand" "=r")
4613 (plus (plus (mult (match_operand 1 "register_operand" "r")
4614 (match_operand 2 "const248_operand" "i"))
4615 (match_operand 3 "register_operand" "r"))
4616 (match_operand 4 "immediate_operand" "i")))]
4617 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4618 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4619 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4620 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4621 "#"
4622 "&& reload_completed"
4623 [(const_int 0)]
4624 "
4625 {
4626 rtx pat;
4627 operands[0] = gen_lowpart (SImode, operands[0]);
4628 operands[1] = gen_lowpart (Pmode, operands[1]);
4629 operands[3] = gen_lowpart (Pmode, operands[3]);
4630 operands[4] = gen_lowpart (Pmode, operands[4]);
4631 pat = gen_rtx_PLUS (Pmode,
4632 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4633 operands[2]),
4634 operands[3]),
4635 operands[4]);
4636 if (Pmode != SImode)
4637 pat = gen_rtx_SUBREG (SImode, pat, 0);
4638 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4639 DONE;
4640 }"
4641 [(set_attr "type" "lea")
4642 (set_attr "mode" "SI")])
4643
4644 (define_insn "*addsi_1"
4645 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
4646 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
4647 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
4648 (clobber (reg:CC 17))]
4649 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4650 "*
4651 {
4652 switch (get_attr_type (insn))
4653 {
4654 case TYPE_LEA:
4655 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
4656 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
4657
4658 case TYPE_INCDEC:
4659 if (! rtx_equal_p (operands[0], operands[1]))
4660 abort ();
4661 if (operands[2] == const1_rtx)
4662 return \"inc{l}\\t%0\";
4663 else if (operands[2] == constm1_rtx)
4664 return \"dec{l}\\t%0\";
4665 else
4666 abort();
4667
4668 default:
4669 if (! rtx_equal_p (operands[0], operands[1]))
4670 abort ();
4671
4672 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4673 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4674 if (GET_CODE (operands[2]) == CONST_INT
4675 && (INTVAL (operands[2]) == 128
4676 || (INTVAL (operands[2]) < 0
4677 && INTVAL (operands[2]) != -128)))
4678 {
4679 operands[2] = GEN_INT (-INTVAL (operands[2]));
4680 return \"sub{l}\\t{%2, %0|%0, %2}\";
4681 }
4682 return \"add{l}\\t{%2, %0|%0, %2}\";
4683 }
4684 }"
4685 [(set (attr "type")
4686 (cond [(eq_attr "alternative" "2")
4687 (const_string "lea")
4688 ; Current assemblers are broken and do not allow @GOTOFF in
4689 ; ought but a memory context.
4690 (match_operand:SI 2 "pic_symbolic_operand" "")
4691 (const_string "lea")
4692 (match_operand:SI 2 "incdec_operand" "")
4693 (const_string "incdec")
4694 ]
4695 (const_string "alu")))
4696 (set_attr "mode" "SI")])
4697
4698 ;; Convert lea to the lea pattern to avoid flags dependency.
4699 (define_split
4700 [(set (match_operand 0 "register_operand" "")
4701 (plus (match_operand 1 "register_operand" "")
4702 (match_operand 2 "nonmemory_operand" "")))
4703 (clobber (reg:CC 17))]
4704 "reload_completed
4705 && true_regnum (operands[0]) != true_regnum (operands[1])"
4706 [(const_int 0)]
4707 "
4708 {
4709 rtx pat;
4710 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
4711 may confuse gen_lowpart. */
4712 if (GET_MODE (operands[0]) != Pmode)
4713 {
4714 operands[1] = gen_lowpart (Pmode, operands[1]);
4715 operands[2] = gen_lowpart (Pmode, operands[2]);
4716 }
4717 operands[0] = gen_lowpart (SImode, operands[0]);
4718 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
4719 if (Pmode != SImode)
4720 pat = gen_rtx_SUBREG (SImode, pat, 0);
4721 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4722 DONE;
4723 }")
4724
4725 (define_insn "*addsi_2"
4726 [(set (reg 17)
4727 (compare
4728 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4729 (match_operand:SI 2 "general_operand" "rmni,rni"))
4730 (const_int 0)))
4731 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4732 (plus:SI (match_dup 1) (match_dup 2)))]
4733 "ix86_match_ccmode (insn, CCGOCmode)
4734 && ix86_binary_operator_ok (PLUS, SImode, operands)
4735 /* Current assemblers are broken and do not allow @GOTOFF in
4736 ought but a memory context. */
4737 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4738 "*
4739 {
4740 switch (get_attr_type (insn))
4741 {
4742 case TYPE_INCDEC:
4743 if (! rtx_equal_p (operands[0], operands[1]))
4744 abort ();
4745 if (operands[2] == const1_rtx)
4746 return \"inc{l}\\t%0\";
4747 else if (operands[2] == constm1_rtx)
4748 return \"dec{l}\\t%0\";
4749 else
4750 abort();
4751
4752 default:
4753 if (! rtx_equal_p (operands[0], operands[1]))
4754 abort ();
4755 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4756 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4757 if (GET_CODE (operands[2]) == CONST_INT
4758 && (INTVAL (operands[2]) == 128
4759 || (INTVAL (operands[2]) < 0
4760 && INTVAL (operands[2]) != -128)))
4761 {
4762 operands[2] = GEN_INT (-INTVAL (operands[2]));
4763 return \"sub{l}\\t{%2, %0|%0, %2}\";
4764 }
4765 return \"add{l}\\t{%2, %0|%0, %2}\";
4766 }
4767 }"
4768 [(set (attr "type")
4769 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4770 (const_string "incdec")
4771 (const_string "alu")))
4772 (set_attr "mode" "SI")])
4773
4774 (define_insn "*addsi_3"
4775 [(set (reg 17)
4776 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
4777 (match_operand:SI 1 "nonimmediate_operand" "%0")))
4778 (clobber (match_scratch:SI 0 "=r"))]
4779 "ix86_match_ccmode (insn, CCZmode)
4780 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4781 /* Current assemblers are broken and do not allow @GOTOFF in
4782 ought but a memory context. */
4783 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4784 "*
4785 {
4786 switch (get_attr_type (insn))
4787 {
4788 case TYPE_INCDEC:
4789 if (! rtx_equal_p (operands[0], operands[1]))
4790 abort ();
4791 if (operands[2] == const1_rtx)
4792 return \"inc{l}\\t%0\";
4793 else if (operands[2] == constm1_rtx)
4794 return \"dec{l}\\t%0\";
4795 else
4796 abort();
4797
4798 default:
4799 if (! rtx_equal_p (operands[0], operands[1]))
4800 abort ();
4801 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4802 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4803 if (GET_CODE (operands[2]) == CONST_INT
4804 && (INTVAL (operands[2]) == 128
4805 || (INTVAL (operands[2]) < 0
4806 && INTVAL (operands[2]) != -128)))
4807 {
4808 operands[2] = GEN_INT (-INTVAL (operands[2]));
4809 return \"sub{l}\\t{%2, %0|%0, %2}\";
4810 }
4811 return \"add{l}\\t{%2, %0|%0, %2}\";
4812 }
4813 }"
4814 [(set (attr "type")
4815 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4816 (const_string "incdec")
4817 (const_string "alu")))
4818 (set_attr "mode" "SI")])
4819
4820 ; For comparisons agains 1, -1 and 128, we may generate better code
4821 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
4822 ; is matched then. We can't accept general immediate, because for
4823 ; case of overflows, the result is messed up.
4824 ; This pattern also don't hold of 0x80000000, since the value overflows
4825 ; when negated.
4826 ; Also carry flag is reversed compared to cmp, so this converison is valid
4827 ; only for comparisons not depending on it.
4828 (define_insn "*addsi_4"
4829 [(set (reg 17)
4830 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
4831 (match_operand:SI 2 "const_int_operand" "n")))
4832 (clobber (match_scratch:SI 0 "=rm"))]
4833 "ix86_match_ccmode (insn, CCGCmode)
4834 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
4835 "*
4836 {
4837 switch (get_attr_type (insn))
4838 {
4839 case TYPE_INCDEC:
4840 if (operands[2] == constm1_rtx)
4841 return \"inc{l}\\t%0\";
4842 else if (operands[2] == const1_rtx)
4843 return \"dec{l}\\t%0\";
4844 else
4845 abort();
4846
4847 default:
4848 if (! rtx_equal_p (operands[0], operands[1]))
4849 abort ();
4850 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4851 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4852 if ((INTVAL (operands[2]) == -128
4853 || (INTVAL (operands[2]) > 0
4854 && INTVAL (operands[2]) != 128)))
4855 return \"sub{l}\\t{%2, %0|%0, %2}\";
4856 operands[2] = GEN_INT (-INTVAL (operands[2]));
4857 return \"add{l}\\t{%2, %0|%0, %2}\";
4858 }
4859 }"
4860 [(set (attr "type")
4861 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4862 (const_string "incdec")
4863 (const_string "alu")))
4864 (set_attr "mode" "SI")])
4865
4866 (define_insn "*addsi_5"
4867 [(set (reg 17)
4868 (compare
4869 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
4870 (match_operand:SI 2 "general_operand" "rmni"))
4871 (const_int 0)))
4872 (clobber (match_scratch:SI 0 "=r"))]
4873 "ix86_match_ccmode (insn, CCGOCmode)
4874 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4875 /* Current assemblers are broken and do not allow @GOTOFF in
4876 ought but a memory context. */
4877 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4878 "*
4879 {
4880 switch (get_attr_type (insn))
4881 {
4882 case TYPE_INCDEC:
4883 if (! rtx_equal_p (operands[0], operands[1]))
4884 abort ();
4885 if (operands[2] == const1_rtx)
4886 return \"inc{l}\\t%0\";
4887 else if (operands[2] == constm1_rtx)
4888 return \"dec{l}\\t%0\";
4889 else
4890 abort();
4891
4892 default:
4893 if (! rtx_equal_p (operands[0], operands[1]))
4894 abort ();
4895 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4896 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4897 if (GET_CODE (operands[2]) == CONST_INT
4898 && (INTVAL (operands[2]) == 128
4899 || (INTVAL (operands[2]) < 0
4900 && INTVAL (operands[2]) != -128)))
4901 {
4902 operands[2] = GEN_INT (-INTVAL (operands[2]));
4903 return \"sub{l}\\t{%2, %0|%0, %2}\";
4904 }
4905 return \"add{l}\\t{%2, %0|%0, %2}\";
4906 }
4907 }"
4908 [(set (attr "type")
4909 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4910 (const_string "incdec")
4911 (const_string "alu")))
4912 (set_attr "mode" "SI")])
4913
4914 (define_expand "addhi3"
4915 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4916 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4917 (match_operand:HI 2 "general_operand" "")))
4918 (clobber (reg:CC 17))])]
4919 "TARGET_HIMODE_MATH"
4920 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
4921
4922 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
4923 ;; type optimizations enabled by define-splits. This is not important
4924 ;; for PII, and in fact harmful because of partial register stalls.
4925
4926 (define_insn "*addhi_1_lea"
4927 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
4928 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
4929 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
4930 (clobber (reg:CC 17))]
4931 "!TARGET_PARTIAL_REG_STALL
4932 && ix86_binary_operator_ok (PLUS, HImode, operands)"
4933 "*
4934 {
4935 switch (get_attr_type (insn))
4936 {
4937 case TYPE_LEA:
4938 return \"#\";
4939 case TYPE_INCDEC:
4940 if (operands[2] == const1_rtx)
4941 return \"inc{w}\\t%0\";
4942 else if (operands[2] == constm1_rtx
4943 || (GET_CODE (operands[2]) == CONST_INT
4944 && INTVAL (operands[2]) == 65535))
4945 return \"dec{w}\\t%0\";
4946 abort();
4947
4948 default:
4949 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4950 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4951 if (GET_CODE (operands[2]) == CONST_INT
4952 && (INTVAL (operands[2]) == 128
4953 || (INTVAL (operands[2]) < 0
4954 && INTVAL (operands[2]) != -128)))
4955 {
4956 operands[2] = GEN_INT (-INTVAL (operands[2]));
4957 return \"sub{w}\\t{%2, %0|%0, %2}\";
4958 }
4959 return \"add{w}\\t{%2, %0|%0, %2}\";
4960 }
4961 }"
4962 [(set (attr "type")
4963 (if_then_else (eq_attr "alternative" "2")
4964 (const_string "lea")
4965 (if_then_else (match_operand:HI 2 "incdec_operand" "")
4966 (const_string "incdec")
4967 (const_string "alu"))))
4968 (set_attr "mode" "HI,HI,SI")])
4969
4970 (define_insn "*addhi_1"
4971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4972 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4973 (match_operand:HI 2 "general_operand" "ri,rm")))
4974 (clobber (reg:CC 17))]
4975 "TARGET_PARTIAL_REG_STALL
4976 && ix86_binary_operator_ok (PLUS, HImode, operands)"
4977 "*
4978 {
4979 switch (get_attr_type (insn))
4980 {
4981 case TYPE_INCDEC:
4982 if (operands[2] == const1_rtx)
4983 return \"inc{w}\\t%0\";
4984 else if (operands[2] == constm1_rtx
4985 || (GET_CODE (operands[2]) == CONST_INT
4986 && INTVAL (operands[2]) == 65535))
4987 return \"dec{w}\\t%0\";
4988 abort();
4989
4990 default:
4991 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4992 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4993 if (GET_CODE (operands[2]) == CONST_INT
4994 && (INTVAL (operands[2]) == 128
4995 || (INTVAL (operands[2]) < 0
4996 && INTVAL (operands[2]) != -128)))
4997 {
4998 operands[2] = GEN_INT (-INTVAL (operands[2]));
4999 return \"sub{w}\\t{%2, %0|%0, %2}\";
5000 }
5001 return \"add{w}\\t{%2, %0|%0, %2}\";
5002 }
5003 }"
5004 [(set (attr "type")
5005 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5006 (const_string "incdec")
5007 (const_string "alu")))
5008 (set_attr "mode" "HI")])
5009
5010 (define_insn "*addhi_2"
5011 [(set (reg 17)
5012 (compare
5013 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5014 (match_operand:HI 2 "general_operand" "rmni,rni"))
5015 (const_int 0)))
5016 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5017 (plus:HI (match_dup 1) (match_dup 2)))]
5018 "ix86_match_ccmode (insn, CCGOCmode)
5019 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5020 "*
5021 {
5022 switch (get_attr_type (insn))
5023 {
5024 case TYPE_INCDEC:
5025 if (operands[2] == const1_rtx)
5026 return \"inc{w}\\t%0\";
5027 else if (operands[2] == constm1_rtx
5028 || (GET_CODE (operands[2]) == CONST_INT
5029 && INTVAL (operands[2]) == 65535))
5030 return \"dec{w}\\t%0\";
5031 abort();
5032
5033 default:
5034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5036 if (GET_CODE (operands[2]) == CONST_INT
5037 && (INTVAL (operands[2]) == 128
5038 || (INTVAL (operands[2]) < 0
5039 && INTVAL (operands[2]) != -128)))
5040 {
5041 operands[2] = GEN_INT (-INTVAL (operands[2]));
5042 return \"sub{w}\\t{%2, %0|%0, %2}\";
5043 }
5044 return \"add{w}\\t{%2, %0|%0, %2}\";
5045 }
5046 }"
5047 [(set (attr "type")
5048 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5049 (const_string "incdec")
5050 (const_string "alu")))
5051 (set_attr "mode" "HI")])
5052
5053 (define_insn "*addhi_3"
5054 [(set (reg 17)
5055 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5056 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5057 (clobber (match_scratch:HI 0 "=r"))]
5058 "ix86_match_ccmode (insn, CCZmode)
5059 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5060 "*
5061 {
5062 switch (get_attr_type (insn))
5063 {
5064 case TYPE_INCDEC:
5065 if (operands[2] == const1_rtx)
5066 return \"inc{w}\\t%0\";
5067 else if (operands[2] == constm1_rtx
5068 || (GET_CODE (operands[2]) == CONST_INT
5069 && INTVAL (operands[2]) == 65535))
5070 return \"dec{w}\\t%0\";
5071 abort();
5072
5073 default:
5074 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5075 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5076 if (GET_CODE (operands[2]) == CONST_INT
5077 && (INTVAL (operands[2]) == 128
5078 || (INTVAL (operands[2]) < 0
5079 && INTVAL (operands[2]) != -128)))
5080 {
5081 operands[2] = GEN_INT (-INTVAL (operands[2]));
5082 return \"sub{w}\\t{%2, %0|%0, %2}\";
5083 }
5084 return \"add{w}\\t{%2, %0|%0, %2}\";
5085 }
5086 }"
5087 [(set (attr "type")
5088 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5089 (const_string "incdec")
5090 (const_string "alu")))
5091 (set_attr "mode" "HI")])
5092
5093 ; See comments above addsi_3_imm for details.
5094 (define_insn "*addhi_4"
5095 [(set (reg 17)
5096 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5097 (match_operand:HI 2 "const_int_operand" "n")))
5098 (clobber (match_scratch:HI 0 "=rm"))]
5099 "ix86_match_ccmode (insn, CCGCmode)
5100 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5101 "*
5102 {
5103 switch (get_attr_type (insn))
5104 {
5105 case TYPE_INCDEC:
5106 if (operands[2] == constm1_rtx
5107 || (GET_CODE (operands[2]) == CONST_INT
5108 && INTVAL (operands[2]) == 65535))
5109 return \"inc{w}\\t%0\";
5110 else if (operands[2] == const1_rtx)
5111 return \"dec{w}\\t%0\";
5112 else
5113 abort();
5114
5115 default:
5116 if (! rtx_equal_p (operands[0], operands[1]))
5117 abort ();
5118 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5119 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5120 if ((INTVAL (operands[2]) == -128
5121 || (INTVAL (operands[2]) > 0
5122 && INTVAL (operands[2]) != 128)))
5123 return \"sub{w}\\t{%2, %0|%0, %2}\";
5124 operands[2] = GEN_INT (-INTVAL (operands[2]));
5125 return \"add{w}\\t{%2, %0|%0, %2}\";
5126 }
5127 }"
5128 [(set (attr "type")
5129 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5130 (const_string "incdec")
5131 (const_string "alu")))
5132 (set_attr "mode" "SI")])
5133
5134
5135 (define_insn "*addhi_5"
5136 [(set (reg 17)
5137 (compare
5138 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5139 (match_operand:HI 2 "general_operand" "rmni"))
5140 (const_int 0)))
5141 (clobber (match_scratch:HI 0 "=r"))]
5142 "ix86_match_ccmode (insn, CCGOCmode)
5143 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5144 "*
5145 {
5146 switch (get_attr_type (insn))
5147 {
5148 case TYPE_INCDEC:
5149 if (operands[2] == const1_rtx)
5150 return \"inc{w}\\t%0\";
5151 else if (operands[2] == constm1_rtx
5152 || (GET_CODE (operands[2]) == CONST_INT
5153 && INTVAL (operands[2]) == 65535))
5154 return \"dec{w}\\t%0\";
5155 abort();
5156
5157 default:
5158 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5159 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5160 if (GET_CODE (operands[2]) == CONST_INT
5161 && (INTVAL (operands[2]) == 128
5162 || (INTVAL (operands[2]) < 0
5163 && INTVAL (operands[2]) != -128)))
5164 {
5165 operands[2] = GEN_INT (-INTVAL (operands[2]));
5166 return \"sub{w}\\t{%2, %0|%0, %2}\";
5167 }
5168 return \"add{w}\\t{%2, %0|%0, %2}\";
5169 }
5170 }"
5171 [(set (attr "type")
5172 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5173 (const_string "incdec")
5174 (const_string "alu")))
5175 (set_attr "mode" "HI")])
5176
5177 (define_expand "addqi3"
5178 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5179 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5180 (match_operand:QI 2 "general_operand" "")))
5181 (clobber (reg:CC 17))])]
5182 "TARGET_QIMODE_MATH"
5183 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5184
5185 ;; %%% Potential partial reg stall on alternative 2. What to do?
5186 (define_insn "*addqi_1_lea"
5187 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5188 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5189 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
5190 (clobber (reg:CC 17))]
5191 "!TARGET_PARTIAL_REG_STALL
5192 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5193 "*
5194 {
5195 int widen = (which_alternative == 2);
5196 switch (get_attr_type (insn))
5197 {
5198 case TYPE_LEA:
5199 return \"#\";
5200 case TYPE_INCDEC:
5201 if (operands[2] == const1_rtx)
5202 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5203 else if (operands[2] == constm1_rtx
5204 || (GET_CODE (operands[2]) == CONST_INT
5205 && INTVAL (operands[2]) == 255))
5206 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5207 abort();
5208
5209 default:
5210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5212 if (GET_CODE (operands[2]) == CONST_INT
5213 && (INTVAL (operands[2]) == 128
5214 || (INTVAL (operands[2]) < 0
5215 && INTVAL (operands[2]) != -128)))
5216 {
5217 operands[2] = GEN_INT (-INTVAL (operands[2]));
5218 if (widen)
5219 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5220 else
5221 return \"sub{b}\\t{%2, %0|%0, %2}\";
5222 }
5223 if (widen)
5224 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5225 else
5226 return \"add{b}\\t{%2, %0|%0, %2}\";
5227 }
5228 }"
5229 [(set (attr "type")
5230 (if_then_else (eq_attr "alternative" "3")
5231 (const_string "lea")
5232 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5233 (const_string "incdec")
5234 (const_string "alu"))))
5235 (set_attr "mode" "QI,QI,SI,SI")])
5236
5237 (define_insn "*addqi_1"
5238 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5239 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5240 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5241 (clobber (reg:CC 17))]
5242 "TARGET_PARTIAL_REG_STALL
5243 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5244 "*
5245 {
5246 int widen = (which_alternative == 2);
5247 switch (get_attr_type (insn))
5248 {
5249 case TYPE_INCDEC:
5250 if (operands[2] == const1_rtx)
5251 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5252 else if (operands[2] == constm1_rtx
5253 || (GET_CODE (operands[2]) == CONST_INT
5254 && INTVAL (operands[2]) == 255))
5255 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5256 abort();
5257
5258 default:
5259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5261 if (GET_CODE (operands[2]) == CONST_INT
5262 && (INTVAL (operands[2]) == 128
5263 || (INTVAL (operands[2]) < 0
5264 && INTVAL (operands[2]) != -128)))
5265 {
5266 operands[2] = GEN_INT (-INTVAL (operands[2]));
5267 if (widen)
5268 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5269 else
5270 return \"sub{b}\\t{%2, %0|%0, %2}\";
5271 }
5272 if (widen)
5273 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5274 else
5275 return \"add{b}\\t{%2, %0|%0, %2}\";
5276 }
5277 }"
5278 [(set (attr "type")
5279 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5280 (const_string "incdec")
5281 (const_string "alu")))
5282 (set_attr "mode" "QI,QI,SI")])
5283
5284 (define_insn "*addqi_2"
5285 [(set (reg 17)
5286 (compare
5287 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5288 (match_operand:QI 2 "general_operand" "qmni,qni"))
5289 (const_int 0)))
5290 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5291 (plus:QI (match_dup 1) (match_dup 2)))]
5292 "ix86_match_ccmode (insn, CCGOCmode)
5293 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5294 "*
5295 {
5296 switch (get_attr_type (insn))
5297 {
5298 case TYPE_INCDEC:
5299 if (operands[2] == const1_rtx)
5300 return \"inc{b}\\t%0\";
5301 else if (operands[2] == constm1_rtx
5302 || (GET_CODE (operands[2]) == CONST_INT
5303 && INTVAL (operands[2]) == 255))
5304 return \"dec{b}\\t%0\";
5305 abort();
5306
5307 default:
5308 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5309 if (GET_CODE (operands[2]) == CONST_INT
5310 && INTVAL (operands[2]) < 0)
5311 {
5312 operands[2] = GEN_INT (-INTVAL (operands[2]));
5313 return \"sub{b}\\t{%2, %0|%0, %2}\";
5314 }
5315 return \"add{b}\\t{%2, %0|%0, %2}\";
5316 }
5317 }"
5318 [(set (attr "type")
5319 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5320 (const_string "incdec")
5321 (const_string "alu")))
5322 (set_attr "mode" "QI")])
5323
5324 (define_insn "*addqi_3"
5325 [(set (reg 17)
5326 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
5327 (match_operand:QI 1 "nonimmediate_operand" "%0")))
5328 (clobber (match_scratch:QI 0 "=q"))]
5329 "ix86_match_ccmode (insn, CCZmode)
5330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5331 "*
5332 {
5333 switch (get_attr_type (insn))
5334 {
5335 case TYPE_INCDEC:
5336 if (operands[2] == const1_rtx)
5337 return \"inc{b}\\t%0\";
5338 else if (operands[2] == constm1_rtx
5339 || (GET_CODE (operands[2]) == CONST_INT
5340 && INTVAL (operands[2]) == 255))
5341 return \"dec{b}\\t%0\";
5342 abort();
5343
5344 default:
5345 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5346 if (GET_CODE (operands[2]) == CONST_INT
5347 && INTVAL (operands[2]) < 0)
5348 {
5349 operands[2] = GEN_INT (-INTVAL (operands[2]));
5350 return \"sub{b}\\t{%2, %0|%0, %2}\";
5351 }
5352 return \"add{b}\\t{%2, %0|%0, %2}\";
5353 }
5354 }"
5355 [(set (attr "type")
5356 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5357 (const_string "incdec")
5358 (const_string "alu")))
5359 (set_attr "mode" "QI")])
5360
5361 ; See comments above addsi_3_imm for details.
5362 (define_insn "*addqi_4"
5363 [(set (reg 17)
5364 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
5365 (match_operand:QI 2 "const_int_operand" "n")))
5366 (clobber (match_scratch:QI 0 "=qm"))]
5367 "ix86_match_ccmode (insn, CCGCmode)
5368 && (INTVAL (operands[2]) & 0xff) != 0x80"
5369 "*
5370 {
5371 switch (get_attr_type (insn))
5372 {
5373 case TYPE_INCDEC:
5374 if (operands[2] == constm1_rtx
5375 || (GET_CODE (operands[2]) == CONST_INT
5376 && INTVAL (operands[2]) == 255))
5377 return \"inc{b}\\t%0\";
5378 else if (operands[2] == const1_rtx)
5379 return \"dec{b}\\t%0\";
5380 else
5381 abort();
5382
5383 default:
5384 if (! rtx_equal_p (operands[0], operands[1]))
5385 abort ();
5386 if (INTVAL (operands[2]) < 0)
5387 {
5388 operands[2] = GEN_INT (-INTVAL (operands[2]));
5389 return \"add{b}\\t{%2, %0|%0, %2}\";
5390 }
5391 return \"sub{b}\\t{%2, %0|%0, %2}\";
5392 }
5393 }"
5394 [(set (attr "type")
5395 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5396 (const_string "incdec")
5397 (const_string "alu")))
5398 (set_attr "mode" "QI")])
5399
5400
5401 (define_insn "*addqi_5"
5402 [(set (reg 17)
5403 (compare
5404 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
5405 (match_operand:QI 2 "general_operand" "qmni"))
5406 (const_int 0)))
5407 (clobber (match_scratch:QI 0 "=q"))]
5408 "ix86_match_ccmode (insn, CCGOCmode)
5409 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5410 "*
5411 {
5412 switch (get_attr_type (insn))
5413 {
5414 case TYPE_INCDEC:
5415 if (operands[2] == const1_rtx)
5416 return \"inc{b}\\t%0\";
5417 else if (operands[2] == constm1_rtx
5418 || (GET_CODE (operands[2]) == CONST_INT
5419 && INTVAL (operands[2]) == 255))
5420 return \"dec{b}\\t%0\";
5421 abort();
5422
5423 default:
5424 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5425 if (GET_CODE (operands[2]) == CONST_INT
5426 && INTVAL (operands[2]) < 0)
5427 {
5428 operands[2] = GEN_INT (-INTVAL (operands[2]));
5429 return \"sub{b}\\t{%2, %0|%0, %2}\";
5430 }
5431 return \"add{b}\\t{%2, %0|%0, %2}\";
5432 }
5433 }"
5434 [(set (attr "type")
5435 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5436 (const_string "incdec")
5437 (const_string "alu")))
5438 (set_attr "mode" "QI")])
5439
5440
5441 (define_insn "addqi_ext_1"
5442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5443 (const_int 8)
5444 (const_int 8))
5445 (plus:SI
5446 (zero_extract:SI
5447 (match_operand 1 "ext_register_operand" "0")
5448 (const_int 8)
5449 (const_int 8))
5450 (match_operand:QI 2 "general_operand" "qmn")))
5451 (clobber (reg:CC 17))]
5452 ""
5453 "*
5454 {
5455 switch (get_attr_type (insn))
5456 {
5457 case TYPE_INCDEC:
5458 if (operands[2] == const1_rtx)
5459 return \"inc{b}\\t%h0\";
5460 else if (operands[2] == constm1_rtx
5461 || (GET_CODE (operands[2]) == CONST_INT
5462 && INTVAL (operands[2]) == 255))
5463 return \"dec{b}\\t%h0\";
5464 abort();
5465
5466 default:
5467 return \"add{b}\\t{%2, %h0|%h0, %2}\";
5468 }
5469 }"
5470 [(set (attr "type")
5471 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5472 (const_string "incdec")
5473 (const_string "alu")))
5474 (set_attr "mode" "QI")])
5475
5476 (define_insn "*addqi_ext_2"
5477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5478 (const_int 8)
5479 (const_int 8))
5480 (plus:SI
5481 (zero_extract:SI
5482 (match_operand 1 "ext_register_operand" "%0")
5483 (const_int 8)
5484 (const_int 8))
5485 (zero_extract:SI
5486 (match_operand 2 "ext_register_operand" "q")
5487 (const_int 8)
5488 (const_int 8))))
5489 (clobber (reg:CC 17))]
5490 ""
5491 "add{b}\\t{%h2, %h0|%h0, %h2}"
5492 [(set_attr "type" "alu")
5493 (set_attr "mode" "QI")])
5494
5495 ;; The patterns that match these are at the end of this file.
5496
5497 (define_expand "addxf3"
5498 [(set (match_operand:XF 0 "register_operand" "")
5499 (plus:XF (match_operand:XF 1 "register_operand" "")
5500 (match_operand:XF 2 "register_operand" "")))]
5501 "TARGET_80387"
5502 "")
5503
5504 (define_expand "addtf3"
5505 [(set (match_operand:TF 0 "register_operand" "")
5506 (plus:TF (match_operand:TF 1 "register_operand" "")
5507 (match_operand:TF 2 "register_operand" "")))]
5508 "TARGET_80387"
5509 "")
5510
5511 (define_expand "adddf3"
5512 [(set (match_operand:DF 0 "register_operand" "")
5513 (plus:DF (match_operand:DF 1 "register_operand" "")
5514 (match_operand:DF 2 "nonimmediate_operand" "")))]
5515 "TARGET_80387 || TARGET_SSE2"
5516 "")
5517
5518 (define_expand "addsf3"
5519 [(set (match_operand:SF 0 "register_operand" "")
5520 (plus:SF (match_operand:SF 1 "register_operand" "")
5521 (match_operand:SF 2 "nonimmediate_operand" "")))]
5522 "TARGET_80387 || TARGET_SSE"
5523 "")
5524 \f
5525 ;; Subtract instructions
5526
5527 ;; %%% define_expand from the very first?
5528 ;; %%% splits for subsidi3
5529
5530 (define_insn "subdi3"
5531 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5532 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
5533 (match_operand:DI 2 "general_operand" "roiF,riF")))
5534 (clobber (reg:CC 17))]
5535 ""
5536 "#")
5537
5538 (define_split
5539 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5540 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5541 (match_operand:DI 2 "general_operand" "")))
5542 (clobber (reg:CC 17))]
5543 "reload_completed"
5544 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
5545 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
5546 (parallel [(set (match_dup 3)
5547 (minus:SI (match_dup 4)
5548 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5549 (match_dup 5))))
5550 (clobber (reg:CC 17))])]
5551 "split_di (operands+0, 1, operands+0, operands+3);
5552 split_di (operands+1, 1, operands+1, operands+4);
5553 split_di (operands+2, 1, operands+2, operands+5);")
5554
5555 (define_insn "subsi3_carry"
5556 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5557 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5558 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5559 (match_operand:SI 2 "general_operand" "ri,rm"))))
5560 (clobber (reg:CC 17))]
5561 "ix86_binary_operator_ok (MINUS, SImode, operands)"
5562 "sbb{l}\\t{%2, %0|%0, %2}"
5563 [(set_attr "type" "alu")
5564 (set_attr "pent_pair" "pu")
5565 (set_attr "ppro_uops" "few")
5566 (set_attr "mode" "SI")])
5567
5568 (define_expand "subsi3"
5569 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5570 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5571 (match_operand:SI 2 "general_operand" "")))
5572 (clobber (reg:CC 17))])]
5573 ""
5574 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
5575
5576 (define_insn "*subsi_1"
5577 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5578 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5579 (match_operand:SI 2 "general_operand" "ri,rm")))
5580 (clobber (reg:CC 17))]
5581 "ix86_binary_operator_ok (MINUS, SImode, operands)"
5582 "sub{l}\\t{%2, %0|%0, %2}"
5583 [(set_attr "type" "alu")
5584 (set_attr "mode" "SI")])
5585
5586 (define_insn "*subsi_2"
5587 [(set (reg 17)
5588 (compare
5589 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5590 (match_operand:SI 2 "general_operand" "ri,rm"))
5591 (const_int 0)))
5592 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5593 (minus:SI (match_dup 1) (match_dup 2)))]
5594 "ix86_match_ccmode (insn, CCGOCmode)
5595 && ix86_binary_operator_ok (MINUS, SImode, operands)"
5596 "sub{l}\\t{%2, %0|%0, %2}"
5597 [(set_attr "type" "alu")
5598 (set_attr "mode" "SI")])
5599
5600 (define_insn "*subsi_3"
5601 [(set (reg 17)
5602 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
5603 (match_operand:SI 2 "general_operand" "ri,rm")))
5604 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5605 (minus:SI (match_dup 1) (match_dup 2)))]
5606 "ix86_match_ccmode (insn, CCmode)
5607 && ix86_binary_operator_ok (MINUS, SImode, operands)"
5608 "sub{l}\\t{%2, %0|%0, %2}"
5609 [(set_attr "type" "alu")
5610 (set_attr "mode" "SI")])
5611
5612 (define_expand "subhi3"
5613 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5614 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5615 (match_operand:HI 2 "general_operand" "")))
5616 (clobber (reg:CC 17))])]
5617 "TARGET_HIMODE_MATH"
5618 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
5619
5620 (define_insn "*subhi_1"
5621 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5622 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5623 (match_operand:HI 2 "general_operand" "ri,rm")))
5624 (clobber (reg:CC 17))]
5625 "ix86_binary_operator_ok (MINUS, HImode, operands)"
5626 "sub{w}\\t{%2, %0|%0, %2}"
5627 [(set_attr "type" "alu")
5628 (set_attr "mode" "HI")])
5629
5630 (define_insn "*subhi_2"
5631 [(set (reg 17)
5632 (compare
5633 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5634 (match_operand:HI 2 "general_operand" "ri,rm"))
5635 (const_int 0)))
5636 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5637 (minus:HI (match_dup 1) (match_dup 2)))]
5638 "ix86_match_ccmode (insn, CCGOCmode)
5639 && ix86_binary_operator_ok (MINUS, HImode, operands)"
5640 "sub{w}\\t{%2, %0|%0, %2}"
5641 [(set_attr "type" "alu")
5642 (set_attr "mode" "HI")])
5643
5644 (define_insn "*subhi_3"
5645 [(set (reg 17)
5646 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
5647 (match_operand:HI 2 "general_operand" "ri,rm")))
5648 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5649 (minus:HI (match_dup 1) (match_dup 2)))]
5650 "ix86_match_ccmode (insn, CCmode)
5651 && ix86_binary_operator_ok (MINUS, HImode, operands)"
5652 "sub{w}\\t{%2, %0|%0, %2}"
5653 [(set_attr "type" "alu")
5654 (set_attr "mode" "HI")])
5655
5656 (define_expand "subqi3"
5657 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5658 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5659 (match_operand:QI 2 "general_operand" "")))
5660 (clobber (reg:CC 17))])]
5661 "TARGET_QIMODE_MATH"
5662 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
5663
5664 (define_insn "*subqi_1"
5665 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5666 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5667 (match_operand:QI 2 "general_operand" "qn,qmn")))
5668 (clobber (reg:CC 17))]
5669 "ix86_binary_operator_ok (MINUS, QImode, operands)"
5670 "sub{b}\\t{%2, %0|%0, %2}"
5671 [(set_attr "type" "alu")
5672 (set_attr "mode" "QI")])
5673
5674 (define_insn "*subqi_2"
5675 [(set (reg 17)
5676 (compare
5677 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5678 (match_operand:QI 2 "general_operand" "qi,qm"))
5679 (const_int 0)))
5680 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5681 (minus:HI (match_dup 1) (match_dup 2)))]
5682 "ix86_match_ccmode (insn, CCGOCmode)
5683 && ix86_binary_operator_ok (MINUS, QImode, operands)"
5684 "sub{b}\\t{%2, %0|%0, %2}"
5685 [(set_attr "type" "alu")
5686 (set_attr "mode" "QI")])
5687
5688 (define_insn "*subqi_3"
5689 [(set (reg 17)
5690 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
5691 (match_operand:QI 2 "general_operand" "qi,qm")))
5692 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5693 (minus:HI (match_dup 1) (match_dup 2)))]
5694 "ix86_match_ccmode (insn, CCmode)
5695 && ix86_binary_operator_ok (MINUS, QImode, operands)"
5696 "sub{b}\\t{%2, %0|%0, %2}"
5697 [(set_attr "type" "alu")
5698 (set_attr "mode" "QI")])
5699
5700 ;; The patterns that match these are at the end of this file.
5701
5702 (define_expand "subxf3"
5703 [(set (match_operand:XF 0 "register_operand" "")
5704 (minus:XF (match_operand:XF 1 "register_operand" "")
5705 (match_operand:XF 2 "register_operand" "")))]
5706 "TARGET_80387"
5707 "")
5708
5709 (define_expand "subtf3"
5710 [(set (match_operand:TF 0 "register_operand" "")
5711 (minus:TF (match_operand:TF 1 "register_operand" "")
5712 (match_operand:TF 2 "register_operand" "")))]
5713 "TARGET_80387"
5714 "")
5715
5716 (define_expand "subdf3"
5717 [(set (match_operand:DF 0 "register_operand" "")
5718 (minus:DF (match_operand:DF 1 "register_operand" "")
5719 (match_operand:DF 2 "nonimmediate_operand" "")))]
5720 "TARGET_80387 || TARGET_SSE2"
5721 "")
5722
5723 (define_expand "subsf3"
5724 [(set (match_operand:SF 0 "register_operand" "")
5725 (minus:SF (match_operand:SF 1 "register_operand" "")
5726 (match_operand:SF 2 "nonimmediate_operand" "")))]
5727 "TARGET_80387 || TARGET_SSE"
5728 "")
5729 \f
5730 ;; Multiply instructions
5731
5732 (define_expand "mulsi3"
5733 [(parallel [(set (match_operand:SI 0 "register_operand" "")
5734 (mult:SI (match_operand:SI 1 "register_operand" "")
5735 (match_operand:SI 2 "general_operand" "")))
5736 (clobber (reg:CC 17))])]
5737 ""
5738 "")
5739
5740 (define_insn "*mulsi3_1"
5741 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5742 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
5743 (match_operand:SI 2 "general_operand" "K,i,mr")))
5744 (clobber (reg:CC 17))]
5745 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
5746 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
5747 ; there are two ways of writing the exact same machine instruction
5748 ; in assembly language. One, for example, is:
5749 ;
5750 ; imul $12, %eax
5751 ;
5752 ; while the other is:
5753 ;
5754 ; imul $12, %eax, %eax
5755 ;
5756 ; The first is simply short-hand for the latter. But, some assemblers,
5757 ; like the SCO OSR5 COFF assembler, don't handle the first form.
5758 "@
5759 imul{l}\\t{%2, %1, %0|%0, %1, %2}
5760 imul{l}\\t{%2, %1, %0|%0, %1, %2}
5761 imul{l}\\t{%2, %0|%0, %2}"
5762 [(set_attr "type" "imul")
5763 (set_attr "prefix_0f" "0,0,1")
5764 (set_attr "mode" "SI")])
5765
5766 (define_expand "mulhi3"
5767 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5768 (mult:HI (match_operand:HI 1 "register_operand" "")
5769 (match_operand:HI 2 "general_operand" "")))
5770 (clobber (reg:CC 17))])]
5771 "TARGET_HIMODE_MATH"
5772 "")
5773
5774 (define_insn "*mulhi3_1"
5775 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
5776 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
5777 (match_operand:HI 2 "general_operand" "K,i,mr")))
5778 (clobber (reg:CC 17))]
5779 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
5780 ; %%% There was a note about "Assembler has weird restrictions",
5781 ; concerning alternative 1 when op1 == op0. True?
5782 "@
5783 imul{w}\\t{%2, %1, %0|%0, %1, %2}
5784 imul{w}\\t{%2, %1, %0|%0, %1, %2}
5785 imul{w}\\t{%2, %0|%0, %2}"
5786 [(set_attr "type" "imul")
5787 (set_attr "prefix_0f" "0,0,1")
5788 (set_attr "mode" "HI")])
5789
5790 (define_insn "mulqi3"
5791 [(set (match_operand:QI 0 "register_operand" "=a")
5792 (mult:QI (match_operand:QI 1 "register_operand" "%0")
5793 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5794 (clobber (reg:CC 17))]
5795 "TARGET_QIMODE_MATH"
5796 "mul{b}\\t%2"
5797 [(set_attr "type" "imul")
5798 (set_attr "length_immediate" "0")
5799 (set_attr "mode" "QI")])
5800
5801 (define_insn "umulqihi3"
5802 [(set (match_operand:HI 0 "register_operand" "=a")
5803 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
5804 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5805 (clobber (reg:CC 17))]
5806 "TARGET_QIMODE_MATH"
5807 "mul{b}\\t%2"
5808 [(set_attr "type" "imul")
5809 (set_attr "length_immediate" "0")
5810 (set_attr "mode" "QI")])
5811
5812 (define_insn "mulqihi3"
5813 [(set (match_operand:HI 0 "register_operand" "=a")
5814 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
5815 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5816 (clobber (reg:CC 17))]
5817 "TARGET_QIMODE_MATH"
5818 "imul{b}\\t%2"
5819 [(set_attr "type" "imul")
5820 (set_attr "length_immediate" "0")
5821 (set_attr "mode" "QI")])
5822
5823 (define_insn "umulsidi3"
5824 [(set (match_operand:DI 0 "register_operand" "=A")
5825 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
5826 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5827 (clobber (reg:CC 17))]
5828 ""
5829 "mul{l}\\t%2"
5830 [(set_attr "type" "imul")
5831 (set_attr "ppro_uops" "few")
5832 (set_attr "length_immediate" "0")
5833 (set_attr "mode" "SI")])
5834
5835 (define_insn "mulsidi3"
5836 [(set (match_operand:DI 0 "register_operand" "=A")
5837 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
5838 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5839 (clobber (reg:CC 17))]
5840 ""
5841 "imul{l}\\t%2"
5842 [(set_attr "type" "imul")
5843 (set_attr "length_immediate" "0")
5844 (set_attr "mode" "SI")])
5845
5846 (define_insn "umulsi3_highpart"
5847 [(set (match_operand:SI 0 "register_operand" "=d")
5848 (truncate:SI
5849 (lshiftrt:DI
5850 (mult:DI (zero_extend:DI
5851 (match_operand:SI 1 "register_operand" "%a"))
5852 (zero_extend:DI
5853 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5854 (const_int 32))))
5855 (clobber (match_scratch:SI 3 "=a"))
5856 (clobber (reg:CC 17))]
5857 ""
5858 "mul{l}\\t%2"
5859 [(set_attr "type" "imul")
5860 (set_attr "ppro_uops" "few")
5861 (set_attr "length_immediate" "0")
5862 (set_attr "mode" "SI")])
5863
5864 (define_insn "smulsi3_highpart"
5865 [(set (match_operand:SI 0 "register_operand" "=d")
5866 (truncate:SI
5867 (lshiftrt:DI
5868 (mult:DI (sign_extend:DI
5869 (match_operand:SI 1 "register_operand" "%a"))
5870 (sign_extend:DI
5871 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5872 (const_int 32))))
5873 (clobber (match_scratch:SI 3 "=a"))
5874 (clobber (reg:CC 17))]
5875 ""
5876 "imul{l}\\t%2"
5877 [(set_attr "type" "imul")
5878 (set_attr "ppro_uops" "few")
5879 (set_attr "mode" "SI")])
5880
5881 ;; The patterns that match these are at the end of this file.
5882
5883 (define_expand "mulxf3"
5884 [(set (match_operand:XF 0 "register_operand" "")
5885 (mult:XF (match_operand:XF 1 "register_operand" "")
5886 (match_operand:XF 2 "register_operand" "")))]
5887 "TARGET_80387"
5888 "")
5889
5890 (define_expand "multf3"
5891 [(set (match_operand:TF 0 "register_operand" "")
5892 (mult:TF (match_operand:TF 1 "register_operand" "")
5893 (match_operand:TF 2 "register_operand" "")))]
5894 "TARGET_80387"
5895 "")
5896
5897 (define_expand "muldf3"
5898 [(set (match_operand:DF 0 "register_operand" "")
5899 (mult:DF (match_operand:DF 1 "register_operand" "")
5900 (match_operand:DF 2 "nonimmediate_operand" "")))]
5901 "TARGET_80387 || TARGET_SSE2"
5902 "")
5903
5904 (define_expand "mulsf3"
5905 [(set (match_operand:SF 0 "register_operand" "")
5906 (mult:SF (match_operand:SF 1 "register_operand" "")
5907 (match_operand:SF 2 "nonimmediate_operand" "")))]
5908 "TARGET_80387 || TARGET_SSE"
5909 "")
5910 \f
5911 ;; Divide instructions
5912
5913 (define_insn "divqi3"
5914 [(set (match_operand:QI 0 "register_operand" "=a")
5915 (div:QI (match_operand:HI 1 "register_operand" "0")
5916 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5917 (clobber (reg:CC 17))]
5918 "TARGET_QIMODE_MATH"
5919 "idiv{b}\\t%2"
5920 [(set_attr "type" "idiv")
5921 (set_attr "mode" "QI")
5922 (set_attr "ppro_uops" "few")])
5923
5924 (define_insn "udivqi3"
5925 [(set (match_operand:QI 0 "register_operand" "=a")
5926 (udiv:QI (match_operand:HI 1 "register_operand" "0")
5927 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5928 (clobber (reg:CC 17))]
5929 "TARGET_QIMODE_MATH"
5930 "div{b}\\t%2"
5931 [(set_attr "type" "idiv")
5932 (set_attr "mode" "QI")
5933 (set_attr "ppro_uops" "few")])
5934
5935 ;; The patterns that match these are at the end of this file.
5936
5937 (define_expand "divxf3"
5938 [(set (match_operand:XF 0 "register_operand" "")
5939 (div:XF (match_operand:XF 1 "register_operand" "")
5940 (match_operand:XF 2 "register_operand" "")))]
5941 "TARGET_80387"
5942 "")
5943
5944 (define_expand "divtf3"
5945 [(set (match_operand:TF 0 "register_operand" "")
5946 (div:TF (match_operand:TF 1 "register_operand" "")
5947 (match_operand:TF 2 "register_operand" "")))]
5948 "TARGET_80387"
5949 "")
5950
5951 (define_expand "divdf3"
5952 [(set (match_operand:DF 0 "register_operand" "")
5953 (div:DF (match_operand:DF 1 "register_operand" "")
5954 (match_operand:DF 2 "nonimmediate_operand" "")))]
5955 "TARGET_80387 || TARGET_SSE2"
5956 "")
5957
5958 (define_expand "divsf3"
5959 [(set (match_operand:SF 0 "register_operand" "")
5960 (div:SF (match_operand:SF 1 "register_operand" "")
5961 (match_operand:SF 2 "nonimmediate_operand" "")))]
5962 "TARGET_80387 || TARGET_SSE"
5963 "")
5964 \f
5965 ;; Remainder instructions.
5966 (define_expand "divmodsi4"
5967 [(parallel [(set (match_operand:SI 0 "register_operand" "")
5968 (div:SI (match_operand:SI 1 "register_operand" "")
5969 (match_operand:SI 2 "nonimmediate_operand" "")))
5970 (set (match_operand:SI 3 "register_operand" "")
5971 (mod:SI (match_dup 1) (match_dup 2)))
5972 (clobber (reg:CC 17))])]
5973 ""
5974 "")
5975
5976 ;; Allow to come the parameter in eax or edx to avoid extra moves.
5977 ;; Penalize eax case sligthly because it results in worse scheduling
5978 ;; of code.
5979 (define_insn "*divmodsi4_nocltd"
5980 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
5981 (div:SI (match_operand:SI 2 "register_operand" "1,0")
5982 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
5983 (set (match_operand:SI 1 "register_operand" "=&d,&d")
5984 (mod:SI (match_dup 2) (match_dup 3)))
5985 (clobber (reg:CC 17))]
5986 "!optimize_size && !TARGET_USE_CLTD"
5987 "#"
5988 [(set_attr "type" "multi")])
5989
5990 (define_insn "*divmodsi4_cltd"
5991 [(set (match_operand:SI 0 "register_operand" "=a")
5992 (div:SI (match_operand:SI 2 "register_operand" "a")
5993 (match_operand:SI 3 "nonimmediate_operand" "rm")))
5994 (set (match_operand:SI 1 "register_operand" "=&d")
5995 (mod:SI (match_dup 2) (match_dup 3)))
5996 (clobber (reg:CC 17))]
5997 "optimize_size || TARGET_USE_CLTD"
5998 "#"
5999 [(set_attr "type" "multi")])
6000
6001 (define_insn "*divmodsi_noext"
6002 [(set (match_operand:SI 0 "register_operand" "=a")
6003 (div:SI (match_operand:SI 1 "register_operand" "0")
6004 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6005 (set (match_operand:SI 3 "register_operand" "=d")
6006 (mod:SI (match_dup 1) (match_dup 2)))
6007 (use (match_operand:SI 4 "register_operand" "3"))
6008 (clobber (reg:CC 17))]
6009 ""
6010 "idiv{l}\\t%2"
6011 [(set_attr "type" "idiv")
6012 (set_attr "mode" "SI")
6013 (set_attr "ppro_uops" "few")])
6014
6015 (define_split
6016 [(set (match_operand:SI 0 "register_operand" "")
6017 (div:SI (match_operand:SI 1 "register_operand" "")
6018 (match_operand:SI 2 "nonimmediate_operand" "")))
6019 (set (match_operand:SI 3 "register_operand" "")
6020 (mod:SI (match_dup 1) (match_dup 2)))
6021 (clobber (reg:CC 17))]
6022 "reload_completed"
6023 [(parallel [(set (match_dup 3)
6024 (ashiftrt:SI (match_dup 4) (const_int 31)))
6025 (clobber (reg:CC 17))])
6026 (parallel [(set (match_dup 0)
6027 (div:SI (reg:SI 0) (match_dup 2)))
6028 (set (match_dup 3)
6029 (mod:SI (reg:SI 0) (match_dup 2)))
6030 (use (match_dup 3))
6031 (clobber (reg:CC 17))])]
6032 "
6033 {
6034 /* Avoid use of cltd in favour of a mov+shift. */
6035 if (!TARGET_USE_CLTD && !optimize_size)
6036 {
6037 if (true_regnum (operands[1]))
6038 emit_move_insn (operands[0], operands[1]);
6039 else
6040 emit_move_insn (operands[3], operands[1]);
6041 operands[4] = operands[3];
6042 }
6043 else
6044 {
6045 if (true_regnum (operands[1]))
6046 abort();
6047 operands[4] = operands[1];
6048 }
6049 }")
6050 ;; %%% Split me.
6051 (define_insn "divmodhi4"
6052 [(set (match_operand:HI 0 "register_operand" "=a")
6053 (div:HI (match_operand:HI 1 "register_operand" "0")
6054 (match_operand:HI 2 "nonimmediate_operand" "rm")))
6055 (set (match_operand:HI 3 "register_operand" "=&d")
6056 (mod:HI (match_dup 1) (match_dup 2)))
6057 (clobber (reg:CC 17))]
6058 "TARGET_HIMODE_MATH"
6059 "cwtd\;idiv{w}\\t%2"
6060 [(set_attr "type" "multi")
6061 (set_attr "length_immediate" "0")
6062 (set_attr "mode" "SI")])
6063
6064 (define_insn "udivmodsi4"
6065 [(set (match_operand:SI 0 "register_operand" "=a")
6066 (udiv:SI (match_operand:SI 1 "register_operand" "0")
6067 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6068 (set (match_operand:SI 3 "register_operand" "=&d")
6069 (umod:SI (match_dup 1) (match_dup 2)))
6070 (clobber (reg:CC 17))]
6071 ""
6072 "xor{l}\\t%3, %3\;div{l}\\t%2"
6073 [(set_attr "type" "multi")
6074 (set_attr "length_immediate" "0")
6075 (set_attr "mode" "SI")])
6076
6077 (define_insn "*udivmodsi4_noext"
6078 [(set (match_operand:SI 0 "register_operand" "=a")
6079 (udiv:SI (match_operand:SI 1 "register_operand" "0")
6080 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6081 (set (match_operand:SI 3 "register_operand" "=d")
6082 (umod:SI (match_dup 1) (match_dup 2)))
6083 (use (match_dup 3))
6084 (clobber (reg:CC 17))]
6085 ""
6086 "div{l}\\t%2"
6087 [(set_attr "type" "idiv")
6088 (set_attr "ppro_uops" "few")
6089 (set_attr "mode" "SI")])
6090
6091 (define_split
6092 [(set (match_operand:SI 0 "register_operand" "")
6093 (udiv:SI (match_operand:SI 1 "register_operand" "")
6094 (match_operand:SI 2 "nonimmediate_operand" "")))
6095 (set (match_operand:SI 3 "register_operand" "")
6096 (umod:SI (match_dup 1) (match_dup 2)))
6097 (clobber (reg:CC 17))]
6098 "reload_completed"
6099 [(set (match_dup 3) (const_int 0))
6100 (parallel [(set (match_dup 0)
6101 (udiv:SI (match_dup 1) (match_dup 2)))
6102 (set (match_dup 3)
6103 (umod:SI (match_dup 1) (match_dup 2)))
6104 (use (match_dup 3))
6105 (clobber (reg:CC 17))])]
6106 "")
6107
6108 (define_expand "udivmodhi4"
6109 [(set (match_dup 4) (const_int 0))
6110 (parallel [(set (match_operand:HI 0 "register_operand" "")
6111 (udiv:HI (match_operand:HI 1 "register_operand" "")
6112 (match_operand:HI 2 "nonimmediate_operand" "")))
6113 (set (match_operand:HI 3 "register_operand" "")
6114 (umod:HI (match_dup 1) (match_dup 2)))
6115 (use (match_dup 4))
6116 (clobber (reg:CC 17))])]
6117 "TARGET_HIMODE_MATH"
6118 "operands[4] = gen_reg_rtx (HImode);")
6119
6120 (define_insn "*udivmodhi_noext"
6121 [(set (match_operand:HI 0 "register_operand" "=a")
6122 (udiv:HI (match_operand:HI 1 "register_operand" "0")
6123 (match_operand:HI 2 "nonimmediate_operand" "rm")))
6124 (set (match_operand:HI 3 "register_operand" "=d")
6125 (umod:HI (match_dup 1) (match_dup 2)))
6126 (use (match_operand:HI 4 "register_operand" "3"))
6127 (clobber (reg:CC 17))]
6128 ""
6129 "div{w}\\t%2"
6130 [(set_attr "type" "idiv")
6131 (set_attr "mode" "HI")
6132 (set_attr "ppro_uops" "few")])
6133
6134 ;; We can not use div/idiv for double division, because it causes
6135 ;; "division by zero" on the overflow and that's not what we expect
6136 ;; from truncate. Because true (non truncating) double division is
6137 ;; never generated, we can't create this insn anyway.
6138 ;
6139 ;(define_insn ""
6140 ; [(set (match_operand:SI 0 "register_operand" "=a")
6141 ; (truncate:SI
6142 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
6143 ; (zero_extend:DI
6144 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
6145 ; (set (match_operand:SI 3 "register_operand" "=d")
6146 ; (truncate:SI
6147 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
6148 ; (clobber (reg:CC 17))]
6149 ; ""
6150 ; "div{l}\\t{%2, %0|%0, %2}"
6151 ; [(set_attr "type" "idiv")
6152 ; (set_attr "ppro_uops" "few")])
6153 \f
6154 ;;- Logical AND instructions
6155
6156 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
6157 ;; Note that this excludes ah.
6158
6159
6160 (define_insn "testsi_1"
6161 [(set (reg 17)
6162 (compare
6163 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
6164 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
6165 (const_int 0)))]
6166 "ix86_match_ccmode (insn, CCNOmode)"
6167 "test{l}\\t{%1, %0|%0, %1}"
6168 [(set_attr "type" "test")
6169 (set_attr "modrm" "0,1,1")
6170 (set_attr "mode" "SI")
6171 (set_attr "pent_pair" "uv,np,uv")])
6172
6173 (define_expand "testsi_ccno_1"
6174 [(set (reg:CCNO 17)
6175 (compare:CCNO
6176 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
6177 (match_operand:SI 1 "nonmemory_operand" ""))
6178 (const_int 0)))]
6179 ""
6180 "")
6181
6182 (define_insn "*testhi_1"
6183 [(set (reg 17)
6184 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
6185 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
6186 (const_int 0)))]
6187 "ix86_match_ccmode (insn, CCNOmode)"
6188 "test{w}\\t{%1, %0|%0, %1}"
6189 [(set_attr "type" "test")
6190 (set_attr "modrm" "0,1,1")
6191 (set_attr "mode" "HI")
6192 (set_attr "pent_pair" "uv,np,uv")])
6193
6194 (define_expand "testqi_ccz_1"
6195 [(set (reg:CCZ 17)
6196 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
6197 (match_operand:QI 1 "nonmemory_operand" ""))
6198 (const_int 0)))]
6199 ""
6200 "")
6201
6202 (define_insn "*testqi_1"
6203 [(set (reg 17)
6204 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
6205 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
6206 (const_int 0)))]
6207 "ix86_match_ccmode (insn, CCNOmode)"
6208 "*
6209 {
6210 if (which_alternative == 3)
6211 {
6212 if (GET_CODE (operands[1]) == CONST_INT
6213 && (INTVAL (operands[1]) & 0xffffff00))
6214 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
6215 return \"test{l}\\t{%1, %k0|%k0, %1}\";
6216 }
6217 return \"test{b}\\t{%1, %0|%0, %1}\";
6218 }"
6219 [(set_attr "type" "test")
6220 (set_attr "modrm" "0,1,1,1")
6221 (set_attr "mode" "QI,QI,QI,SI")
6222 (set_attr "pent_pair" "uv,np,uv,np")])
6223
6224 (define_expand "testqi_ext_ccno_0"
6225 [(set (reg:CCNO 17)
6226 (compare:CCNO
6227 (and:SI
6228 (zero_extract:SI
6229 (match_operand 0 "ext_register_operand" "")
6230 (const_int 8)
6231 (const_int 8))
6232 (match_operand 1 "const_int_operand" ""))
6233 (const_int 0)))]
6234 ""
6235 "")
6236
6237 (define_insn "*testqi_ext_0"
6238 [(set (reg 17)
6239 (compare
6240 (and:SI
6241 (zero_extract:SI
6242 (match_operand 0 "ext_register_operand" "q")
6243 (const_int 8)
6244 (const_int 8))
6245 (match_operand 1 "const_int_operand" "n"))
6246 (const_int 0)))]
6247 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
6248 && ix86_match_ccmode (insn, CCNOmode)"
6249 "test{b}\\t{%1, %h0|%h0, %1}"
6250 [(set_attr "type" "test")
6251 (set_attr "mode" "QI")
6252 (set_attr "length_immediate" "1")
6253 (set_attr "pent_pair" "np")])
6254
6255 (define_insn "*testqi_ext_1"
6256 [(set (reg 17)
6257 (compare
6258 (and:SI
6259 (zero_extract:SI
6260 (match_operand 0 "ext_register_operand" "q")
6261 (const_int 8)
6262 (const_int 8))
6263 (zero_extend:SI
6264 (match_operand:QI 1 "nonimmediate_operand" "qm")))
6265 (const_int 0)))]
6266 "ix86_match_ccmode (insn, CCNOmode)"
6267 "test{b}\\t{%1, %h0|%h0, %1}"
6268 [(set_attr "type" "test")
6269 (set_attr "mode" "QI")])
6270
6271 (define_insn "*testqi_ext_2"
6272 [(set (reg 17)
6273 (compare
6274 (and:SI
6275 (zero_extract:SI
6276 (match_operand 0 "ext_register_operand" "q")
6277 (const_int 8)
6278 (const_int 8))
6279 (zero_extract:SI
6280 (match_operand 1 "ext_register_operand" "q")
6281 (const_int 8)
6282 (const_int 8)))
6283 (const_int 0)))]
6284 "ix86_match_ccmode (insn, CCNOmode)"
6285 "test{b}\\t{%h1, %h0|%h0, %h1}"
6286 [(set_attr "type" "test")
6287 (set_attr "mode" "QI")])
6288
6289 ;; Combine likes to form bit extractions for some tests. Humor it.
6290 (define_insn "*testqi_ext_3"
6291 [(set (reg 17)
6292 (compare (zero_extract:SI
6293 (match_operand 0 "nonimmediate_operand" "rm")
6294 (match_operand:SI 1 "const_int_operand" "")
6295 (match_operand:SI 2 "const_int_operand" ""))
6296 (const_int 0)))]
6297 "ix86_match_ccmode (insn, CCNOmode)
6298 && (GET_MODE (operands[0]) == SImode
6299 || GET_MODE (operands[0]) == HImode
6300 || GET_MODE (operands[0]) == QImode)"
6301 "#")
6302
6303 (define_split
6304 [(set (reg 17)
6305 (compare (zero_extract:SI
6306 (match_operand 0 "nonimmediate_operand" "rm")
6307 (match_operand:SI 1 "const_int_operand" "")
6308 (match_operand:SI 2 "const_int_operand" ""))
6309 (const_int 0)))]
6310 "ix86_match_ccmode (insn, CCNOmode)"
6311 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
6312 "
6313 {
6314 HOST_WIDE_INT len = INTVAL (operands[1]);
6315 HOST_WIDE_INT pos = INTVAL (operands[2]);
6316 HOST_WIDE_INT mask;
6317 enum machine_mode mode;
6318
6319 mode = GET_MODE (operands[0]);
6320 if (GET_CODE (operands[0]) == MEM)
6321 {
6322 /* ??? Combine likes to put non-volatile mem extractions in QImode
6323 no matter the size of the test. So find a mode that works. */
6324 if (! MEM_VOLATILE_P (operands[0]))
6325 {
6326 mode = smallest_mode_for_size (pos + len, MODE_INT);
6327 operands[0] = change_address (operands[0], mode, NULL_RTX);
6328 }
6329 }
6330 else if (mode == HImode && pos + len <= 8)
6331 {
6332 /* Small HImode tests can be converted to QImode. */
6333 mode = QImode;
6334 operands[0] = gen_lowpart (QImode, operands[0]);
6335 }
6336
6337 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
6338 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
6339
6340 operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
6341 }")
6342
6343 ;; %%% This used to optimize known byte-wide and operations to memory,
6344 ;; and sometimes to QImode registers. If this is considered useful,
6345 ;; it should be done with splitters.
6346
6347 (define_expand "andsi3"
6348 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6349 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
6350 (match_operand:SI 2 "general_operand" "")))
6351 (clobber (reg:CC 17))]
6352 ""
6353 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
6354
6355 (define_insn "*andsi_1"
6356 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
6357 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
6358 (match_operand:SI 2 "general_operand" "ri,rm,L")))
6359 (clobber (reg:CC 17))]
6360 "ix86_binary_operator_ok (AND, SImode, operands)"
6361 "*
6362 {
6363 switch (get_attr_type (insn))
6364 {
6365 case TYPE_IMOVX:
6366 {
6367 enum machine_mode mode;
6368
6369 if (GET_CODE (operands[2]) != CONST_INT)
6370 abort ();
6371 if (INTVAL (operands[2]) == 0xff)
6372 mode = QImode;
6373 else if (INTVAL (operands[2]) == 0xffff)
6374 mode = HImode;
6375 else
6376 abort ();
6377
6378 operands[1] = gen_lowpart (mode, operands[1]);
6379 if (mode == QImode)
6380 return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
6381 else
6382 return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
6383 }
6384
6385 default:
6386 if (! rtx_equal_p (operands[0], operands[1]))
6387 abort ();
6388 return \"and{l}\\t{%2, %0|%0, %2}\";
6389 }
6390 }"
6391 [(set_attr "type" "alu,alu,imovx")
6392 (set_attr "length_immediate" "*,*,0")
6393 (set_attr "mode" "SI")])
6394
6395 (define_split
6396 [(set (match_operand:SI 0 "register_operand" "")
6397 (and:SI (match_dup 0)
6398 (const_int -65536)))
6399 (clobber (reg:CC 17))]
6400 "optimize_size"
6401 [(set (strict_low_part (match_dup 1)) (const_int 0))]
6402 "operands[1] = gen_lowpart (HImode, operands[0]);")
6403
6404 (define_split
6405 [(set (match_operand 0 "q_regs_operand" "")
6406 (and (match_dup 0)
6407 (const_int -256)))
6408 (clobber (reg:CC 17))]
6409 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6410 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6411 [(set (strict_low_part (match_dup 1)) (const_int 0))]
6412 "operands[1] = gen_lowpart (QImode, operands[0]);")
6413
6414 (define_split
6415 [(set (match_operand 0 "q_regs_operand" "")
6416 (and (match_dup 0)
6417 (const_int -65281)))
6418 (clobber (reg:CC 17))]
6419 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6420 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6421 [(parallel [(set (zero_extract:SI (match_dup 0)
6422 (const_int 8)
6423 (const_int 8))
6424 (xor:SI
6425 (zero_extract:SI (match_dup 0)
6426 (const_int 8)
6427 (const_int 8))
6428 (zero_extract:SI (match_dup 0)
6429 (const_int 8)
6430 (const_int 8))))
6431 (clobber (reg:CC 17))])]
6432 "operands[0] = gen_lowpart (SImode, operands[0]);")
6433
6434 (define_insn "*andsi_2"
6435 [(set (reg 17)
6436 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6437 (match_operand:SI 2 "general_operand" "rim,ri"))
6438 (const_int 0)))
6439 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6440 (and:SI (match_dup 1) (match_dup 2)))]
6441 "ix86_match_ccmode (insn, CCNOmode)
6442 && ix86_binary_operator_ok (AND, SImode, operands)"
6443 "and{l}\\t{%2, %0|%0, %2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "SI")])
6446
6447 (define_expand "andhi3"
6448 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6449 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
6450 (match_operand:HI 2 "general_operand" "")))
6451 (clobber (reg:CC 17))]
6452 "TARGET_HIMODE_MATH"
6453 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
6454
6455 (define_insn "*andhi_1"
6456 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6457 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
6458 (match_operand:HI 2 "general_operand" "ri,rm,L")))
6459 (clobber (reg:CC 17))]
6460 "ix86_binary_operator_ok (AND, HImode, operands)"
6461 "*
6462 {
6463 switch (get_attr_type (insn))
6464 {
6465 case TYPE_IMOVX:
6466 if (GET_CODE (operands[2]) != CONST_INT)
6467 abort ();
6468 if (INTVAL (operands[2]) == 0xff)
6469 return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
6470 abort ();
6471
6472 default:
6473 if (! rtx_equal_p (operands[0], operands[1]))
6474 abort ();
6475
6476 return \"and{w}\\t{%2, %0|%0, %2}\";
6477 }
6478 }"
6479 [(set_attr "type" "alu,alu,imovx")
6480 (set_attr "length_immediate" "*,*,0")
6481 (set_attr "mode" "HI,HI,SI")])
6482
6483 (define_insn "*andhi_2"
6484 [(set (reg 17)
6485 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6486 (match_operand:HI 2 "general_operand" "rim,ri"))
6487 (const_int 0)))
6488 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6489 (and:HI (match_dup 1) (match_dup 2)))]
6490 "ix86_match_ccmode (insn, CCNOmode)
6491 && ix86_binary_operator_ok (AND, HImode, operands)"
6492 "and{w}\\t{%2, %0|%0, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "mode" "HI")])
6495
6496 (define_expand "andqi3"
6497 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6498 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
6499 (match_operand:QI 2 "general_operand" "")))
6500 (clobber (reg:CC 17))]
6501 "TARGET_QIMODE_MATH"
6502 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
6503
6504 ;; %%% Potential partial reg stall on alternative 2. What to do?
6505 (define_insn "*andqi_1"
6506 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6507 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6508 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
6509 (clobber (reg:CC 17))]
6510 "ix86_binary_operator_ok (AND, QImode, operands)"
6511 "@
6512 and{b}\\t{%2, %0|%0, %2}
6513 and{b}\\t{%2, %0|%0, %2}
6514 and{l}\\t{%k2, %k0|%k0, %k2}"
6515 [(set_attr "type" "alu")
6516 (set_attr "mode" "QI,QI,SI")])
6517
6518 (define_insn "*andqi_1_slp"
6519 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6520 (and:QI (match_dup 0)
6521 (match_operand:QI 1 "general_operand" "qi,qmi")))
6522 (clobber (reg:CC 17))]
6523 ""
6524 "and{b}\\t{%1, %0|%0, %1}"
6525 [(set_attr "type" "alu1")
6526 (set_attr "mode" "QI")])
6527
6528 (define_insn "*andqi_2"
6529 [(set (reg 17)
6530 (compare (and:QI
6531 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6532 (match_operand:QI 2 "general_operand" "qim,qi,i"))
6533 (const_int 0)))
6534 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
6535 (and:QI (match_dup 1) (match_dup 2)))]
6536 "ix86_match_ccmode (insn, CCNOmode)
6537 && ix86_binary_operator_ok (AND, QImode, operands)"
6538 "*
6539 {
6540 if (which_alternative == 2)
6541 {
6542 if (GET_CODE (operands[2]) == CONST_INT
6543 && (INTVAL (operands[2]) & 0xffffff00))
6544 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
6545 return \"and{l}\\t{%2, %k0|%k0, %2}\";
6546 }
6547 return \"and{b}\\t{%2, %0|%0, %2}\";
6548 }"
6549 [(set_attr "type" "alu")
6550 (set_attr "mode" "QI,QI,SI")])
6551
6552 (define_insn "*andqi_2_slp"
6553 [(set (reg 17)
6554 (compare (and:QI
6555 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6556 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
6557 (const_int 0)))
6558 (set (strict_low_part (match_dup 0))
6559 (and:QI (match_dup 0) (match_dup 1)))]
6560 "ix86_match_ccmode (insn, CCNOmode)"
6561 "and{b}\\t{%1, %0|%0, %1}"
6562 [(set_attr "type" "alu1")
6563 (set_attr "mode" "QI")])
6564
6565 ;; ??? A bug in recog prevents it from recognizing a const_int as an
6566 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
6567 ;; for a QImode operand, which of course failed.
6568
6569 (define_insn "andqi_ext_0"
6570 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6571 (const_int 8)
6572 (const_int 8))
6573 (and:SI
6574 (zero_extract:SI
6575 (match_operand 1 "ext_register_operand" "0")
6576 (const_int 8)
6577 (const_int 8))
6578 (match_operand 2 "const_int_operand" "n")))
6579 (clobber (reg:CC 17))]
6580 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6581 "and{b}\\t{%2, %h0|%h0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "length_immediate" "1")
6584 (set_attr "mode" "QI")])
6585
6586 ;; Generated by peephole translating test to and. This shows up
6587 ;; often in fp comparisons.
6588
6589 (define_insn "*andqi_ext_0_cc"
6590 [(set (reg 17)
6591 (compare
6592 (and:SI
6593 (zero_extract:SI
6594 (match_operand 1 "ext_register_operand" "0")
6595 (const_int 8)
6596 (const_int 8))
6597 (match_operand 2 "const_int_operand" "n"))
6598 (const_int 0)))
6599 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6600 (const_int 8)
6601 (const_int 8))
6602 (and:SI
6603 (zero_extract:SI
6604 (match_dup 1)
6605 (const_int 8)
6606 (const_int 8))
6607 (match_dup 2)))]
6608 "ix86_match_ccmode (insn, CCNOmode)
6609 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6610 "and{b}\\t{%2, %h0|%h0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "length_immediate" "1")
6613 (set_attr "mode" "QI")])
6614
6615 (define_insn "*andqi_ext_1"
6616 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6617 (const_int 8)
6618 (const_int 8))
6619 (and:SI
6620 (zero_extract:SI
6621 (match_operand 1 "ext_register_operand" "0")
6622 (const_int 8)
6623 (const_int 8))
6624 (zero_extend:SI
6625 (match_operand:QI 2 "general_operand" "qm"))))
6626 (clobber (reg:CC 17))]
6627 ""
6628 "and{b}\\t{%2, %h0|%h0, %2}"
6629 [(set_attr "type" "alu")
6630 (set_attr "length_immediate" "0")
6631 (set_attr "mode" "QI")])
6632
6633 (define_insn "*andqi_ext_2"
6634 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6635 (const_int 8)
6636 (const_int 8))
6637 (and:SI
6638 (zero_extract:SI
6639 (match_operand 1 "ext_register_operand" "%0")
6640 (const_int 8)
6641 (const_int 8))
6642 (zero_extract:SI
6643 (match_operand 2 "ext_register_operand" "q")
6644 (const_int 8)
6645 (const_int 8))))
6646 (clobber (reg:CC 17))]
6647 ""
6648 "and{b}\\t{%h2, %h0|%h0, %h2}"
6649 [(set_attr "type" "alu")
6650 (set_attr "length_immediate" "0")
6651 (set_attr "mode" "QI")])
6652 \f
6653 ;; Logical inclusive OR instructions
6654
6655 ;; %%% This used to optimize known byte-wide and operations to memory.
6656 ;; If this is considered useful, it should be done with splitters.
6657
6658 (define_expand "iorsi3"
6659 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6660 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
6661 (match_operand:SI 2 "general_operand" "")))
6662 (clobber (reg:CC 17))]
6663 ""
6664 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
6665
6666 (define_insn "*iorsi_1"
6667 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6668 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6669 (match_operand:SI 2 "general_operand" "ri,rmi")))
6670 (clobber (reg:CC 17))]
6671 "ix86_binary_operator_ok (IOR, SImode, operands)"
6672 "or{l}\\t{%2, %0|%0, %2}"
6673 [(set_attr "type" "alu")
6674 (set_attr "mode" "SI")])
6675
6676 (define_insn "*iorsi_2"
6677 [(set (reg 17)
6678 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6679 (match_operand:SI 2 "general_operand" "rim,ri"))
6680 (const_int 0)))
6681 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6682 (ior:SI (match_dup 1) (match_dup 2)))]
6683 "ix86_match_ccmode (insn, CCNOmode)
6684 && ix86_binary_operator_ok (IOR, SImode, operands)"
6685 "or{l}\\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "mode" "SI")])
6688
6689 (define_insn "*iorsi_3"
6690 [(set (reg 17)
6691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6692 (match_operand:SI 2 "general_operand" "rim"))
6693 (const_int 0)))
6694 (clobber (match_scratch:SI 0 "=r"))]
6695 "ix86_match_ccmode (insn, CCNOmode)
6696 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6697 "or{l}\\t{%2, %0|%0, %2}"
6698 [(set_attr "type" "alu")
6699 (set_attr "mode" "SI")])
6700
6701 (define_expand "iorhi3"
6702 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6703 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
6704 (match_operand:HI 2 "general_operand" "")))
6705 (clobber (reg:CC 17))]
6706 "TARGET_HIMODE_MATH"
6707 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
6708
6709 (define_insn "*iorhi_1"
6710 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6711 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6712 (match_operand:HI 2 "general_operand" "rmi,ri")))
6713 (clobber (reg:CC 17))]
6714 "ix86_binary_operator_ok (IOR, HImode, operands)"
6715 "or{w}\\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "alu")
6717 (set_attr "mode" "HI")])
6718
6719 (define_insn "*iorhi_2"
6720 [(set (reg 17)
6721 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6722 (match_operand:HI 2 "general_operand" "rim,ri"))
6723 (const_int 0)))
6724 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6725 (ior:HI (match_dup 1) (match_dup 2)))]
6726 "ix86_match_ccmode (insn, CCNOmode)
6727 && ix86_binary_operator_ok (IOR, HImode, operands)"
6728 "or{w}\\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "HI")])
6731
6732 (define_insn "*iorhi_3"
6733 [(set (reg 17)
6734 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6735 (match_operand:HI 2 "general_operand" "rim"))
6736 (const_int 0)))
6737 (clobber (match_scratch:HI 0 "=r"))]
6738 "ix86_match_ccmode (insn, CCNOmode)
6739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6740 "or{w}\\t{%2, %0|%0, %2}"
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "HI")])
6743
6744 (define_expand "iorqi3"
6745 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6746 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
6747 (match_operand:QI 2 "general_operand" "")))
6748 (clobber (reg:CC 17))]
6749 "TARGET_QIMODE_MATH"
6750 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
6751
6752 ;; %%% Potential partial reg stall on alternative 2. What to do?
6753 (define_insn "*iorqi_1"
6754 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
6755 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6756 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
6757 (clobber (reg:CC 17))]
6758 "ix86_binary_operator_ok (IOR, QImode, operands)"
6759 "@
6760 or{b}\\t{%2, %0|%0, %2}
6761 or{b}\\t{%2, %0|%0, %2}
6762 or{l}\\t{%k2, %k0|%k0, %k2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "QI,QI,SI")])
6765
6766 (define_insn "*iorqi_1_slp"
6767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
6768 (ior:QI (match_dup 0)
6769 (match_operand:QI 1 "general_operand" "qmi,qi")))
6770 (clobber (reg:CC 17))]
6771 ""
6772 "or{b}\\t{%1, %0|%0, %1}"
6773 [(set_attr "type" "alu1")
6774 (set_attr "mode" "QI")])
6775
6776 (define_insn "*iorqi_2"
6777 [(set (reg 17)
6778 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6779 (match_operand:QI 2 "general_operand" "qim,qi"))
6780 (const_int 0)))
6781 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6782 (ior:QI (match_dup 1) (match_dup 2)))]
6783 "ix86_match_ccmode (insn, CCNOmode)
6784 && ix86_binary_operator_ok (IOR, QImode, operands)"
6785 "or{b}\\t{%2, %0|%0, %2}"
6786 [(set_attr "type" "alu")
6787 (set_attr "mode" "QI")])
6788
6789 (define_insn "*iorqi_2_slp"
6790 [(set (reg 17)
6791 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6792 (match_operand:QI 1 "general_operand" "qim,qi"))
6793 (const_int 0)))
6794 (set (strict_low_part (match_dup 0))
6795 (ior:QI (match_dup 0) (match_dup 1)))]
6796 "ix86_match_ccmode (insn, CCNOmode)"
6797 "or{b}\\t{%1, %0|%0, %1}"
6798 [(set_attr "type" "alu1")
6799 (set_attr "mode" "QI")])
6800
6801 (define_insn "*iorqi_3"
6802 [(set (reg 17)
6803 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6804 (match_operand:QI 2 "general_operand" "qim"))
6805 (const_int 0)))
6806 (clobber (match_scratch:QI 0 "=q"))]
6807 "ix86_match_ccmode (insn, CCNOmode)
6808 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6809 "or{b}\\t{%2, %0|%0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "mode" "QI")])
6812
6813 \f
6814 ;; Logical XOR instructions
6815
6816 ;; %%% This used to optimize known byte-wide and operations to memory.
6817 ;; If this is considered useful, it should be done with splitters.
6818
6819 (define_expand "xorsi3"
6820 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6821 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
6822 (match_operand:SI 2 "general_operand" "")))
6823 (clobber (reg:CC 17))]
6824 ""
6825 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
6826
6827 (define_insn "*xorsi_1"
6828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6829 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6830 (match_operand:SI 2 "general_operand" "ri,rm")))
6831 (clobber (reg:CC 17))]
6832 "ix86_binary_operator_ok (XOR, SImode, operands)"
6833 "xor{l}\\t{%2, %0|%0, %2}"
6834 [(set_attr "type" "alu")
6835 (set_attr "mode" "SI")])
6836
6837 (define_insn "*xorsi_2"
6838 [(set (reg 17)
6839 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6840 (match_operand:SI 2 "general_operand" "rim,ri"))
6841 (const_int 0)))
6842 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6843 (xor:SI (match_dup 1) (match_dup 2)))]
6844 "ix86_match_ccmode (insn, CCNOmode)
6845 && ix86_binary_operator_ok (XOR, SImode, operands)"
6846 "xor{l}\\t{%2, %0|%0, %2}"
6847 [(set_attr "type" "alu")
6848 (set_attr "mode" "SI")])
6849
6850 (define_insn "*xorsi_3"
6851 [(set (reg 17)
6852 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6853 (match_operand:SI 2 "general_operand" "rim"))
6854 (const_int 0)))
6855 (clobber (match_scratch:SI 0 "=r"))]
6856 "ix86_match_ccmode (insn, CCNOmode)
6857 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6858 "xor{l}\\t{%2, %0|%0, %2}"
6859 [(set_attr "type" "alu")
6860 (set_attr "mode" "SI")])
6861
6862 (define_expand "xorhi3"
6863 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6864 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
6865 (match_operand:HI 2 "general_operand" "")))
6866 (clobber (reg:CC 17))]
6867 "TARGET_HIMODE_MATH"
6868 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
6869
6870 (define_insn "*xorhi_1"
6871 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6872 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6873 (match_operand:HI 2 "general_operand" "rmi,ri")))
6874 (clobber (reg:CC 17))]
6875 "ix86_binary_operator_ok (XOR, HImode, operands)"
6876 "xor{w}\\t{%2, %0|%0, %2}"
6877 [(set_attr "type" "alu")
6878 (set_attr "mode" "HI")])
6879
6880 (define_insn "*xorhi_2"
6881 [(set (reg 17)
6882 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6883 (match_operand:HI 2 "general_operand" "rim,ri"))
6884 (const_int 0)))
6885 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6886 (xor:HI (match_dup 1) (match_dup 2)))]
6887 "ix86_match_ccmode (insn, CCNOmode)
6888 && ix86_binary_operator_ok (XOR, HImode, operands)"
6889 "xor{w}\\t{%2, %0|%0, %2}"
6890 [(set_attr "type" "alu")
6891 (set_attr "mode" "HI")])
6892
6893 (define_insn "*xorhi_3"
6894 [(set (reg 17)
6895 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6896 (match_operand:HI 2 "general_operand" "rim"))
6897 (const_int 0)))
6898 (clobber (match_scratch:HI 0 "=r"))]
6899 "ix86_match_ccmode (insn, CCNOmode)
6900 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6901 "xor{w}\\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "mode" "HI")])
6904
6905 (define_expand "xorqi3"
6906 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6907 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
6908 (match_operand:QI 2 "general_operand" "")))
6909 (clobber (reg:CC 17))]
6910 "TARGET_QIMODE_MATH"
6911 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
6912
6913 ;; %%% Potential partial reg stall on alternative 2. What to do?
6914 (define_insn "*xorqi_1"
6915 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
6916 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6917 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
6918 (clobber (reg:CC 17))]
6919 "ix86_binary_operator_ok (XOR, QImode, operands)"
6920 "@
6921 xor{b}\\t{%2, %0|%0, %2}
6922 xor{b}\\t{%2, %0|%0, %2}
6923 xor{l}\\t{%k2, %k0|%k0, %k2}"
6924 [(set_attr "type" "alu")
6925 (set_attr "mode" "QI,QI,SI")])
6926
6927 (define_insn "*xorqi_ext_1"
6928 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6929 (const_int 8)
6930 (const_int 8))
6931 (xor:SI
6932 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
6933 (const_int 8)
6934 (const_int 8))
6935 (zero_extract:SI (match_operand 2 "ext_register_operand" "q")
6936 (const_int 8)
6937 (const_int 8))))
6938 (clobber (reg:CC 17))]
6939 ""
6940 "xor{b}\\t{%h2, %h0|%h0, %h2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "length_immediate" "0")
6943 (set_attr "mode" "QI")])
6944
6945 (define_insn "*xorqi_cc_1"
6946 [(set (reg 17)
6947 (compare
6948 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6949 (match_operand:QI 2 "general_operand" "qim,qi"))
6950 (const_int 0)))
6951 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6952 (xor:QI (match_dup 1) (match_dup 2)))]
6953 "ix86_match_ccmode (insn, CCNOmode)
6954 && ix86_binary_operator_ok (XOR, QImode, operands)"
6955 "xor{b}\\t{%2, %0|%0, %2}"
6956 [(set_attr "type" "alu")
6957 (set_attr "mode" "QI")])
6958
6959 (define_insn "*xorqi_cc_2"
6960 [(set (reg 17)
6961 (compare
6962 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6963 (match_operand:QI 2 "general_operand" "qim"))
6964 (const_int 0)))
6965 (clobber (match_scratch:QI 0 "=q"))]
6966 "ix86_match_ccmode (insn, CCNOmode)
6967 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6968 "xor{b}\\t{%2, %0|%0, %2}"
6969 [(set_attr "type" "alu")
6970 (set_attr "mode" "QI")])
6971
6972 (define_insn "*xorqi_cc_ext_1"
6973 [(set (reg 17)
6974 (compare
6975 (xor:SI
6976 (zero_extract:SI
6977 (match_operand 1 "ext_register_operand" "0")
6978 (const_int 8)
6979 (const_int 8))
6980 (match_operand:QI 2 "general_operand" "qmn"))
6981 (const_int 0)))
6982 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6983 (const_int 8)
6984 (const_int 8))
6985 (xor:SI
6986 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
6987 (match_dup 2)))]
6988 "ix86_match_ccmode (insn, CCNOmode)"
6989 "xor{b}\\t{%2, %h0|%h0, %2}"
6990 [(set_attr "type" "alu")
6991 (set_attr "mode" "QI")])
6992
6993 (define_expand "xorqi_cc_ext_1"
6994 [(parallel [
6995 (set (reg:CCNO 17)
6996 (compare:CCNO
6997 (xor:SI
6998 (zero_extract:SI
6999 (match_operand 1 "ext_register_operand" "")
7000 (const_int 8)
7001 (const_int 8))
7002 (match_operand:QI 2 "general_operand" ""))
7003 (const_int 0)))
7004 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
7005 (const_int 8)
7006 (const_int 8))
7007 (xor:SI
7008 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
7009 (match_dup 2)))])]
7010 ""
7011 "")
7012 \f
7013 ;; Negation instructions
7014
7015 ;; %%% define_expand from the very first?
7016
7017 (define_expand "negdi2"
7018 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7019 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
7020 (clobber (reg:CC 17))])]
7021 ""
7022 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
7023
7024 (define_insn "*negdi2_1"
7025 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
7026 (neg:DI (match_operand:DI 1 "general_operand" "0")))
7027 (clobber (reg:CC 17))]
7028 "ix86_unary_operator_ok (NEG, DImode, operands)"
7029 "#")
7030
7031 (define_split
7032 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7033 (neg:DI (match_operand:DI 1 "general_operand" "")))
7034 (clobber (reg:CC 17))]
7035 "reload_completed"
7036 [(parallel
7037 [(set (reg:CCZ 17)
7038 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
7039 (set (match_dup 0) (neg:SI (match_dup 2)))])
7040 (parallel
7041 [(set (match_dup 1)
7042 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7043 (match_dup 3))
7044 (const_int 0)))
7045 (clobber (reg:CC 17))])
7046 (parallel
7047 [(set (match_dup 1)
7048 (neg:SI (match_dup 1)))
7049 (clobber (reg:CC 17))])]
7050 "split_di (operands+1, 1, operands+2, operands+3);
7051 split_di (operands+0, 1, operands+0, operands+1);")
7052
7053 (define_expand "negsi2"
7054 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7055 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
7056 (clobber (reg:CC 17))])]
7057 ""
7058 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
7059
7060 (define_insn "*negsi2_1"
7061 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7062 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
7063 (clobber (reg:CC 17))]
7064 "ix86_unary_operator_ok (NEG, SImode, operands)"
7065 "neg{l}\\t%0"
7066 [(set_attr "type" "negnot")
7067 (set_attr "mode" "SI")])
7068
7069 ;; The problem with neg is that it does not perform (compare x 0),
7070 ;; it really performs (compare 0 x), which leaves us with the zero
7071 ;; flag being the only useful item.
7072
7073 (define_insn "*negsi2_cmpz"
7074 [(set (reg:CCZ 17)
7075 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7076 (const_int 0)))
7077 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7078 (neg:SI (match_dup 1)))]
7079 "ix86_unary_operator_ok (NEG, SImode, operands)"
7080 "neg{l}\\t%0"
7081 [(set_attr "type" "negnot")
7082 (set_attr "mode" "SI")])
7083
7084 (define_expand "neghi2"
7085 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7086 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
7087 (clobber (reg:CC 17))])]
7088 "TARGET_HIMODE_MATH"
7089 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
7090
7091 (define_insn "*neghi2_1"
7092 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7093 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
7094 (clobber (reg:CC 17))]
7095 "ix86_unary_operator_ok (NEG, HImode, operands)"
7096 "neg{w}\\t%0"
7097 [(set_attr "type" "negnot")
7098 (set_attr "mode" "HI")])
7099
7100 (define_insn "*neghi2_cmpz"
7101 [(set (reg:CCZ 17)
7102 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7103 (const_int 0)))
7104 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7105 (neg:HI (match_dup 1)))]
7106 "ix86_unary_operator_ok (NEG, HImode, operands)"
7107 "neg{w}\\t%0"
7108 [(set_attr "type" "negnot")
7109 (set_attr "mode" "HI")])
7110
7111 (define_expand "negqi2"
7112 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7113 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
7114 (clobber (reg:CC 17))])]
7115 "TARGET_QIMODE_MATH"
7116 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
7117
7118 (define_insn "*negqi2_1"
7119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7120 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
7121 (clobber (reg:CC 17))]
7122 "ix86_unary_operator_ok (NEG, QImode, operands)"
7123 "neg{b}\\t%0"
7124 [(set_attr "type" "negnot")
7125 (set_attr "mode" "QI")])
7126
7127 (define_insn "*negqi2_cmpz"
7128 [(set (reg:CCZ 17)
7129 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
7130 (const_int 0)))
7131 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7132 (neg:QI (match_dup 1)))]
7133 "ix86_unary_operator_ok (NEG, QImode, operands)"
7134 "neg{b}\\t%0"
7135 [(set_attr "type" "negnot")
7136 (set_attr "mode" "QI")])
7137
7138 ;; Changing of sign for FP values is doable using integer unit too.
7139
7140 (define_expand "negsf2"
7141 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
7142 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
7143 (clobber (reg:CC 17))])]
7144 "TARGET_80387"
7145 "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
7146
7147 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7148 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7149 ;; to itself.
7150 (define_insn "*negsf2_if"
7151 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7152 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
7153 (clobber (reg:CC 17))]
7154 "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
7155 "#")
7156
7157 (define_split
7158 [(set (match_operand:SF 0 "register_operand" "")
7159 (neg:SF (match_operand:SF 1 "register_operand" "")))
7160 (clobber (reg:CC 17))]
7161 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7162 [(set (match_dup 0)
7163 (neg:SF (match_dup 1)))]
7164 "")
7165
7166 (define_split
7167 [(set (match_operand:SF 0 "register_operand" "")
7168 (neg:SF (match_operand:SF 1 "register_operand" "")))
7169 (clobber (reg:CC 17))]
7170 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7171 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7172 (clobber (reg:CC 17))])]
7173 "operands[1] = GEN_INT (0x80000000);
7174 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7175
7176 (define_split
7177 [(set (match_operand 0 "memory_operand" "")
7178 (neg (match_operand 1 "memory_operand" "")))
7179 (clobber (reg:CC 17))]
7180 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7181 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7182 (clobber (reg:CC 17))])]
7183 "
7184 {
7185 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7186
7187 /* XFmode's size is 12, but only 10 bytes are used. */
7188 if (size == 12)
7189 size = 10;
7190 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7191 operands[0] = adj_offsettable_operand (operands[0], size - 1);
7192 operands[1] = GEN_INT (0x80);
7193 }")
7194
7195 (define_expand "negdf2"
7196 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
7197 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
7198 (clobber (reg:CC 17))])]
7199 "TARGET_80387"
7200 "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
7201
7202 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7203 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7204 ;; to itself.
7205 (define_insn "*negdf2_if"
7206 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7207 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
7208 (clobber (reg:CC 17))]
7209 "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
7210 "#")
7211
7212 (define_split
7213 [(set (match_operand:DF 0 "register_operand" "")
7214 (neg:DF (match_operand:DF 1 "register_operand" "")))
7215 (clobber (reg:CC 17))]
7216 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7217 [(set (match_dup 0)
7218 (neg:DF (match_dup 1)))]
7219 "")
7220
7221 (define_split
7222 [(set (match_operand:DF 0 "register_operand" "")
7223 (neg:DF (match_operand:DF 1 "register_operand" "")))
7224 (clobber (reg:CC 17))]
7225 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7226 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
7227 (clobber (reg:CC 17))])]
7228 "operands[4] = GEN_INT (0x80000000);
7229 split_di (operands+0, 1, operands+2, operands+3);")
7230
7231 (define_expand "negxf2"
7232 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
7233 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
7234 (clobber (reg:CC 17))])]
7235 "TARGET_80387"
7236 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
7237
7238 (define_expand "negtf2"
7239 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7240 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7241 (clobber (reg:CC 17))])]
7242 "TARGET_80387"
7243 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
7244
7245 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7246 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7247 ;; to itself.
7248 (define_insn "*negxf2_if"
7249 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7250 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
7251 (clobber (reg:CC 17))]
7252 "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
7253 "#")
7254
7255 (define_split
7256 [(set (match_operand:XF 0 "register_operand" "")
7257 (neg:XF (match_operand:XF 1 "register_operand" "")))
7258 (clobber (reg:CC 17))]
7259 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7260 [(set (match_dup 0)
7261 (neg:XF (match_dup 1)))]
7262 "")
7263
7264 (define_split
7265 [(set (match_operand:XF 0 "register_operand" "")
7266 (neg:XF (match_operand:XF 1 "register_operand" "")))
7267 (clobber (reg:CC 17))]
7268 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7269 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7270 (clobber (reg:CC 17))])]
7271 "operands[1] = GEN_INT (0x8000);
7272 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7273
7274 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7275 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7276 ;; to itself.
7277 (define_insn "*negtf2_if"
7278 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7279 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7280 (clobber (reg:CC 17))]
7281 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
7282 "#")
7283
7284 (define_split
7285 [(set (match_operand:TF 0 "register_operand" "")
7286 (neg:TF (match_operand:TF 1 "register_operand" "")))
7287 (clobber (reg:CC 17))]
7288 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7289 [(set (match_dup 0)
7290 (neg:TF (match_dup 1)))]
7291 "")
7292
7293 (define_split
7294 [(set (match_operand:TF 0 "register_operand" "")
7295 (neg:TF (match_operand:TF 1 "register_operand" "")))
7296 (clobber (reg:CC 17))]
7297 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7298 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7299 (clobber (reg:CC 17))])]
7300 "operands[1] = GEN_INT (0x8000);
7301 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7302
7303 ;; Conditionize these after reload. If they matches before reload, we
7304 ;; lose the clobber and ability to use integer instructions.
7305
7306 (define_insn "*negsf2_1"
7307 [(set (match_operand:SF 0 "register_operand" "=f")
7308 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
7309 "TARGET_80387 && reload_completed"
7310 "fchs"
7311 [(set_attr "type" "fsgn")
7312 (set_attr "mode" "SF")
7313 (set_attr "ppro_uops" "few")])
7314
7315 (define_insn "*negdf2_1"
7316 [(set (match_operand:DF 0 "register_operand" "=f")
7317 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
7318 "TARGET_80387 && reload_completed"
7319 "fchs"
7320 [(set_attr "type" "fsgn")
7321 (set_attr "mode" "DF")
7322 (set_attr "ppro_uops" "few")])
7323
7324 (define_insn "*negextendsfdf2"
7325 [(set (match_operand:DF 0 "register_operand" "=f")
7326 (neg:DF (float_extend:DF
7327 (match_operand:SF 1 "register_operand" "0"))))]
7328 "TARGET_80387"
7329 "fchs"
7330 [(set_attr "type" "fsgn")
7331 (set_attr "mode" "DF")
7332 (set_attr "ppro_uops" "few")])
7333
7334 (define_insn "*negxf2_1"
7335 [(set (match_operand:XF 0 "register_operand" "=f")
7336 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
7337 "TARGET_80387 && reload_completed"
7338 "fchs"
7339 [(set_attr "type" "fsgn")
7340 (set_attr "mode" "XF")
7341 (set_attr "ppro_uops" "few")])
7342
7343 (define_insn "*negextenddfxf2"
7344 [(set (match_operand:XF 0 "register_operand" "=f")
7345 (neg:XF (float_extend:XF
7346 (match_operand:DF 1 "register_operand" "0"))))]
7347 "TARGET_80387"
7348 "fchs"
7349 [(set_attr "type" "fsgn")
7350 (set_attr "mode" "XF")
7351 (set_attr "ppro_uops" "few")])
7352
7353 (define_insn "*negextendsfxf2"
7354 [(set (match_operand:XF 0 "register_operand" "=f")
7355 (neg:XF (float_extend:XF
7356 (match_operand:SF 1 "register_operand" "0"))))]
7357 "TARGET_80387"
7358 "fchs"
7359 [(set_attr "type" "fsgn")
7360 (set_attr "mode" "XF")
7361 (set_attr "ppro_uops" "few")])
7362
7363 (define_insn "*negtf2_1"
7364 [(set (match_operand:TF 0 "register_operand" "=f")
7365 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
7366 "TARGET_80387 && reload_completed"
7367 "fchs"
7368 [(set_attr "type" "fsgn")
7369 (set_attr "mode" "XF")
7370 (set_attr "ppro_uops" "few")])
7371
7372 (define_insn "*negextenddftf2"
7373 [(set (match_operand:TF 0 "register_operand" "=f")
7374 (neg:TF (float_extend:TF
7375 (match_operand:DF 1 "register_operand" "0"))))]
7376 "TARGET_80387"
7377 "fchs"
7378 [(set_attr "type" "fsgn")
7379 (set_attr "mode" "XF")
7380 (set_attr "ppro_uops" "few")])
7381
7382 (define_insn "*negextendsftf2"
7383 [(set (match_operand:TF 0 "register_operand" "=f")
7384 (neg:TF (float_extend:TF
7385 (match_operand:SF 1 "register_operand" "0"))))]
7386 "TARGET_80387"
7387 "fchs"
7388 [(set_attr "type" "fsgn")
7389 (set_attr "mode" "XF")
7390 (set_attr "ppro_uops" "few")])
7391 \f
7392 ;; Absolute value instructions
7393
7394 (define_expand "abssf2"
7395 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
7396 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
7397 (clobber (reg:CC 17))])]
7398 "TARGET_80387"
7399 "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
7400
7401 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7402 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7403 ;; to itself.
7404 (define_insn "*abssf2_if"
7405 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7406 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
7407 (clobber (reg:CC 17))]
7408 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
7409 "#")
7410
7411 (define_split
7412 [(set (match_operand:SF 0 "register_operand" "")
7413 (abs:SF (match_operand:SF 1 "register_operand" "")))
7414 (clobber (reg:CC 17))]
7415 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
7416 [(set (match_dup 0)
7417 (abs:SF (match_dup 1)))]
7418 "")
7419
7420 (define_split
7421 [(set (match_operand:SF 0 "register_operand" "")
7422 (abs:SF (match_operand:SF 1 "register_operand" "")))
7423 (clobber (reg:CC 17))]
7424 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7425 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7426 (clobber (reg:CC 17))])]
7427 "operands[1] = GEN_INT (~0x80000000);
7428 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7429
7430 (define_split
7431 [(set (match_operand 0 "memory_operand" "")
7432 (abs (match_operand 1 "memory_operand" "")))
7433 (clobber (reg:CC 17))]
7434 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7435 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7436 (clobber (reg:CC 17))])]
7437 "
7438 {
7439 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7440
7441 /* XFmode's size is 12, but only 10 bytes are used. */
7442 if (size == 12)
7443 size = 10;
7444 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7445 operands[0] = adj_offsettable_operand (operands[0], size - 1);
7446 operands[1] = GEN_INT (~0x80);
7447 }")
7448
7449 (define_expand "absdf2"
7450 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
7451 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
7452 (clobber (reg:CC 17))])]
7453 "TARGET_80387"
7454 "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
7455
7456 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7457 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7458 ;; to itself.
7459 (define_insn "*absdf2_if"
7460 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7461 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
7462 (clobber (reg:CC 17))]
7463 "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
7464 "#")
7465
7466 (define_split
7467 [(set (match_operand:DF 0 "register_operand" "")
7468 (abs:DF (match_operand:DF 1 "register_operand" "")))
7469 (clobber (reg:CC 17))]
7470 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7471 [(set (match_dup 0)
7472 (abs:DF (match_dup 1)))]
7473 "")
7474
7475 (define_split
7476 [(set (match_operand:DF 0 "register_operand" "")
7477 (abs:DF (match_operand:DF 1 "register_operand" "")))
7478 (clobber (reg:CC 17))]
7479 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7480 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
7481 (clobber (reg:CC 17))])]
7482 "operands[4] = GEN_INT (~0x80000000);
7483 split_di (operands+0, 1, operands+2, operands+3);")
7484
7485 (define_expand "absxf2"
7486 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
7487 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
7488 (clobber (reg:CC 17))])]
7489 "TARGET_80387"
7490 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
7491
7492 (define_expand "abstf2"
7493 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7494 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7495 (clobber (reg:CC 17))])]
7496 "TARGET_80387"
7497 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
7498
7499 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7500 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7501 ;; to itself.
7502 (define_insn "*absxf2_if"
7503 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7504 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
7505 (clobber (reg:CC 17))]
7506 "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
7507 "#")
7508
7509 (define_split
7510 [(set (match_operand:XF 0 "register_operand" "")
7511 (abs:XF (match_operand:XF 1 "register_operand" "")))
7512 (clobber (reg:CC 17))]
7513 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7514 [(set (match_dup 0)
7515 (abs:XF (match_dup 1)))]
7516 "")
7517
7518 (define_split
7519 [(set (match_operand:XF 0 "register_operand" "")
7520 (abs:XF (match_operand:XF 1 "register_operand" "")))
7521 (clobber (reg:CC 17))]
7522 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7523 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7524 (clobber (reg:CC 17))])]
7525 "operands[1] = GEN_INT (~0x8000);
7526 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7527
7528 (define_insn "*abstf2_if"
7529 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7530 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7531 (clobber (reg:CC 17))]
7532 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
7533 "#")
7534
7535 (define_split
7536 [(set (match_operand:TF 0 "register_operand" "")
7537 (abs:TF (match_operand:TF 1 "register_operand" "")))
7538 (clobber (reg:CC 17))]
7539 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7540 [(set (match_dup 0)
7541 (abs:TF (match_dup 1)))]
7542 "")
7543
7544 (define_split
7545 [(set (match_operand:TF 0 "register_operand" "")
7546 (abs:TF (match_operand:TF 1 "register_operand" "")))
7547 (clobber (reg:CC 17))]
7548 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7549 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7550 (clobber (reg:CC 17))])]
7551 "operands[1] = GEN_INT (~0x8000);
7552 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7553
7554 (define_insn "*abssf2_1"
7555 [(set (match_operand:SF 0 "register_operand" "=f")
7556 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
7557 "TARGET_80387 && reload_completed"
7558 "fabs"
7559 [(set_attr "type" "fsgn")
7560 (set_attr "mode" "SF")])
7561
7562 (define_insn "*absdf2_1"
7563 [(set (match_operand:DF 0 "register_operand" "=f")
7564 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
7565 "TARGET_80387 && reload_completed"
7566 "fabs"
7567 [(set_attr "type" "fsgn")
7568 (set_attr "mode" "DF")])
7569
7570 (define_insn "*absextendsfdf2"
7571 [(set (match_operand:DF 0 "register_operand" "=f")
7572 (abs:DF (float_extend:DF
7573 (match_operand:SF 1 "register_operand" "0"))))]
7574 "TARGET_80387"
7575 "fabs"
7576 [(set_attr "type" "fsgn")
7577 (set_attr "mode" "DF")])
7578
7579 (define_insn "*absxf2_1"
7580 [(set (match_operand:XF 0 "register_operand" "=f")
7581 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
7582 "TARGET_80387 && reload_completed"
7583 "fabs"
7584 [(set_attr "type" "fsgn")
7585 (set_attr "mode" "DF")])
7586
7587 (define_insn "*absextenddfxf2"
7588 [(set (match_operand:XF 0 "register_operand" "=f")
7589 (abs:XF (float_extend:XF
7590 (match_operand:DF 1 "register_operand" "0"))))]
7591 "TARGET_80387"
7592 "fabs"
7593 [(set_attr "type" "fsgn")
7594 (set_attr "mode" "XF")])
7595
7596 (define_insn "*absextendsfxf2"
7597 [(set (match_operand:XF 0 "register_operand" "=f")
7598 (abs:XF (float_extend:XF
7599 (match_operand:SF 1 "register_operand" "0"))))]
7600 "TARGET_80387"
7601 "fabs"
7602 [(set_attr "type" "fsgn")
7603 (set_attr "mode" "XF")])
7604
7605 (define_insn "*abstf2_1"
7606 [(set (match_operand:TF 0 "register_operand" "=f")
7607 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
7608 "TARGET_80387 && reload_completed"
7609 "fabs"
7610 [(set_attr "type" "fsgn")
7611 (set_attr "mode" "DF")])
7612
7613 (define_insn "*absextenddftf2"
7614 [(set (match_operand:TF 0 "register_operand" "=f")
7615 (abs:TF (float_extend:TF
7616 (match_operand:DF 1 "register_operand" "0"))))]
7617 "TARGET_80387"
7618 "fabs"
7619 [(set_attr "type" "fsgn")
7620 (set_attr "mode" "XF")])
7621
7622 (define_insn "*absextendsftf2"
7623 [(set (match_operand:TF 0 "register_operand" "=f")
7624 (abs:TF (float_extend:TF
7625 (match_operand:SF 1 "register_operand" "0"))))]
7626 "TARGET_80387"
7627 "fabs"
7628 [(set_attr "type" "fsgn")
7629 (set_attr "mode" "XF")])
7630 \f
7631 ;; One complement instructions
7632
7633 (define_expand "one_cmplsi2"
7634 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7635 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
7636 ""
7637 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
7638
7639 (define_insn "*one_cmplsi2_1"
7640 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7641 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
7642 "ix86_unary_operator_ok (NOT, SImode, operands)"
7643 "not{l}\\t%0"
7644 [(set_attr "type" "negnot")
7645 (set_attr "mode" "SI")])
7646
7647 (define_insn "*one_cmplsi2_2"
7648 [(set (reg 17)
7649 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7650 (const_int 0)))
7651 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7652 (not:SI (match_dup 1)))]
7653 "ix86_match_ccmode (insn, CCNOmode)
7654 && ix86_unary_operator_ok (NOT, SImode, operands)"
7655 "#"
7656 [(set_attr "type" "alu1")
7657 (set_attr "mode" "SI")])
7658
7659 (define_split
7660 [(set (reg 17)
7661 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
7662 (const_int 0)))
7663 (set (match_operand:SI 0 "nonimmediate_operand" "")
7664 (not:SI (match_dup 1)))]
7665 "ix86_match_ccmode (insn, CCNOmode)"
7666 [(parallel [(set (reg:CCNO 17)
7667 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
7668 (const_int 0)))
7669 (set (match_dup 0)
7670 (xor:SI (match_dup 1) (const_int -1)))])]
7671 "")
7672
7673 (define_expand "one_cmplhi2"
7674 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7675 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
7676 "TARGET_HIMODE_MATH"
7677 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
7678
7679 (define_insn "*one_cmplhi2_1"
7680 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7681 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
7682 "ix86_unary_operator_ok (NOT, HImode, operands)"
7683 "not{w}\\t%0"
7684 [(set_attr "type" "negnot")
7685 (set_attr "mode" "HI")])
7686
7687 (define_insn "*one_cmplhi2_2"
7688 [(set (reg 17)
7689 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7690 (const_int 0)))
7691 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7692 (not:HI (match_dup 1)))]
7693 "ix86_match_ccmode (insn, CCNOmode)
7694 && ix86_unary_operator_ok (NEG, HImode, operands)"
7695 "#"
7696 [(set_attr "type" "alu1")
7697 (set_attr "mode" "HI")])
7698
7699 (define_split
7700 [(set (reg 17)
7701 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
7702 (const_int 0)))
7703 (set (match_operand:HI 0 "nonimmediate_operand" "")
7704 (not:HI (match_dup 1)))]
7705 "ix86_match_ccmode (insn, CCNOmode)"
7706 [(parallel [(set (reg:CCNO 17)
7707 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
7708 (const_int 0)))
7709 (set (match_dup 0)
7710 (xor:HI (match_dup 1) (const_int -1)))])]
7711 "")
7712
7713 ;; %%% Potential partial reg stall on alternative 1. What to do?
7714 (define_expand "one_cmplqi2"
7715 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7716 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
7717 "TARGET_QIMODE_MATH"
7718 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
7719
7720 (define_insn "*one_cmplqi2_1"
7721 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
7722 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
7723 "ix86_unary_operator_ok (NOT, QImode, operands)"
7724 "@
7725 not{b}\\t%0
7726 not{l}\\t%k0"
7727 [(set_attr "type" "negnot")
7728 (set_attr "mode" "QI,SI")])
7729
7730 (define_insn "*one_cmplqi2_2"
7731 [(set (reg 17)
7732 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
7733 (const_int 0)))
7734 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7735 (not:QI (match_dup 1)))]
7736 "ix86_match_ccmode (insn, CCNOmode)
7737 && ix86_unary_operator_ok (NOT, QImode, operands)"
7738 "#"
7739 [(set_attr "type" "alu1")
7740 (set_attr "mode" "QI")])
7741
7742 (define_split
7743 [(set (reg 17)
7744 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
7745 (const_int 0)))
7746 (set (match_operand:QI 0 "nonimmediate_operand" "")
7747 (not:QI (match_dup 1)))]
7748 "ix86_match_ccmode (insn, CCNOmode)"
7749 [(parallel [(set (reg:CCNO 17)
7750 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
7751 (const_int 0)))
7752 (set (match_dup 0)
7753 (xor:QI (match_dup 1) (const_int -1)))])]
7754 "")
7755 \f
7756 ;; Arithmetic shift instructions
7757
7758 ;; DImode shifts are implemented using the i386 "shift double" opcode,
7759 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
7760 ;; is variable, then the count is in %cl and the "imm" operand is dropped
7761 ;; from the assembler input.
7762 ;;
7763 ;; This instruction shifts the target reg/mem as usual, but instead of
7764 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
7765 ;; is a left shift double, bits are taken from the high order bits of
7766 ;; reg, else if the insn is a shift right double, bits are taken from the
7767 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
7768 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
7769 ;;
7770 ;; Since sh[lr]d does not change the `reg' operand, that is done
7771 ;; separately, making all shifts emit pairs of shift double and normal
7772 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
7773 ;; support a 63 bit shift, each shift where the count is in a reg expands
7774 ;; to a pair of shifts, a branch, a shift by 32 and a label.
7775 ;;
7776 ;; If the shift count is a constant, we need never emit more than one
7777 ;; shift pair, instead using moves and sign extension for counts greater
7778 ;; than 31.
7779
7780 (define_expand "ashldi3"
7781 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
7782 (ashift:DI (match_operand:DI 1 "register_operand" "0")
7783 (match_operand:QI 2 "nonmemory_operand" "Jc")))
7784 (clobber (reg:CC 17))])]
7785 ""
7786 "
7787 {
7788 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
7789 {
7790 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
7791 DONE;
7792 }
7793 }")
7794
7795 (define_insn "ashldi3_1"
7796 [(set (match_operand:DI 0 "register_operand" "=r")
7797 (ashift:DI (match_operand:DI 1 "register_operand" "0")
7798 (match_operand:QI 2 "nonmemory_operand" "Jc")))
7799 (clobber (match_scratch:SI 3 "=&r"))
7800 (clobber (reg:CC 17))]
7801 "TARGET_CMOVE"
7802 "#"
7803 [(set_attr "type" "multi")])
7804
7805 (define_insn "*ashldi3_2"
7806 [(set (match_operand:DI 0 "register_operand" "=r")
7807 (ashift:DI (match_operand:DI 1 "register_operand" "0")
7808 (match_operand:QI 2 "nonmemory_operand" "Jc")))
7809 (clobber (reg:CC 17))]
7810 ""
7811 "#"
7812 [(set_attr "type" "multi")])
7813
7814 (define_split
7815 [(set (match_operand:DI 0 "register_operand" "")
7816 (ashift:DI (match_operand:DI 1 "register_operand" "")
7817 (match_operand:QI 2 "nonmemory_operand" "")))
7818 (clobber (match_scratch:SI 3 ""))
7819 (clobber (reg:CC 17))]
7820 "TARGET_CMOVE && reload_completed"
7821 [(const_int 0)]
7822 "ix86_split_ashldi (operands, operands[3]); DONE;")
7823
7824 (define_split
7825 [(set (match_operand:DI 0 "register_operand" "")
7826 (ashift:DI (match_operand:DI 1 "register_operand" "")
7827 (match_operand:QI 2 "nonmemory_operand" "")))
7828 (clobber (reg:CC 17))]
7829 "reload_completed"
7830 [(const_int 0)]
7831 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
7832
7833 (define_insn "x86_shld_1"
7834 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
7835 (ior:SI (ashift:SI (match_dup 0)
7836 (match_operand:QI 2 "nonmemory_operand" "I,c"))
7837 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
7838 (minus:QI (const_int 32) (match_dup 2)))))
7839 (clobber (reg:CC 17))]
7840 ""
7841 "@
7842 shld{l}\\t{%2, %1, %0|%0, %1, %2}
7843 shld{l}\\t{%s2%1, %0|%0, %1, %2}"
7844 [(set_attr "type" "ishift")
7845 (set_attr "prefix_0f" "1")
7846 (set_attr "mode" "SI")
7847 (set_attr "pent_pair" "np")
7848 (set_attr "athlon_decode" "vector")
7849 (set_attr "ppro_uops" "few")])
7850
7851 (define_expand "x86_shift_adj_1"
7852 [(set (reg:CCZ 17)
7853 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
7854 (const_int 32))
7855 (const_int 0)))
7856 (set (match_operand:SI 0 "register_operand" "")
7857 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
7858 (match_operand:SI 1 "register_operand" "")
7859 (match_dup 0)))
7860 (set (match_dup 1)
7861 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
7862 (match_operand:SI 3 "register_operand" "r")
7863 (match_dup 1)))]
7864 "TARGET_CMOVE"
7865 "")
7866
7867 (define_expand "x86_shift_adj_2"
7868 [(use (match_operand:SI 0 "register_operand" ""))
7869 (use (match_operand:SI 1 "register_operand" ""))
7870 (use (match_operand:QI 2 "register_operand" ""))]
7871 ""
7872 "
7873 {
7874 rtx label = gen_label_rtx ();
7875 rtx tmp;
7876
7877 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
7878
7879 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
7880 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7881 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
7882 gen_rtx_LABEL_REF (VOIDmode, label),
7883 pc_rtx);
7884 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
7885 JUMP_LABEL (tmp) = label;
7886
7887 emit_move_insn (operands[0], operands[1]);
7888 emit_move_insn (operands[1], const0_rtx);
7889
7890 emit_label (label);
7891 LABEL_NUSES (label) = 1;
7892
7893 DONE;
7894 }")
7895
7896 (define_expand "ashlsi3"
7897 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7898 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
7899 (match_operand:QI 2 "nonmemory_operand" "")))
7900 (clobber (reg:CC 17))]
7901 ""
7902 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
7903
7904 (define_insn "*ashlsi3_1"
7905 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7906 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
7907 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
7908 (clobber (reg:CC 17))]
7909 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
7910 "*
7911 {
7912 switch (get_attr_type (insn))
7913 {
7914 case TYPE_ALU:
7915 if (operands[2] != const1_rtx)
7916 abort ();
7917 if (!rtx_equal_p (operands[0], operands[1]))
7918 abort ();
7919 return \"add{l}\\t{%0, %0|%0, %0}\";
7920
7921 case TYPE_LEA:
7922 if (GET_CODE (operands[2]) != CONST_INT
7923 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
7924 abort ();
7925 operands[1] = gen_rtx_MULT (SImode, operands[1],
7926 GEN_INT (1 << INTVAL (operands[2])));
7927 return \"lea{l}\\t{%a1, %0|%0, %a1}\";
7928
7929 default:
7930 if (REG_P (operands[2]))
7931 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
7932 else if (GET_CODE (operands[2]) == CONST_INT
7933 && INTVAL (operands[2]) == 1
7934 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7935 return \"sal{l}\\t%0\";
7936 else
7937 return \"sal{l}\\t{%2, %0|%0, %2}\";
7938 }
7939 }"
7940 [(set (attr "type")
7941 (cond [(eq_attr "alternative" "1")
7942 (const_string "lea")
7943 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7944 (const_int 0))
7945 (match_operand 0 "register_operand" ""))
7946 (match_operand 2 "const1_operand" ""))
7947 (const_string "alu")
7948 ]
7949 (const_string "ishift")))
7950 (set_attr "mode" "SI")])
7951
7952 ;; Convert lea to the lea pattern to avoid flags dependency.
7953 (define_split
7954 [(set (match_operand 0 "register_operand" "")
7955 (ashift (match_operand 1 "register_operand" "")
7956 (match_operand:QI 2 "const_int_operand" "")))
7957 (clobber (reg:CC 17))]
7958 "reload_completed
7959 && true_regnum (operands[0]) != true_regnum (operands[1])"
7960 [(const_int 0)]
7961 "
7962 {
7963 rtx pat;
7964 operands[0] = gen_lowpart (SImode, operands[0]);
7965 operands[1] = gen_lowpart (Pmode, operands[1]);
7966 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7967 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
7968 if (Pmode != SImode)
7969 pat = gen_rtx_SUBREG (SImode, pat, 0);
7970 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7971 DONE;
7972 }")
7973
7974 ;; This pattern can't accept a variable shift count, since shifts by
7975 ;; zero don't affect the flags. We assume that shifts by constant
7976 ;; zero are optimized away.
7977 (define_insn "*ashlsi3_cmp"
7978 [(set (reg 17)
7979 (compare
7980 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7981 (match_operand:QI 2 "immediate_operand" "I"))
7982 (const_int 0)))
7983 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7984 (ashift:SI (match_dup 1) (match_dup 2)))]
7985 "ix86_match_ccmode (insn, CCGOCmode)
7986 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
7987 "*
7988 {
7989 switch (get_attr_type (insn))
7990 {
7991 case TYPE_ALU:
7992 if (operands[2] != const1_rtx)
7993 abort ();
7994 return \"add{l}\\t{%0, %0|%0, %0}\";
7995
7996 default:
7997 if (REG_P (operands[2]))
7998 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
7999 else if (GET_CODE (operands[2]) == CONST_INT
8000 && INTVAL (operands[2]) == 1
8001 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8002 return \"sal{l}\\t%0\";
8003 else
8004 return \"sal{l}\\t{%2, %0|%0, %2}\";
8005 }
8006 }"
8007 [(set (attr "type")
8008 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8009 (const_int 0))
8010 (match_operand 0 "register_operand" ""))
8011 (match_operand 2 "const1_operand" ""))
8012 (const_string "alu")
8013 ]
8014 (const_string "ishift")))
8015 (set_attr "mode" "SI")])
8016
8017 (define_expand "ashlhi3"
8018 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8019 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
8020 (match_operand:QI 2 "nonmemory_operand" "")))
8021 (clobber (reg:CC 17))]
8022 "TARGET_HIMODE_MATH"
8023 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
8024
8025 (define_insn "*ashlhi3_1_lea"
8026 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8027 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
8028 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8029 (clobber (reg:CC 17))]
8030 "!TARGET_PARTIAL_REG_STALL
8031 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8032 "*
8033 {
8034 switch (get_attr_type (insn))
8035 {
8036 case TYPE_LEA:
8037 return \"#\";
8038 case TYPE_ALU:
8039 if (operands[2] != const1_rtx)
8040 abort ();
8041 return \"add{w}\\t{%0, %0|%0, %0}\";
8042
8043 default:
8044 if (REG_P (operands[2]))
8045 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8046 else if (GET_CODE (operands[2]) == CONST_INT
8047 && INTVAL (operands[2]) == 1
8048 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8049 return \"sal{w}\\t%0\";
8050 else
8051 return \"sal{w}\\t{%2, %0|%0, %2}\";
8052 }
8053 }"
8054 [(set (attr "type")
8055 (cond [(eq_attr "alternative" "1")
8056 (const_string "lea")
8057 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8058 (const_int 0))
8059 (match_operand 0 "register_operand" ""))
8060 (match_operand 2 "const1_operand" ""))
8061 (const_string "alu")
8062 ]
8063 (const_string "ishift")))
8064 (set_attr "mode" "HI,SI")])
8065
8066 (define_insn "*ashlhi3_1"
8067 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8068 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8069 (match_operand:QI 2 "nonmemory_operand" "cI")))
8070 (clobber (reg:CC 17))]
8071 "TARGET_PARTIAL_REG_STALL
8072 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8073 "*
8074 {
8075 switch (get_attr_type (insn))
8076 {
8077 case TYPE_ALU:
8078 if (operands[2] != const1_rtx)
8079 abort ();
8080 return \"add{w}\\t{%0, %0|%0, %0}\";
8081
8082 default:
8083 if (REG_P (operands[2]))
8084 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8085 else if (GET_CODE (operands[2]) == CONST_INT
8086 && INTVAL (operands[2]) == 1
8087 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8088 return \"sal{w}\\t%0\";
8089 else
8090 return \"sal{w}\\t{%2, %0|%0, %2}\";
8091 }
8092 }"
8093 [(set (attr "type")
8094 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8095 (const_int 0))
8096 (match_operand 0 "register_operand" ""))
8097 (match_operand 2 "const1_operand" ""))
8098 (const_string "alu")
8099 ]
8100 (const_string "ishift")))
8101 (set_attr "mode" "HI")])
8102
8103 ;; This pattern can't accept a variable shift count, since shifts by
8104 ;; zero don't affect the flags. We assume that shifts by constant
8105 ;; zero are optimized away.
8106 (define_insn "*ashlhi3_cmp"
8107 [(set (reg 17)
8108 (compare
8109 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8110 (match_operand:QI 2 "immediate_operand" "I"))
8111 (const_int 0)))
8112 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8113 (ashift:HI (match_dup 1) (match_dup 2)))]
8114 "ix86_match_ccmode (insn, CCGOCmode)
8115 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8116 "*
8117 {
8118 switch (get_attr_type (insn))
8119 {
8120 case TYPE_ALU:
8121 if (operands[2] != const1_rtx)
8122 abort ();
8123 return \"add{w}\\t{%0, %0|%0, %0}\";
8124
8125 default:
8126 if (REG_P (operands[2]))
8127 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8128 else if (GET_CODE (operands[2]) == CONST_INT
8129 && INTVAL (operands[2]) == 1
8130 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8131 return \"sal{w}\\t%0\";
8132 else
8133 return \"sal{w}\\t{%2, %0|%0, %2}\";
8134 }
8135 }"
8136 [(set (attr "type")
8137 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8138 (const_int 0))
8139 (match_operand 0 "register_operand" ""))
8140 (match_operand 2 "const1_operand" ""))
8141 (const_string "alu")
8142 ]
8143 (const_string "ishift")))
8144 (set_attr "mode" "HI")])
8145
8146 (define_expand "ashlqi3"
8147 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8148 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
8149 (match_operand:QI 2 "nonmemory_operand" "")))
8150 (clobber (reg:CC 17))]
8151 "TARGET_QIMODE_MATH"
8152 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
8153
8154 ;; %%% Potential partial reg stall on alternative 2. What to do?
8155
8156 (define_insn "*ashlqi3_1_lea"
8157 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
8158 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
8159 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8160 (clobber (reg:CC 17))]
8161 "!TARGET_PARTIAL_REG_STALL
8162 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8163 "*
8164 {
8165 switch (get_attr_type (insn))
8166 {
8167 case TYPE_LEA:
8168 return \"#\";
8169 case TYPE_ALU:
8170 if (operands[2] != const1_rtx)
8171 abort ();
8172 if (NON_QI_REG_P (operands[1]))
8173 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
8174 else
8175 return \"add{b}\\t{%0, %0|%0, %0}\";
8176
8177 default:
8178 if (REG_P (operands[2]))
8179 {
8180 if (get_attr_mode (insn) == MODE_SI)
8181 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
8182 else
8183 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8184 }
8185 else if (GET_CODE (operands[2]) == CONST_INT
8186 && INTVAL (operands[2]) == 1
8187 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8188 {
8189 if (get_attr_mode (insn) == MODE_SI)
8190 return \"sal{l}\\t%0\";
8191 else
8192 return \"sal{b}\\t%0\";
8193 }
8194 else
8195 {
8196 if (get_attr_mode (insn) == MODE_SI)
8197 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
8198 else
8199 return \"sal{b}\\t{%2, %0|%0, %2}\";
8200 }
8201 }
8202 }"
8203 [(set (attr "type")
8204 (cond [(eq_attr "alternative" "2")
8205 (const_string "lea")
8206 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8207 (const_int 0))
8208 (match_operand 0 "register_operand" ""))
8209 (match_operand 2 "const1_operand" ""))
8210 (const_string "alu")
8211 ]
8212 (const_string "ishift")))
8213 (set_attr "mode" "QI,SI,SI")])
8214
8215 (define_insn "*ashlqi3_1"
8216 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8217 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8218 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8219 (clobber (reg:CC 17))]
8220 "TARGET_PARTIAL_REG_STALL
8221 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8222 "*
8223 {
8224 switch (get_attr_type (insn))
8225 {
8226 case TYPE_ALU:
8227 if (operands[2] != const1_rtx)
8228 abort ();
8229 if (NON_QI_REG_P (operands[1]))
8230 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
8231 else
8232 return \"add{b}\\t{%0, %0|%0, %0}\";
8233
8234 default:
8235 if (REG_P (operands[2]))
8236 {
8237 if (NON_QI_REG_P (operands[1]))
8238 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
8239 else
8240 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8241 }
8242 else if (GET_CODE (operands[2]) == CONST_INT
8243 && INTVAL (operands[2]) == 1
8244 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8245 {
8246 if (NON_QI_REG_P (operands[1]))
8247 return \"sal{l}\\t%0\";
8248 else
8249 return \"sal{b}\\t%0\";
8250 }
8251 else
8252 {
8253 if (NON_QI_REG_P (operands[1]))
8254 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
8255 else
8256 return \"sal{b}\\t{%2, %0|%0, %2}\";
8257 }
8258 }
8259 }"
8260 [(set (attr "type")
8261 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8262 (const_int 0))
8263 (match_operand 0 "register_operand" ""))
8264 (match_operand 2 "const1_operand" ""))
8265 (const_string "alu")
8266 ]
8267 (const_string "ishift")))
8268 (set_attr "mode" "QI,SI")])
8269
8270 ;; This pattern can't accept a variable shift count, since shifts by
8271 ;; zero don't affect the flags. We assume that shifts by constant
8272 ;; zero are optimized away.
8273 (define_insn "*ashlqi3_cmp"
8274 [(set (reg 17)
8275 (compare
8276 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8277 (match_operand:QI 2 "immediate_operand" "I"))
8278 (const_int 0)))
8279 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8280 (ashift:QI (match_dup 1) (match_dup 2)))]
8281 "ix86_match_ccmode (insn, CCGOCmode)
8282 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8283 "*
8284 {
8285 switch (get_attr_type (insn))
8286 {
8287 case TYPE_ALU:
8288 if (operands[2] != const1_rtx)
8289 abort ();
8290 return \"add{b}\\t{%0, %0|%0, %0}\";
8291
8292 default:
8293 if (REG_P (operands[2]))
8294 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8295 else if (GET_CODE (operands[2]) == CONST_INT
8296 && INTVAL (operands[2]) == 1
8297 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8298 return \"sal{b}\\t%0\";
8299 else
8300 return \"sal{b}\\t{%2, %0|%0, %2}\";
8301 }
8302 }"
8303 [(set (attr "type")
8304 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8305 (const_int 0))
8306 (match_operand 0 "register_operand" ""))
8307 (match_operand 2 "const1_operand" ""))
8308 (const_string "alu")
8309 ]
8310 (const_string "ishift")))
8311 (set_attr "mode" "QI")])
8312
8313 ;; See comment above `ashldi3' about how this works.
8314
8315 (define_expand "ashrdi3"
8316 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8317 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8318 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8319 (clobber (reg:CC 17))])]
8320 ""
8321 "
8322 {
8323 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
8324 {
8325 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
8326 DONE;
8327 }
8328 }")
8329
8330 (define_insn "ashrdi3_1"
8331 [(set (match_operand:DI 0 "register_operand" "=r")
8332 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8333 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8334 (clobber (match_scratch:SI 3 "=&r"))
8335 (clobber (reg:CC 17))]
8336 "TARGET_CMOVE"
8337 "#"
8338 [(set_attr "type" "multi")])
8339
8340 (define_insn "*ashrdi3_2"
8341 [(set (match_operand:DI 0 "register_operand" "=r")
8342 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8343 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8344 (clobber (reg:CC 17))]
8345 ""
8346 "#"
8347 [(set_attr "type" "multi")])
8348
8349 (define_split
8350 [(set (match_operand:DI 0 "register_operand" "")
8351 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8352 (match_operand:QI 2 "nonmemory_operand" "")))
8353 (clobber (match_scratch:SI 3 ""))
8354 (clobber (reg:CC 17))]
8355 "TARGET_CMOVE && reload_completed"
8356 [(const_int 0)]
8357 "ix86_split_ashrdi (operands, operands[3]); DONE;")
8358
8359 (define_split
8360 [(set (match_operand:DI 0 "register_operand" "")
8361 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8362 (match_operand:QI 2 "nonmemory_operand" "")))
8363 (clobber (reg:CC 17))]
8364 "reload_completed"
8365 [(const_int 0)]
8366 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
8367
8368 (define_insn "x86_shrd_1"
8369 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
8370 (ior:SI (ashiftrt:SI (match_dup 0)
8371 (match_operand:QI 2 "nonmemory_operand" "I,c"))
8372 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
8373 (minus:QI (const_int 32) (match_dup 2)))))
8374 (clobber (reg:CC 17))]
8375 ""
8376 "@
8377 shrd{l}\\t{%2, %1, %0|%0, %1, %2}
8378 shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
8379 [(set_attr "type" "ishift")
8380 (set_attr "prefix_0f" "1")
8381 (set_attr "pent_pair" "np")
8382 (set_attr "ppro_uops" "few")
8383 (set_attr "mode" "SI")])
8384
8385 (define_expand "x86_shift_adj_3"
8386 [(use (match_operand:SI 0 "register_operand" ""))
8387 (use (match_operand:SI 1 "register_operand" ""))
8388 (use (match_operand:QI 2 "register_operand" ""))]
8389 ""
8390 "
8391 {
8392 rtx label = gen_label_rtx ();
8393 rtx tmp;
8394
8395 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
8396
8397 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8398 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8399 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8400 gen_rtx_LABEL_REF (VOIDmode, label),
8401 pc_rtx);
8402 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8403 JUMP_LABEL (tmp) = label;
8404
8405 emit_move_insn (operands[0], operands[1]);
8406 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
8407
8408 emit_label (label);
8409 LABEL_NUSES (label) = 1;
8410
8411 DONE;
8412 }")
8413
8414 (define_insn "ashrsi3_31"
8415 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
8416 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
8417 (match_operand:SI 2 "const_int_operand" "i,i")))
8418 (clobber (reg:CC 17))]
8419 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
8420 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8421 "@
8422 {cltd|cdq}
8423 sar{l}\\t{%2, %0|%0, %2}"
8424 [(set_attr "type" "imovx,ishift")
8425 (set_attr "prefix_0f" "0,*")
8426 (set_attr "length_immediate" "0,*")
8427 (set_attr "modrm" "0,1")
8428 (set_attr "mode" "SI")])
8429
8430 (define_expand "ashrsi3"
8431 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8432 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
8433 (match_operand:QI 2 "nonmemory_operand" "")))
8434 (clobber (reg:CC 17))]
8435 ""
8436 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
8437
8438 (define_insn "*ashrsi3_1_one_bit"
8439 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8440 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8441 (match_operand:QI 2 "const_int_1_operand" "")))
8442 (clobber (reg:CC 17))]
8443 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
8444 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8445 "sar{l}\\t%0"
8446 [(set_attr "type" "ishift")
8447 (set (attr "length")
8448 (if_then_else (match_operand:SI 0 "register_operand" "")
8449 (const_string "2")
8450 (const_string "*")))])
8451
8452 (define_insn "*ashrsi3_1"
8453 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8454 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8455 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8456 (clobber (reg:CC 17))]
8457 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8458 "@
8459 sar{l}\\t{%2, %0|%0, %2}
8460 sar{l}\\t{%b2, %0|%0, %b2}"
8461 [(set_attr "type" "ishift")
8462 (set_attr "mode" "SI")])
8463
8464 ;; This pattern can't accept a variable shift count, since shifts by
8465 ;; zero don't affect the flags. We assume that shifts by constant
8466 ;; zero are optimized away.
8467 (define_insn "*ashrsi3_one_bit_cmp"
8468 [(set (reg 17)
8469 (compare
8470 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8471 (match_operand:QI 2 "const_int_1_operand" ""))
8472 (const_int 0)))
8473 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8474 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
8475 "ix86_match_ccmode (insn, CCGOCmode)
8476 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8477 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8478 "sar{l}\\t%0"
8479 [(set_attr "type" "ishift")
8480 (set (attr "length")
8481 (if_then_else (match_operand:SI 0 "register_operand" "")
8482 (const_string "2")
8483 (const_string "*")))])
8484
8485 ;; This pattern can't accept a variable shift count, since shifts by
8486 ;; zero don't affect the flags. We assume that shifts by constant
8487 ;; zero are optimized away.
8488 (define_insn "*ashrsi3_cmp"
8489 [(set (reg 17)
8490 (compare
8491 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8492 (match_operand:QI 2 "immediate_operand" "I"))
8493 (const_int 0)))
8494 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8495 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
8496 "ix86_match_ccmode (insn, CCGOCmode)
8497 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8498 "sar{l}\\t{%2, %0|%0, %2}"
8499 [(set_attr "type" "ishift")
8500 (set_attr "mode" "SI")])
8501
8502 (define_expand "ashrhi3"
8503 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8504 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
8505 (match_operand:QI 2 "nonmemory_operand" "")))
8506 (clobber (reg:CC 17))]
8507 "TARGET_HIMODE_MATH"
8508 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
8509
8510 (define_insn "*ashrhi3_1_one_bit"
8511 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8512 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8513 (match_operand:QI 2 "const_int_1_operand" "")))
8514 (clobber (reg:CC 17))]
8515 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
8516 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8517 "sar{w}\\t%0"
8518 [(set_attr "type" "ishift")
8519 (set (attr "length")
8520 (if_then_else (match_operand:SI 0 "register_operand" "")
8521 (const_string "2")
8522 (const_string "*")))])
8523
8524 (define_insn "*ashrhi3_1"
8525 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8526 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8527 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8528 (clobber (reg:CC 17))]
8529 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8530 "@
8531 sar{w}\\t{%2, %0|%0, %2}
8532 sar{w}\\t{%b2, %0|%0, %b2}"
8533 [(set_attr "type" "ishift")
8534 (set_attr "mode" "HI")])
8535
8536 ;; This pattern can't accept a variable shift count, since shifts by
8537 ;; zero don't affect the flags. We assume that shifts by constant
8538 ;; zero are optimized away.
8539 (define_insn "*ashrhi3_one_bit_cmp"
8540 [(set (reg 17)
8541 (compare
8542 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8543 (match_operand:QI 2 "const_int_1_operand" ""))
8544 (const_int 0)))
8545 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8546 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
8547 "ix86_match_ccmode (insn, CCGOCmode)
8548 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8549 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8550 "sar{w}\\t%0"
8551 [(set_attr "type" "ishift")
8552 (set (attr "length")
8553 (if_then_else (match_operand:SI 0 "register_operand" "")
8554 (const_string "2")
8555 (const_string "*")))])
8556
8557 ;; This pattern can't accept a variable shift count, since shifts by
8558 ;; zero don't affect the flags. We assume that shifts by constant
8559 ;; zero are optimized away.
8560 (define_insn "*ashrhi3_cmp"
8561 [(set (reg 17)
8562 (compare
8563 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8564 (match_operand:QI 2 "immediate_operand" "I"))
8565 (const_int 0)))
8566 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8567 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
8568 "ix86_match_ccmode (insn, CCGOCmode)
8569 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8570 "sar{w}\\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "ishift")
8572 (set_attr "mode" "HI")])
8573
8574 (define_expand "ashrqi3"
8575 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8576 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
8577 (match_operand:QI 2 "nonmemory_operand" "")))
8578 (clobber (reg:CC 17))]
8579 "TARGET_QIMODE_MATH"
8580 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
8581
8582 (define_insn "*ashrqi3_1_one_bit"
8583 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8584 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8585 (match_operand:QI 2 "const_int_1_operand" "")))
8586 (clobber (reg:CC 17))]
8587 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
8588 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8589 "sar{b}\\t%0"
8590 [(set_attr "type" "ishift")
8591 (set (attr "length")
8592 (if_then_else (match_operand:SI 0 "register_operand" "")
8593 (const_string "2")
8594 (const_string "*")))])
8595
8596 (define_insn "*ashrqi3_1"
8597 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8598 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8599 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8600 (clobber (reg:CC 17))]
8601 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8602 "@
8603 sar{b}\\t{%2, %0|%0, %2}
8604 sar{b}\\t{%b2, %0|%0, %b2}"
8605 [(set_attr "type" "ishift")
8606 (set_attr "mode" "QI")])
8607
8608 ;; This pattern can't accept a variable shift count, since shifts by
8609 ;; zero don't affect the flags. We assume that shifts by constant
8610 ;; zero are optimized away.
8611 (define_insn "*ashrqi3_one_bit_cmp"
8612 [(set (reg 17)
8613 (compare
8614 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8615 (match_operand:QI 2 "const_int_1_operand" "I"))
8616 (const_int 0)))
8617 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8618 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
8619 "ix86_match_ccmode (insn, CCGOCmode)
8620 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8621 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8622 "sar{b}\\t%0"
8623 [(set_attr "type" "ishift")
8624 (set (attr "length")
8625 (if_then_else (match_operand:SI 0 "register_operand" "")
8626 (const_string "2")
8627 (const_string "*")))])
8628
8629 ;; This pattern can't accept a variable shift count, since shifts by
8630 ;; zero don't affect the flags. We assume that shifts by constant
8631 ;; zero are optimized away.
8632 (define_insn "*ashrqi3_cmp"
8633 [(set (reg 17)
8634 (compare
8635 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8636 (match_operand:QI 2 "immediate_operand" "I"))
8637 (const_int 0)))
8638 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8639 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
8640 "ix86_match_ccmode (insn, CCGOCmode)
8641 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8642 "sar{b}\\t{%2, %0|%0, %2}"
8643 [(set_attr "type" "ishift")
8644 (set_attr "mode" "QI")])
8645 \f
8646 ;; Logical shift instructions
8647
8648 ;; See comment above `ashldi3' about how this works.
8649
8650 (define_expand "lshrdi3"
8651 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8652 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8653 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8654 (clobber (reg:CC 17))])]
8655 ""
8656 "
8657 {
8658 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
8659 {
8660 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
8661 DONE;
8662 }
8663 }")
8664
8665 (define_insn "lshrdi3_1"
8666 [(set (match_operand:DI 0 "register_operand" "=r")
8667 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8668 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8669 (clobber (match_scratch:SI 3 "=&r"))
8670 (clobber (reg:CC 17))]
8671 "TARGET_CMOVE"
8672 "#"
8673 [(set_attr "type" "multi")])
8674
8675 (define_insn "*lshrdi3_2"
8676 [(set (match_operand:DI 0 "register_operand" "=r")
8677 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8678 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8679 (clobber (reg:CC 17))]
8680 ""
8681 "#"
8682 [(set_attr "type" "multi")])
8683
8684 (define_split
8685 [(set (match_operand:DI 0 "register_operand" "")
8686 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8687 (match_operand:QI 2 "nonmemory_operand" "")))
8688 (clobber (match_scratch:SI 3 ""))
8689 (clobber (reg:CC 17))]
8690 "TARGET_CMOVE && reload_completed"
8691 [(const_int 0)]
8692 "ix86_split_lshrdi (operands, operands[3]); DONE;")
8693
8694 (define_split
8695 [(set (match_operand:DI 0 "register_operand" "")
8696 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8697 (match_operand:QI 2 "nonmemory_operand" "")))
8698 (clobber (reg:CC 17))]
8699 "reload_completed"
8700 [(const_int 0)]
8701 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
8702
8703 (define_expand "lshrsi3"
8704 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8705 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
8706 (match_operand:QI 2 "nonmemory_operand" "")))
8707 (clobber (reg:CC 17))]
8708 ""
8709 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
8710
8711 (define_insn "*lshrsi3_1_one_bit"
8712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8713 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8714 (match_operand:QI 2 "const_int_1_operand" "")))
8715 (clobber (reg:CC 17))]
8716 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
8717 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8718 "shr{l}\\t%0"
8719 [(set_attr "type" "ishift")
8720 (set (attr "length")
8721 (if_then_else (match_operand:SI 0 "register_operand" "")
8722 (const_string "2")
8723 (const_string "*")))])
8724
8725 (define_insn "*lshrsi3_1"
8726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8728 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8729 (clobber (reg:CC 17))]
8730 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8731 "@
8732 shr{l}\\t{%2, %0|%0, %2}
8733 shr{l}\\t{%b2, %0|%0, %b2}"
8734 [(set_attr "type" "ishift")
8735 (set_attr "mode" "SI")])
8736
8737 ;; This pattern can't accept a variable shift count, since shifts by
8738 ;; zero don't affect the flags. We assume that shifts by constant
8739 ;; zero are optimized away.
8740 (define_insn "*lshrsi3_one_bit_cmp"
8741 [(set (reg 17)
8742 (compare
8743 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8744 (match_operand:QI 2 "const_int_1_operand" ""))
8745 (const_int 0)))
8746 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8747 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
8748 "ix86_match_ccmode (insn, CCGOCmode)
8749 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8750 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8751 "shr{l}\\t%0"
8752 [(set_attr "type" "ishift")
8753 (set (attr "length")
8754 (if_then_else (match_operand:SI 0 "register_operand" "")
8755 (const_string "2")
8756 (const_string "*")))])
8757
8758 ;; This pattern can't accept a variable shift count, since shifts by
8759 ;; zero don't affect the flags. We assume that shifts by constant
8760 ;; zero are optimized away.
8761 (define_insn "*lshrsi3_cmp"
8762 [(set (reg 17)
8763 (compare
8764 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8765 (match_operand:QI 2 "immediate_operand" "I"))
8766 (const_int 0)))
8767 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8768 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
8769 "ix86_match_ccmode (insn, CCGOCmode)
8770 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8771 "shr{l}\\t{%2, %0|%0, %2}"
8772 [(set_attr "type" "ishift")
8773 (set_attr "mode" "SI")])
8774
8775 (define_expand "lshrhi3"
8776 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8777 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
8778 (match_operand:QI 2 "nonmemory_operand" "")))
8779 (clobber (reg:CC 17))]
8780 "TARGET_HIMODE_MATH"
8781 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
8782
8783 (define_insn "*lshrhi3_1_one_bit"
8784 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8785 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8786 (match_operand:QI 2 "const_int_1_operand" "")))
8787 (clobber (reg:CC 17))]
8788 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
8789 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8790 "shr{w}\\t%0"
8791 [(set_attr "type" "ishift")
8792 (set (attr "length")
8793 (if_then_else (match_operand:SI 0 "register_operand" "")
8794 (const_string "2")
8795 (const_string "*")))])
8796
8797 (define_insn "*lshrhi3_1"
8798 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8799 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8800 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8801 (clobber (reg:CC 17))]
8802 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8803 "@
8804 shr{w}\\t{%2, %0|%0, %2}
8805 shr{w}\\t{%b2, %0|%0, %b2}"
8806 [(set_attr "type" "ishift")
8807 (set_attr "mode" "HI")])
8808
8809 ;; This pattern can't accept a variable shift count, since shifts by
8810 ;; zero don't affect the flags. We assume that shifts by constant
8811 ;; zero are optimized away.
8812 (define_insn "*lshrhi3_one_bit_cmp"
8813 [(set (reg 17)
8814 (compare
8815 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8816 (match_operand:QI 2 "const_int_1_operand" ""))
8817 (const_int 0)))
8818 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8819 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
8820 "ix86_match_ccmode (insn, CCGOCmode)
8821 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8822 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8823 "shr{w}\\t%0"
8824 [(set_attr "type" "ishift")
8825 (set (attr "length")
8826 (if_then_else (match_operand:SI 0 "register_operand" "")
8827 (const_string "2")
8828 (const_string "*")))])
8829
8830 ;; This pattern can't accept a variable shift count, since shifts by
8831 ;; zero don't affect the flags. We assume that shifts by constant
8832 ;; zero are optimized away.
8833 (define_insn "*lshrhi3_cmp"
8834 [(set (reg 17)
8835 (compare
8836 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8837 (match_operand:QI 2 "immediate_operand" "I"))
8838 (const_int 0)))
8839 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8840 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
8841 "ix86_match_ccmode (insn, CCGOCmode)
8842 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8843 "shr{w}\\t{%2, %0|%0, %2}"
8844 [(set_attr "type" "ishift")
8845 (set_attr "mode" "HI")])
8846
8847 (define_expand "lshrqi3"
8848 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8849 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
8850 (match_operand:QI 2 "nonmemory_operand" "")))
8851 (clobber (reg:CC 17))]
8852 "TARGET_QIMODE_MATH"
8853 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
8854
8855 (define_insn "*lshrqi3_1_one_bit"
8856 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8857 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8858 (match_operand:QI 2 "const_int_1_operand" "")))
8859 (clobber (reg:CC 17))]
8860 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
8861 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8862 "shr{b}\\t%0"
8863 [(set_attr "type" "ishift")
8864 (set (attr "length")
8865 (if_then_else (match_operand:SI 0 "register_operand" "")
8866 (const_string "2")
8867 (const_string "*")))])
8868
8869 (define_insn "*lshrqi3_1"
8870 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8871 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8872 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8873 (clobber (reg:CC 17))]
8874 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8875 "@
8876 shr{b}\\t{%2, %0|%0, %2}
8877 shr{b}\\t{%b2, %0|%0, %b2}"
8878 [(set_attr "type" "ishift")
8879 (set_attr "mode" "QI")])
8880
8881 ;; This pattern can't accept a variable shift count, since shifts by
8882 ;; zero don't affect the flags. We assume that shifts by constant
8883 ;; zero are optimized away.
8884 (define_insn "*lshrqi2_one_bit_cmp"
8885 [(set (reg 17)
8886 (compare
8887 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8888 (match_operand:QI 2 "const_int_1_operand" ""))
8889 (const_int 0)))
8890 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8891 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
8892 "ix86_match_ccmode (insn, CCGOCmode)
8893 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8894 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8895 "shr{b}\\t%0"
8896 [(set_attr "type" "ishift")
8897 (set (attr "length")
8898 (if_then_else (match_operand:SI 0 "register_operand" "")
8899 (const_string "2")
8900 (const_string "*")))])
8901
8902 ;; This pattern can't accept a variable shift count, since shifts by
8903 ;; zero don't affect the flags. We assume that shifts by constant
8904 ;; zero are optimized away.
8905 (define_insn "*lshrqi2_cmp"
8906 [(set (reg 17)
8907 (compare
8908 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8909 (match_operand:QI 2 "immediate_operand" "I"))
8910 (const_int 0)))
8911 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8912 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
8913 "ix86_match_ccmode (insn, CCGOCmode)
8914 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8915 "shr{b}\\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "ishift")
8917 (set_attr "mode" "QI")])
8918 \f
8919 ;; Rotate instructions
8920
8921 (define_expand "rotlsi3"
8922 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8923 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
8924 (match_operand:QI 2 "nonmemory_operand" "")))
8925 (clobber (reg:CC 17))]
8926 ""
8927 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
8928
8929 (define_insn "*rotlsi3_1_one_bit"
8930 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8931 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8932 (match_operand:QI 2 "const_int_1_operand" "")))
8933 (clobber (reg:CC 17))]
8934 "ix86_binary_operator_ok (ROTATE, SImode, operands)
8935 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8936 "rol{l}\\t%0"
8937 [(set_attr "type" "ishift")
8938 (set (attr "length")
8939 (if_then_else (match_operand:SI 0 "register_operand" "")
8940 (const_string "2")
8941 (const_string "*")))])
8942
8943 (define_insn "*rotlsi3_1"
8944 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8945 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8946 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8947 (clobber (reg:CC 17))]
8948 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
8949 "@
8950 rol{l}\\t{%2, %0|%0, %2}
8951 rol{l}\\t{%b2, %0|%0, %b2}"
8952 [(set_attr "type" "ishift")
8953 (set_attr "mode" "SI")])
8954
8955 (define_expand "rotlhi3"
8956 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8957 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
8958 (match_operand:QI 2 "nonmemory_operand" "")))
8959 (clobber (reg:CC 17))]
8960 "TARGET_HIMODE_MATH"
8961 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
8962
8963 (define_insn "*rotlhi3_1_one_bit"
8964 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8965 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8966 (match_operand:QI 2 "const_int_1_operand" "")))
8967 (clobber (reg:CC 17))]
8968 "ix86_binary_operator_ok (ROTATE, HImode, operands)
8969 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8970 "rol{w}\\t%0"
8971 [(set_attr "type" "ishift")
8972 (set (attr "length")
8973 (if_then_else (match_operand:SI 0 "register_operand" "")
8974 (const_string "2")
8975 (const_string "*")))])
8976
8977 (define_insn "*rotlhi3_1"
8978 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8979 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8980 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8981 (clobber (reg:CC 17))]
8982 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
8983 "@
8984 rol{w}\\t{%2, %0|%0, %2}
8985 rol{w}\\t{%b2, %0|%0, %b2}"
8986 [(set_attr "type" "ishift")
8987 (set_attr "mode" "HI")])
8988
8989 (define_expand "rotlqi3"
8990 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8991 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
8992 (match_operand:QI 2 "nonmemory_operand" "")))
8993 (clobber (reg:CC 17))]
8994 "TARGET_QIMODE_MATH"
8995 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
8996
8997 (define_insn "*rotlqi3_1_one_bit"
8998 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8999 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9000 (match_operand:QI 2 "const_int_1_operand" "")))
9001 (clobber (reg:CC 17))]
9002 "ix86_binary_operator_ok (ROTATE, QImode, operands)
9003 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9004 "rol{b}\\t%0"
9005 [(set_attr "type" "ishift")
9006 (set (attr "length")
9007 (if_then_else (match_operand:SI 0 "register_operand" "")
9008 (const_string "2")
9009 (const_string "*")))])
9010
9011 (define_insn "*rotlqi3_1"
9012 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9013 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9014 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9015 (clobber (reg:CC 17))]
9016 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
9017 "@
9018 rol{b}\\t{%2, %0|%0, %2}
9019 rol{b}\\t{%b2, %0|%0, %b2}"
9020 [(set_attr "type" "ishift")
9021 (set_attr "mode" "QI")])
9022
9023 (define_expand "rotrsi3"
9024 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9025 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
9026 (match_operand:QI 2 "nonmemory_operand" "")))
9027 (clobber (reg:CC 17))]
9028 ""
9029 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
9030
9031 (define_insn "*rotrsi3_1_one_bit"
9032 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9033 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9034 (match_operand:QI 2 "const_int_1_operand" "")))
9035 (clobber (reg:CC 17))]
9036 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
9037 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9038 "ror{l}\\t%0"
9039 [(set_attr "type" "ishift")
9040 (set (attr "length")
9041 (if_then_else (match_operand:SI 0 "register_operand" "")
9042 (const_string "2")
9043 (const_string "*")))])
9044
9045 (define_insn "*rotrsi3_1"
9046 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
9047 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9048 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9049 (clobber (reg:CC 17))]
9050 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
9051 "@
9052 ror{l}\\t{%2, %0|%0, %2}
9053 ror{l}\\t{%b2, %0|%0, %b2}"
9054 [(set_attr "type" "ishift")
9055 (set_attr "mode" "SI")])
9056
9057 (define_expand "rotrhi3"
9058 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9059 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
9060 (match_operand:QI 2 "nonmemory_operand" "")))
9061 (clobber (reg:CC 17))]
9062 "TARGET_HIMODE_MATH"
9063 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
9064
9065 (define_insn "*rotrhi3_one_bit"
9066 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9067 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9068 (match_operand:QI 2 "const_int_1_operand" "")))
9069 (clobber (reg:CC 17))]
9070 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
9071 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9072 "ror{w}\\t%0"
9073 [(set_attr "type" "ishift")
9074 (set (attr "length")
9075 (if_then_else (match_operand:SI 0 "register_operand" "")
9076 (const_string "2")
9077 (const_string "*")))])
9078
9079 (define_insn "*rotrhi3"
9080 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
9081 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
9082 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9083 (clobber (reg:CC 17))]
9084 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
9085 "@
9086 ror{w}\\t{%2, %0|%0, %2}
9087 ror{w}\\t{%b2, %0|%0, %b2}"
9088 [(set_attr "type" "ishift")
9089 (set_attr "mode" "HI")])
9090
9091 (define_expand "rotrqi3"
9092 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9093 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
9094 (match_operand:QI 2 "nonmemory_operand" "")))
9095 (clobber (reg:CC 17))]
9096 "TARGET_QIMODE_MATH"
9097 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
9098
9099 (define_insn "*rotrqi3_1_one_bit"
9100 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9101 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9102 (match_operand:QI 2 "const_int_1_operand" "")))
9103 (clobber (reg:CC 17))]
9104 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
9105 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9106 "ror{b}\\t%0"
9107 [(set_attr "type" "ishift")
9108 (set (attr "length")
9109 (if_then_else (match_operand:SI 0 "register_operand" "")
9110 (const_string "2")
9111 (const_string "*")))])
9112
9113 (define_insn "*rotrqi3_1"
9114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9115 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9116 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9117 (clobber (reg:CC 17))]
9118 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
9119 "@
9120 ror{b}\\t{%2, %0|%0, %2}
9121 ror{b}\\t{%b2, %0|%0, %b2}"
9122 [(set_attr "type" "ishift")
9123 (set_attr "mode" "QI")])
9124 \f
9125 ;; Bit set / bit test instructions
9126
9127 (define_expand "extv"
9128 [(set (match_operand:SI 0 "register_operand" "")
9129 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
9130 (match_operand:SI 2 "immediate_operand" "")
9131 (match_operand:SI 3 "immediate_operand" "")))]
9132 ""
9133 "
9134 {
9135 /* Handle extractions from %ah et al. */
9136 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9137 FAIL;
9138
9139 /* From mips.md: extract_bit_field doesn't verify that our source
9140 matches the predicate, so check it again here. */
9141 if (! register_operand (operands[1], VOIDmode))
9142 FAIL;
9143 }")
9144
9145 (define_expand "extzv"
9146 [(set (match_operand:SI 0 "register_operand" "")
9147 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
9148 (match_operand:SI 2 "immediate_operand" "")
9149 (match_operand:SI 3 "immediate_operand" "")))]
9150 ""
9151 "
9152 {
9153 /* Handle extractions from %ah et al. */
9154 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9155 FAIL;
9156
9157 /* From mips.md: extract_bit_field doesn't verify that our source
9158 matches the predicate, so check it again here. */
9159 if (! register_operand (operands[1], VOIDmode))
9160 FAIL;
9161 }")
9162
9163 (define_expand "insv"
9164 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9165 (match_operand:SI 1 "immediate_operand" "")
9166 (match_operand:SI 2 "immediate_operand" ""))
9167 (match_operand:SI 3 "register_operand" ""))]
9168 ""
9169 "
9170 {
9171 /* Handle extractions from %ah et al. */
9172 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
9173 FAIL;
9174
9175 /* From mips.md: insert_bit_field doesn't verify that our source
9176 matches the predicate, so check it again here. */
9177 if (! register_operand (operands[0], VOIDmode))
9178 FAIL;
9179 }")
9180
9181 ;; %%% bts, btr, btc, bt.
9182 \f
9183 ;; Store-flag instructions.
9184
9185 ;; For all sCOND expanders, also expand the compare or test insn that
9186 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
9187
9188 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
9189 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
9190 ;; way, which can later delete the movzx if only QImode is needed.
9191
9192 (define_expand "seq"
9193 [(set (match_operand:SI 0 "register_operand" "")
9194 (eq:SI (reg:CC 17) (const_int 0)))]
9195 ""
9196 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
9197
9198 (define_expand "sne"
9199 [(set (match_operand:SI 0 "register_operand" "")
9200 (ne:SI (reg:CC 17) (const_int 0)))]
9201 ""
9202 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
9203
9204 (define_expand "sgt"
9205 [(set (match_operand:SI 0 "register_operand" "")
9206 (gt:SI (reg:CC 17) (const_int 0)))]
9207 ""
9208 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
9209
9210 (define_expand "sgtu"
9211 [(set (match_operand:SI 0 "register_operand" "")
9212 (gtu:SI (reg:CC 17) (const_int 0)))]
9213 ""
9214 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
9215
9216 (define_expand "slt"
9217 [(set (match_operand:SI 0 "register_operand" "")
9218 (lt:SI (reg:CC 17) (const_int 0)))]
9219 ""
9220 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
9221
9222 (define_expand "sltu"
9223 [(set (match_operand:SI 0 "register_operand" "")
9224 (ltu:SI (reg:CC 17) (const_int 0)))]
9225 ""
9226 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
9227
9228 (define_expand "sge"
9229 [(set (match_operand:SI 0 "register_operand" "")
9230 (ge:SI (reg:CC 17) (const_int 0)))]
9231 ""
9232 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
9233
9234 (define_expand "sgeu"
9235 [(set (match_operand:SI 0 "register_operand" "")
9236 (geu:SI (reg:CC 17) (const_int 0)))]
9237 ""
9238 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
9239
9240 (define_expand "sle"
9241 [(set (match_operand:SI 0 "register_operand" "")
9242 (le:SI (reg:CC 17) (const_int 0)))]
9243 ""
9244 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
9245
9246 (define_expand "sleu"
9247 [(set (match_operand:SI 0 "register_operand" "")
9248 (leu:SI (reg:CC 17) (const_int 0)))]
9249 ""
9250 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
9251
9252 (define_expand "sunordered"
9253 [(set (match_operand:SI 0 "register_operand" "")
9254 (unordered:SI (reg:CC 17) (const_int 0)))]
9255 "TARGET_80387 || TARGET_SSE"
9256 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
9257
9258 (define_expand "sordered"
9259 [(set (match_operand:SI 0 "register_operand" "")
9260 (ordered:SI (reg:CC 17) (const_int 0)))]
9261 "TARGET_80387"
9262 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
9263
9264 (define_expand "suneq"
9265 [(set (match_operand:SI 0 "register_operand" "")
9266 (uneq:SI (reg:CC 17) (const_int 0)))]
9267 "TARGET_80387 || TARGET_SSE"
9268 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
9269
9270 (define_expand "sunge"
9271 [(set (match_operand:SI 0 "register_operand" "")
9272 (unge:SI (reg:CC 17) (const_int 0)))]
9273 "TARGET_80387 || TARGET_SSE"
9274 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
9275
9276 (define_expand "sungt"
9277 [(set (match_operand:SI 0 "register_operand" "")
9278 (ungt:SI (reg:CC 17) (const_int 0)))]
9279 "TARGET_80387 || TARGET_SSE"
9280 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
9281
9282 (define_expand "sunle"
9283 [(set (match_operand:SI 0 "register_operand" "")
9284 (unle:SI (reg:CC 17) (const_int 0)))]
9285 "TARGET_80387 || TARGET_SSE"
9286 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
9287
9288 (define_expand "sunlt"
9289 [(set (match_operand:SI 0 "register_operand" "")
9290 (unlt:SI (reg:CC 17) (const_int 0)))]
9291 "TARGET_80387 || TARGET_SSE"
9292 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
9293
9294 (define_expand "sltgt"
9295 [(set (match_operand:SI 0 "register_operand" "")
9296 (ltgt:SI (reg:CC 17) (const_int 0)))]
9297 "TARGET_80387 || TARGET_SSE"
9298 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
9299
9300 (define_insn "*setcc_1"
9301 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9302 (match_operator:QI 1 "ix86_comparison_operator"
9303 [(reg 17) (const_int 0)]))]
9304 ""
9305 "set%C1\\t%0"
9306 [(set_attr "type" "setcc")
9307 (set_attr "mode" "QI")])
9308
9309 (define_insn "setcc_2"
9310 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9311 (match_operator:QI 1 "ix86_comparison_operator"
9312 [(reg 17) (const_int 0)]))]
9313 ""
9314 "set%C1\\t%0"
9315 [(set_attr "type" "setcc")
9316 (set_attr "mode" "QI")])
9317
9318 \f
9319 ;; Basic conditional jump instructions.
9320 ;; We ignore the overflow flag for signed branch instructions.
9321
9322 ;; For all bCOND expanders, also expand the compare or test insn that
9323 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
9324
9325 (define_expand "beq"
9326 [(set (pc)
9327 (if_then_else (match_dup 1)
9328 (label_ref (match_operand 0 "" ""))
9329 (pc)))]
9330 ""
9331 "ix86_expand_branch (EQ, operands[0]); DONE;")
9332
9333 (define_expand "bne"
9334 [(set (pc)
9335 (if_then_else (match_dup 1)
9336 (label_ref (match_operand 0 "" ""))
9337 (pc)))]
9338 ""
9339 "ix86_expand_branch (NE, operands[0]); DONE;")
9340
9341 (define_expand "bgt"
9342 [(set (pc)
9343 (if_then_else (match_dup 1)
9344 (label_ref (match_operand 0 "" ""))
9345 (pc)))]
9346 ""
9347 "ix86_expand_branch (GT, operands[0]); DONE;")
9348
9349 (define_expand "bgtu"
9350 [(set (pc)
9351 (if_then_else (match_dup 1)
9352 (label_ref (match_operand 0 "" ""))
9353 (pc)))]
9354 ""
9355 "ix86_expand_branch (GTU, operands[0]); DONE;")
9356
9357 (define_expand "blt"
9358 [(set (pc)
9359 (if_then_else (match_dup 1)
9360 (label_ref (match_operand 0 "" ""))
9361 (pc)))]
9362 ""
9363 "ix86_expand_branch (LT, operands[0]); DONE;")
9364
9365 (define_expand "bltu"
9366 [(set (pc)
9367 (if_then_else (match_dup 1)
9368 (label_ref (match_operand 0 "" ""))
9369 (pc)))]
9370 ""
9371 "ix86_expand_branch (LTU, operands[0]); DONE;")
9372
9373 (define_expand "bge"
9374 [(set (pc)
9375 (if_then_else (match_dup 1)
9376 (label_ref (match_operand 0 "" ""))
9377 (pc)))]
9378 ""
9379 "ix86_expand_branch (GE, operands[0]); DONE;")
9380
9381 (define_expand "bgeu"
9382 [(set (pc)
9383 (if_then_else (match_dup 1)
9384 (label_ref (match_operand 0 "" ""))
9385 (pc)))]
9386 ""
9387 "ix86_expand_branch (GEU, operands[0]); DONE;")
9388
9389 (define_expand "ble"
9390 [(set (pc)
9391 (if_then_else (match_dup 1)
9392 (label_ref (match_operand 0 "" ""))
9393 (pc)))]
9394 ""
9395 "ix86_expand_branch (LE, operands[0]); DONE;")
9396
9397 (define_expand "bleu"
9398 [(set (pc)
9399 (if_then_else (match_dup 1)
9400 (label_ref (match_operand 0 "" ""))
9401 (pc)))]
9402 ""
9403 "ix86_expand_branch (LEU, operands[0]); DONE;")
9404
9405 (define_expand "bunordered"
9406 [(set (pc)
9407 (if_then_else (match_dup 1)
9408 (label_ref (match_operand 0 "" ""))
9409 (pc)))]
9410 "TARGET_80387 || TARGET_SSE"
9411 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
9412
9413 (define_expand "bordered"
9414 [(set (pc)
9415 (if_then_else (match_dup 1)
9416 (label_ref (match_operand 0 "" ""))
9417 (pc)))]
9418 "TARGET_80387 || TARGET_SSE"
9419 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
9420
9421 (define_expand "buneq"
9422 [(set (pc)
9423 (if_then_else (match_dup 1)
9424 (label_ref (match_operand 0 "" ""))
9425 (pc)))]
9426 "TARGET_80387 || TARGET_SSE"
9427 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
9428
9429 (define_expand "bunge"
9430 [(set (pc)
9431 (if_then_else (match_dup 1)
9432 (label_ref (match_operand 0 "" ""))
9433 (pc)))]
9434 "TARGET_80387 || TARGET_SSE"
9435 "ix86_expand_branch (UNGE, operands[0]); DONE;")
9436
9437 (define_expand "bungt"
9438 [(set (pc)
9439 (if_then_else (match_dup 1)
9440 (label_ref (match_operand 0 "" ""))
9441 (pc)))]
9442 "TARGET_80387 || TARGET_SSE"
9443 "ix86_expand_branch (UNGT, operands[0]); DONE;")
9444
9445 (define_expand "bunle"
9446 [(set (pc)
9447 (if_then_else (match_dup 1)
9448 (label_ref (match_operand 0 "" ""))
9449 (pc)))]
9450 "TARGET_80387 || TARGET_SSE"
9451 "ix86_expand_branch (UNLE, operands[0]); DONE;")
9452
9453 (define_expand "bunlt"
9454 [(set (pc)
9455 (if_then_else (match_dup 1)
9456 (label_ref (match_operand 0 "" ""))
9457 (pc)))]
9458 "TARGET_80387 || TARGET_SSE"
9459 "ix86_expand_branch (UNLT, operands[0]); DONE;")
9460
9461 (define_expand "bltgt"
9462 [(set (pc)
9463 (if_then_else (match_dup 1)
9464 (label_ref (match_operand 0 "" ""))
9465 (pc)))]
9466 "TARGET_80387 || TARGET_SSE"
9467 "ix86_expand_branch (LTGT, operands[0]); DONE;")
9468
9469 (define_insn "*jcc_1"
9470 [(set (pc)
9471 (if_then_else (match_operator 1 "ix86_comparison_operator"
9472 [(reg 17) (const_int 0)])
9473 (label_ref (match_operand 0 "" ""))
9474 (pc)))]
9475 ""
9476 "j%C1\\t%l0"
9477 [(set_attr "type" "ibr")
9478 (set (attr "prefix_0f")
9479 (if_then_else (and (ge (minus (match_dup 0) (pc))
9480 (const_int -128))
9481 (lt (minus (match_dup 0) (pc))
9482 (const_int 124)))
9483 (const_int 0)
9484 (const_int 1)))])
9485
9486 (define_insn "*jcc_2"
9487 [(set (pc)
9488 (if_then_else (match_operator 1 "ix86_comparison_operator"
9489 [(reg 17) (const_int 0)])
9490 (pc)
9491 (label_ref (match_operand 0 "" ""))))]
9492 ""
9493 "j%c1\\t%l0"
9494 [(set_attr "type" "ibr")
9495 (set (attr "prefix_0f")
9496 (if_then_else (and (ge (minus (match_dup 0) (pc))
9497 (const_int -128))
9498 (lt (minus (match_dup 0) (pc))
9499 (const_int 124)))
9500 (const_int 0)
9501 (const_int 1)))])
9502
9503 ;; Define combination compare-and-branch fp compare instructions to use
9504 ;; during early optimization. Splitting the operation apart early makes
9505 ;; for bad code when we want to reverse the operation.
9506
9507 (define_insn "*fp_jcc_1"
9508 [(set (pc)
9509 (if_then_else (match_operator 0 "comparison_operator"
9510 [(match_operand 1 "register_operand" "f")
9511 (match_operand 2 "register_operand" "f")])
9512 (label_ref (match_operand 3 "" ""))
9513 (pc)))
9514 (clobber (reg:CCFP 18))
9515 (clobber (reg:CCFP 17))]
9516 "TARGET_CMOVE && TARGET_80387
9517 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9518 && FLOAT_MODE_P (GET_MODE (operands[1]))
9519 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9520 "#")
9521
9522 (define_insn "*fp_jcc_1_sse"
9523 [(set (pc)
9524 (if_then_else (match_operator 0 "comparison_operator"
9525 [(match_operand 1 "register_operand" "f#x,x#f")
9526 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
9527 (label_ref (match_operand 3 "" ""))
9528 (pc)))
9529 (clobber (reg:CCFP 18))
9530 (clobber (reg:CCFP 17))]
9531 "TARGET_80387
9532 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9533 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9534 "#")
9535
9536 (define_insn "*fp_jcc_1_sse_only"
9537 [(set (pc)
9538 (if_then_else (match_operator 0 "comparison_operator"
9539 [(match_operand 1 "register_operand" "x")
9540 (match_operand 2 "nonimmediate_operand" "xm")])
9541 (label_ref (match_operand 3 "" ""))
9542 (pc)))
9543 (clobber (reg:CCFP 18))
9544 (clobber (reg:CCFP 17))]
9545 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9546 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9547 "#")
9548
9549 (define_insn "*fp_jcc_2"
9550 [(set (pc)
9551 (if_then_else (match_operator 0 "comparison_operator"
9552 [(match_operand 1 "register_operand" "f")
9553 (match_operand 2 "register_operand" "f")])
9554 (pc)
9555 (label_ref (match_operand 3 "" ""))))
9556 (clobber (reg:CCFP 18))
9557 (clobber (reg:CCFP 17))]
9558 "TARGET_CMOVE && TARGET_80387
9559 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9560 && FLOAT_MODE_P (GET_MODE (operands[1]))
9561 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9562 "#")
9563
9564 (define_insn "*fp_jcc_2_sse"
9565 [(set (pc)
9566 (if_then_else (match_operator 0 "comparison_operator"
9567 [(match_operand 1 "register_operand" "f#x,x#f")
9568 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
9569 (pc)
9570 (label_ref (match_operand 3 "" ""))))
9571 (clobber (reg:CCFP 18))
9572 (clobber (reg:CCFP 17))]
9573 "TARGET_80387
9574 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9575 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9576 "#")
9577
9578 (define_insn "*fp_jcc_2_sse_only"
9579 [(set (pc)
9580 (if_then_else (match_operator 0 "comparison_operator"
9581 [(match_operand 1 "register_operand" "x")
9582 (match_operand 2 "nonimmediate_operand" "xm")])
9583 (pc)
9584 (label_ref (match_operand 3 "" ""))))
9585 (clobber (reg:CCFP 18))
9586 (clobber (reg:CCFP 17))]
9587 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9588 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9589 "#")
9590
9591 (define_insn "*fp_jcc_3"
9592 [(set (pc)
9593 (if_then_else (match_operator 0 "comparison_operator"
9594 [(match_operand 1 "register_operand" "f")
9595 (match_operand 2 "nonimmediate_operand" "fm")])
9596 (label_ref (match_operand 3 "" ""))
9597 (pc)))
9598 (clobber (reg:CCFP 18))
9599 (clobber (reg:CCFP 17))
9600 (clobber (match_scratch:HI 4 "=a"))]
9601 "TARGET_80387
9602 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
9603 && GET_MODE (operands[1]) == GET_MODE (operands[2])
9604 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9605 && SELECT_CC_MODE (GET_CODE (operands[0]),
9606 operands[1], operands[2]) == CCFPmode"
9607 "#")
9608
9609 (define_insn "*fp_jcc_4"
9610 [(set (pc)
9611 (if_then_else (match_operator 0 "comparison_operator"
9612 [(match_operand 1 "register_operand" "f")
9613 (match_operand 2 "nonimmediate_operand" "fm")])
9614 (pc)
9615 (label_ref (match_operand 3 "" ""))))
9616 (clobber (reg:CCFP 18))
9617 (clobber (reg:CCFP 17))
9618 (clobber (match_scratch:HI 4 "=a"))]
9619 "TARGET_80387
9620 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
9621 && GET_MODE (operands[1]) == GET_MODE (operands[2])
9622 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9623 && SELECT_CC_MODE (GET_CODE (operands[0]),
9624 operands[1], operands[2]) == CCFPmode"
9625 "#")
9626
9627 (define_insn "*fp_jcc_5"
9628 [(set (pc)
9629 (if_then_else (match_operator 0 "comparison_operator"
9630 [(match_operand 1 "register_operand" "f")
9631 (match_operand 2 "register_operand" "f")])
9632 (label_ref (match_operand 3 "" ""))
9633 (pc)))
9634 (clobber (reg:CCFP 18))
9635 (clobber (reg:CCFP 17))
9636 (clobber (match_scratch:HI 4 "=a"))]
9637 "TARGET_80387
9638 && FLOAT_MODE_P (GET_MODE (operands[1]))
9639 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9640 "#")
9641
9642 (define_insn "*fp_jcc_6"
9643 [(set (pc)
9644 (if_then_else (match_operator 0 "comparison_operator"
9645 [(match_operand 1 "register_operand" "f")
9646 (match_operand 2 "register_operand" "f")])
9647 (pc)
9648 (label_ref (match_operand 3 "" ""))))
9649 (clobber (reg:CCFP 18))
9650 (clobber (reg:CCFP 17))
9651 (clobber (match_scratch:HI 4 "=a"))]
9652 "TARGET_80387
9653 && FLOAT_MODE_P (GET_MODE (operands[1]))
9654 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9655 "#")
9656
9657 (define_split
9658 [(set (pc)
9659 (if_then_else (match_operator 0 "comparison_operator"
9660 [(match_operand 1 "register_operand" "")
9661 (match_operand 2 "nonimmediate_operand" "")])
9662 (match_operand 3 "" "")
9663 (match_operand 4 "" "")))
9664 (clobber (reg:CCFP 18))
9665 (clobber (reg:CCFP 17))]
9666 "reload_completed"
9667 [(const_int 0)]
9668 "
9669 {
9670 ix86_split_fp_branch (operands[0], operands[1], operands[2],
9671 operands[3], operands[4], NULL_RTX);
9672 DONE;
9673 }")
9674
9675 (define_split
9676 [(set (pc)
9677 (if_then_else (match_operator 0 "comparison_operator"
9678 [(match_operand 1 "register_operand" "")
9679 (match_operand 2 "nonimmediate_operand" "")])
9680 (match_operand 3 "" "")
9681 (match_operand 4 "" "")))
9682 (clobber (reg:CCFP 18))
9683 (clobber (reg:CCFP 17))
9684 (clobber (match_scratch:HI 5 "=a"))]
9685 "reload_completed"
9686 [(set (pc)
9687 (if_then_else (match_dup 6)
9688 (match_dup 3)
9689 (match_dup 4)))]
9690 "
9691 {
9692 ix86_split_fp_branch (operands[0], operands[1], operands[2],
9693 operands[3], operands[4], operands[5]);
9694 DONE;
9695 }")
9696 \f
9697 ;; Unconditional and other jump instructions
9698
9699 (define_insn "jump"
9700 [(set (pc)
9701 (label_ref (match_operand 0 "" "")))]
9702 ""
9703 "jmp\\t%l0"
9704 [(set_attr "type" "ibr")])
9705
9706 (define_insn "indirect_jump"
9707 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
9708 ""
9709 "jmp\\t%A0"
9710 [(set_attr "type" "ibr")
9711 (set_attr "length_immediate" "0")])
9712
9713 (define_insn "tablejump"
9714 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
9715 (use (label_ref (match_operand 1 "" "")))]
9716 "! flag_pic"
9717 "jmp\\t%A0"
9718 [(set_attr "type" "ibr")
9719 (set_attr "length_immediate" "0")])
9720
9721 ;; Implement switch statements when generating PIC code. Switches are
9722 ;; implemented by `tablejump' when not using -fpic.
9723 ;;
9724 ;; Emit code here to do the range checking and make the index zero based.
9725 ;;
9726 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
9727 ;; two rules below:
9728 ;;
9729 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
9730 ;;
9731 ;; 1. An expression involving an external reference may only use the
9732 ;; addition operator, and only with an assembly-time constant.
9733 ;; The example above satisfies this because ".-.L2" is a constant.
9734 ;;
9735 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
9736 ;; given the value of "GOT - .", where GOT is the actual address of
9737 ;; the Global Offset Table. Therefore, the .long above actually
9738 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
9739 ;; expression "GOT - .L2" by itself would generate an error from as(1).
9740 ;;
9741 ;; The pattern below emits code that looks like this:
9742 ;;
9743 ;; movl %ebx,reg
9744 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
9745 ;; jmp reg
9746 ;;
9747 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
9748 ;; the addr_diff_vec is known to be part of this module.
9749 ;;
9750 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
9751 ;; evaluates to just ".L2".
9752
9753 (define_expand "casesi"
9754 [(set (match_dup 5)
9755 (match_operand:SI 0 "general_operand" ""))
9756 (parallel [(set (match_dup 6)
9757 (minus:SI (match_dup 5)
9758 (match_operand:SI 1 "general_operand" "")))
9759 (clobber (reg:CC 17))])
9760 (set (reg:CC 17)
9761 (compare:CC (match_dup 6)
9762 (match_operand:SI 2 "general_operand" "")))
9763 (set (pc)
9764 (if_then_else (gtu (reg:CC 17)
9765 (const_int 0))
9766 (label_ref (match_operand 4 "" ""))
9767 (pc)))
9768 (parallel
9769 [(set (match_dup 7)
9770 (minus:SI (match_dup 8)
9771 (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
9772 (match_dup 8))
9773 (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
9774 (clobber (reg:CC 17))])
9775 (parallel [(set (pc) (match_dup 7))
9776 (use (label_ref (match_dup 3)))])]
9777 "flag_pic"
9778 "
9779 {
9780 operands[5] = gen_reg_rtx (SImode);
9781 operands[6] = gen_reg_rtx (SImode);
9782 operands[7] = gen_reg_rtx (SImode);
9783 operands[8] = pic_offset_table_rtx;
9784 current_function_uses_pic_offset_table = 1;
9785 }")
9786
9787 (define_insn "*tablejump_pic"
9788 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
9789 (use (label_ref (match_operand 1 "" "")))]
9790 ""
9791 "jmp\\t%A0"
9792 [(set_attr "type" "ibr")
9793 (set_attr "length_immediate" "0")])
9794 \f
9795 ;; Loop instruction
9796 ;;
9797 ;; This is all complicated by the fact that since this is a jump insn
9798 ;; we must handle our own reloads.
9799
9800 (define_expand "doloop_end"
9801 [(use (match_operand 0 "" "")) ; loop pseudo
9802 (use (match_operand 1 "" "")) ; iterations; zero if unknown
9803 (use (match_operand 2 "" "")) ; max iterations
9804 (use (match_operand 3 "" "")) ; loop level
9805 (use (match_operand 4 "" ""))] ; label
9806 "TARGET_USE_LOOP"
9807 "
9808 {
9809 /* Only use cloop on innermost loops. */
9810 if (INTVAL (operands[3]) > 1)
9811 FAIL;
9812 if (GET_MODE (operands[0]) != SImode)
9813 FAIL;
9814 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
9815 operands[0]));
9816 DONE;
9817 }")
9818
9819 (define_insn "doloop_end_internal"
9820 [(set (pc)
9821 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
9822 (const_int 1))
9823 (label_ref (match_operand 0 "" ""))
9824 (pc)))
9825 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
9826 (plus:SI (match_dup 1)
9827 (const_int -1)))
9828 (clobber (match_scratch:SI 3 "=X,X,r"))
9829 (clobber (reg:CC 17))]
9830 "TARGET_USE_LOOP"
9831 "*
9832 {
9833 if (which_alternative != 0)
9834 return \"#\";
9835 if (get_attr_length (insn) == 2)
9836 return \"loop\\t%l0\";
9837 else
9838 return \"dec{l}\\t%1\;jne\\t%l0\";
9839 }"
9840 [(set_attr "ppro_uops" "many")
9841 (set (attr "type")
9842 (if_then_else (and (eq_attr "alternative" "0")
9843 (and (ge (minus (match_dup 0) (pc))
9844 (const_int -128))
9845 (lt (minus (match_dup 0) (pc))
9846 (const_int 124))))
9847 (const_string "ibr")
9848 (const_string "multi")))])
9849
9850 (define_split
9851 [(set (pc)
9852 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
9853 (const_int 1))
9854 (match_operand 0 "" "")
9855 (pc)))
9856 (set (match_dup 1)
9857 (plus:SI (match_dup 1)
9858 (const_int -1)))
9859 (clobber (match_scratch:SI 2 ""))
9860 (clobber (reg:CC 17))]
9861 "TARGET_USE_LOOP
9862 && reload_completed
9863 && REGNO (operands[1]) != 2"
9864 [(parallel [(set (reg:CCZ 17)
9865 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
9866 (const_int 0)))
9867 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
9868 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
9869 (match_dup 0)
9870 (pc)))]
9871 "")
9872
9873 (define_split
9874 [(set (pc)
9875 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
9876 (const_int 1))
9877 (match_operand 0 "" "")
9878 (pc)))
9879 (set (match_operand:SI 2 "nonimmediate_operand" "")
9880 (plus:SI (match_dup 1)
9881 (const_int -1)))
9882 (clobber (match_scratch:SI 3 ""))
9883 (clobber (reg:CC 17))]
9884 "TARGET_USE_LOOP
9885 && reload_completed
9886 && (! REG_P (operands[2])
9887 || ! rtx_equal_p (operands[1], operands[2]))"
9888 [(set (match_dup 3) (match_dup 1))
9889 (parallel [(set (reg:CCZ 17)
9890 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
9891 (const_int 0)))
9892 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9893 (set (match_dup 2) (match_dup 3))
9894 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
9895 (match_dup 0)
9896 (pc)))]
9897 "")
9898 \f
9899 ;; Call instructions.
9900
9901 ;; The predicates normally associated with named expanders are not properly
9902 ;; checked for calls. This is a bug in the generic code, but it isn't that
9903 ;; easy to fix. Ignore it for now and be prepared to fix things up.
9904
9905 ;; Call subroutine returning no value.
9906
9907 (define_expand "call_pop"
9908 [(parallel [(call (match_operand:QI 0 "" "")
9909 (match_operand:SI 1 "" ""))
9910 (set (reg:SI 7)
9911 (plus:SI (reg:SI 7)
9912 (match_operand:SI 3 "" "")))])]
9913 ""
9914 "
9915 {
9916 if (operands[3] == const0_rtx)
9917 {
9918 emit_insn (gen_call (operands[0], operands[1]));
9919 DONE;
9920 }
9921 /* Static functions and indirect calls don't need
9922 current_function_uses_pic_offset_table. */
9923 if (flag_pic
9924 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9925 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
9926 current_function_uses_pic_offset_table = 1;
9927 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
9928 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9929 }")
9930
9931 (define_insn "*call_pop_0"
9932 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
9933 (match_operand:SI 1 "" ""))
9934 (set (reg:SI 7) (plus:SI (reg:SI 7)
9935 (match_operand:SI 2 "immediate_operand" "")))]
9936 ""
9937 "*
9938 {
9939 if (SIBLING_CALL_P (insn))
9940 return \"jmp\\t%P0\";
9941 else
9942 return \"call\\t%P0\";
9943 }"
9944 [(set_attr "type" "call")])
9945
9946 (define_insn "*call_pop_1"
9947 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
9948 (match_operand:SI 1 "" ""))
9949 (set (reg:SI 7) (plus:SI (reg:SI 7)
9950 (match_operand:SI 2 "immediate_operand" "i")))]
9951 ""
9952 "*
9953 {
9954 if (constant_call_address_operand (operands[0], Pmode))
9955 {
9956 if (SIBLING_CALL_P (insn))
9957 return \"jmp\\t%P0\";
9958 else
9959 return \"call\\t%P0\";
9960 }
9961 if (SIBLING_CALL_P (insn))
9962 return \"jmp\\t%A0\";
9963 else
9964 return \"call\\t%A0\";
9965 }"
9966 [(set_attr "type" "call")])
9967
9968 (define_expand "call"
9969 [(call (match_operand:QI 0 "" "")
9970 (match_operand:SI 1 "" ""))]
9971 ;; Operand 1 not used on the i386.
9972 ""
9973 "
9974 {
9975 /* Static functions and indirect calls don't need
9976 current_function_uses_pic_offset_table. */
9977 if (flag_pic
9978 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9979 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
9980 current_function_uses_pic_offset_table = 1;
9981 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
9982 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9983 }")
9984
9985 (define_insn "*call_0"
9986 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
9987 (match_operand:SI 1 "" ""))]
9988 ""
9989 "*
9990 {
9991 if (SIBLING_CALL_P (insn))
9992 return \"jmp\\t%P0\";
9993 else
9994 return \"call\\t%P0\";
9995 }"
9996 [(set_attr "type" "call")])
9997
9998 (define_insn "*call_1"
9999 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
10000 (match_operand:SI 1 "" ""))]
10001 ""
10002 "*
10003 {
10004 if (constant_call_address_operand (operands[0], QImode))
10005 {
10006 if (SIBLING_CALL_P (insn))
10007 return \"jmp\\t%P0\";
10008 else
10009 return \"call\\t%P0\";
10010 }
10011 if (SIBLING_CALL_P (insn))
10012 return \"jmp\\t%A0\";
10013 else
10014 return \"call\\t%A0\";
10015 }"
10016 [(set_attr "type" "call")])
10017
10018 ;; Call subroutine, returning value in operand 0
10019 ;; (which must be a hard register).
10020
10021 (define_expand "call_value_pop"
10022 [(parallel [(set (match_operand 0 "" "")
10023 (call (match_operand:QI 1 "" "")
10024 (match_operand:SI 2 "" "")))
10025 (set (reg:SI 7)
10026 (plus:SI (reg:SI 7)
10027 (match_operand:SI 4 "" "")))])]
10028 ""
10029 "
10030 {
10031 if (operands[4] == const0_rtx)
10032 {
10033 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
10034 DONE;
10035 }
10036 /* Static functions and indirect calls don't need
10037 current_function_uses_pic_offset_table. */
10038 if (flag_pic
10039 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10040 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
10041 current_function_uses_pic_offset_table = 1;
10042 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
10043 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
10044 }")
10045
10046 (define_expand "call_value"
10047 [(set (match_operand 0 "" "")
10048 (call (match_operand:QI 1 "" "")
10049 (match_operand:SI 2 "" "")))]
10050 ;; Operand 2 not used on the i386.
10051 ""
10052 "
10053 {
10054 /* Static functions and indirect calls don't need
10055 current_function_uses_pic_offset_table. */
10056 if (flag_pic
10057 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10058 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
10059 current_function_uses_pic_offset_table = 1;
10060 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
10061 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
10062 }")
10063
10064 ;; Call subroutine returning any type.
10065
10066 (define_expand "untyped_call"
10067 [(parallel [(call (match_operand 0 "" "")
10068 (const_int 0))
10069 (match_operand 1 "" "")
10070 (match_operand 2 "" "")])]
10071 ""
10072 "
10073 {
10074 int i;
10075
10076 /* In order to give reg-stack an easier job in validating two
10077 coprocessor registers as containing a possible return value,
10078 simply pretend the untyped call returns a complex long double
10079 value. */
10080
10081 emit_call_insn (TARGET_80387
10082 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
10083 operands[0], const0_rtx)
10084 : gen_call (operands[0], const0_rtx));
10085
10086 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10087 {
10088 rtx set = XVECEXP (operands[2], 0, i);
10089 emit_move_insn (SET_DEST (set), SET_SRC (set));
10090 }
10091
10092 /* The optimizer does not know that the call sets the function value
10093 registers we stored in the result block. We avoid problems by
10094 claiming that all hard registers are used and clobbered at this
10095 point. */
10096 emit_insn (gen_blockage ());
10097
10098 DONE;
10099 }")
10100 \f
10101 ;; Prologue and epilogue instructions
10102
10103 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10104 ;; all of memory. This blocks insns from being moved across this point.
10105
10106 (define_insn "blockage"
10107 [(unspec_volatile [(const_int 0)] 0)]
10108 ""
10109 ""
10110 [(set_attr "length" "0")])
10111
10112 ;; Insn emitted into the body of a function to return from a function.
10113 ;; This is only done if the function's epilogue is known to be simple.
10114 ;; See comments for ix86_can_use_return_insn_p in i386.c.
10115
10116 (define_expand "return"
10117 [(return)]
10118 "ix86_can_use_return_insn_p ()"
10119 "
10120 {
10121 if (current_function_pops_args)
10122 {
10123 rtx popc = GEN_INT (current_function_pops_args);
10124 emit_jump_insn (gen_return_pop_internal (popc));
10125 DONE;
10126 }
10127 }")
10128
10129 (define_insn "return_internal"
10130 [(return)]
10131 "reload_completed"
10132 "ret"
10133 [(set_attr "length" "1")
10134 (set_attr "length_immediate" "0")
10135 (set_attr "modrm" "0")])
10136
10137 (define_insn "return_pop_internal"
10138 [(return)
10139 (use (match_operand:SI 0 "const_int_operand" ""))]
10140 "reload_completed"
10141 "ret\\t%0"
10142 [(set_attr "length" "3")
10143 (set_attr "length_immediate" "2")
10144 (set_attr "modrm" "0")])
10145
10146 (define_insn "return_indirect_internal"
10147 [(return)
10148 (use (match_operand:SI 0 "register_operand" "r"))]
10149 "reload_completed"
10150 "jmp\\t%A0"
10151 [(set_attr "type" "ibr")
10152 (set_attr "length_immediate" "0")])
10153
10154 (define_insn "nop"
10155 [(const_int 0)]
10156 ""
10157 "nop"
10158 [(set_attr "length" "1")
10159 (set_attr "length_immediate" "0")
10160 (set_attr "modrm" "0")
10161 (set_attr "ppro_uops" "one")])
10162
10163 (define_expand "prologue"
10164 [(const_int 1)]
10165 ""
10166 "ix86_expand_prologue (); DONE;")
10167
10168 (define_insn "prologue_set_got"
10169 [(set (match_operand:SI 0 "register_operand" "=r")
10170 (unspec_volatile:SI
10171 [(plus:SI (match_dup 0)
10172 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
10173 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
10174 (clobber (reg:CC 17))]
10175 ""
10176 "*
10177 {
10178 if (GET_CODE (operands[2]) == LABEL_REF)
10179 operands[2] = XEXP (operands[2], 0);
10180 if (TARGET_DEEP_BRANCH_PREDICTION)
10181 return \"add{l}\\t{%1, %0|%0, %1}\";
10182 else
10183 return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
10184 }"
10185 [(set_attr "type" "alu")
10186 ; Since this insn may have two constant operands, we must set the
10187 ; length manually.
10188 (set_attr "length_immediate" "4")
10189 (set_attr "mode" "SI")])
10190
10191 (define_insn "prologue_get_pc"
10192 [(set (match_operand:SI 0 "register_operand" "=r")
10193 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
10194 ""
10195 "*
10196 {
10197 if (GET_CODE (operands[1]) == LABEL_REF)
10198 operands[1] = XEXP (operands[1], 0);
10199 output_asm_insn (\"call\\t%X1\", operands);
10200 if (! TARGET_DEEP_BRANCH_PREDICTION)
10201 {
10202 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
10203 CODE_LABEL_NUMBER (operands[1]));
10204 }
10205 RET;
10206 }"
10207 [(set_attr "type" "multi")])
10208
10209 (define_expand "epilogue"
10210 [(const_int 1)]
10211 ""
10212 "ix86_expand_epilogue (1); DONE;")
10213
10214 (define_expand "sibcall_epilogue"
10215 [(const_int 1)]
10216 ""
10217 "ix86_expand_epilogue (0); DONE;")
10218
10219 (define_insn "leave"
10220 [(set (reg:SI 7) (reg:SI 6))
10221 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
10222 ""
10223 "leave"
10224 [(set_attr "length_immediate" "0")
10225 (set_attr "length" "1")
10226 (set_attr "modrm" "0")
10227 (set_attr "modrm" "0")
10228 (set_attr "athlon_decode" "vector")
10229 (set_attr "ppro_uops" "few")])
10230 \f
10231 (define_expand "ffssi2"
10232 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10233 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
10234 ""
10235 "
10236 {
10237 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
10238 rtx in = operands[1];
10239
10240 if (TARGET_CMOVE)
10241 {
10242 emit_move_insn (tmp, constm1_rtx);
10243 emit_insn (gen_ffssi_1 (out, in));
10244 emit_insn (gen_rtx_SET (VOIDmode, out,
10245 gen_rtx_IF_THEN_ELSE (SImode,
10246 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
10247 const0_rtx),
10248 tmp,
10249 out)));
10250 emit_insn (gen_addsi3 (out, out, const1_rtx));
10251 emit_move_insn (operands[0], out);
10252 }
10253
10254 /* Pentium bsf instruction is extremly slow. The following code is
10255 recommended by the Intel Optimizing Manual as a reasonable replacement:
10256 TEST EAX,EAX
10257 JZ SHORT BS2
10258 XOR ECX,ECX
10259 MOV DWORD PTR [TEMP+4],ECX
10260 SUB ECX,EAX
10261 AND EAX,ECX
10262 MOV DWORD PTR [TEMP],EAX
10263 FILD QWORD PTR [TEMP]
10264 FSTP QWORD PTR [TEMP]
10265 WAIT ; WAIT only needed for compatibility with
10266 ; earlier processors
10267 MOV ECX, DWORD PTR [TEMP+4]
10268 SHR ECX,20
10269 SUB ECX,3FFH
10270 TEST EAX,EAX ; clear zero flag
10271 BS2:
10272 Following piece of code expand ffs to similar beast.
10273 */
10274
10275 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
10276 {
10277 rtx label = gen_label_rtx ();
10278 rtx lo, hi;
10279 rtx mem = assign_386_stack_local (DImode, 0);
10280 rtx fptmp = gen_reg_rtx (DFmode);
10281 split_di (&mem, 1, &lo, &hi);
10282
10283 emit_move_insn (out, const0_rtx);
10284
10285 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
10286
10287 emit_move_insn (hi, out);
10288 emit_insn (gen_subsi3 (out, out, in));
10289 emit_insn (gen_andsi3 (out, out, in));
10290 emit_move_insn (lo, out);
10291 emit_insn (gen_floatdidf2 (fptmp,mem));
10292 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
10293 emit_move_insn (out, hi);
10294 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
10295 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
10296
10297 emit_label (label);
10298 LABEL_NUSES (label) = 1;
10299
10300 emit_move_insn (operands[0], out);
10301 }
10302 else
10303 {
10304 emit_move_insn (tmp, const0_rtx);
10305 emit_insn (gen_ffssi_1 (out, in));
10306 emit_insn (gen_rtx_SET (VOIDmode,
10307 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
10308 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
10309 const0_rtx)));
10310 emit_insn (gen_negsi2 (tmp, tmp));
10311 emit_insn (gen_iorsi3 (out, out, tmp));
10312 emit_insn (gen_addsi3 (out, out, const1_rtx));
10313 emit_move_insn (operands[0], out);
10314 }
10315 DONE;
10316 }")
10317
10318 (define_insn "ffssi_1"
10319 [(set (reg:CCZ 17)
10320 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
10321 (const_int 0)))
10322 (set (match_operand:SI 0 "register_operand" "=r")
10323 (unspec:SI [(match_dup 1)] 5))]
10324 ""
10325 "bsf{l}\\t{%1, %0|%0, %1}"
10326 [(set_attr "prefix_0f" "1")
10327 (set_attr "ppro_uops" "few")])
10328
10329 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
10330 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
10331 \f
10332 ;; These patterns match the binary 387 instructions for addM3, subM3,
10333 ;; mulM3 and divM3. There are three patterns for each of DFmode and
10334 ;; SFmode. The first is the normal insn, the second the same insn but
10335 ;; with one operand a conversion, and the third the same insn but with
10336 ;; the other operand a conversion. The conversion may be SFmode or
10337 ;; SImode if the target mode DFmode, but only SImode if the target mode
10338 ;; is SFmode.
10339
10340 ;; Gcc is slightly more smart about handling normal two address instructions
10341 ;; so use special patterns for add and mull.
10342 (define_insn "*fop_sf_comm"
10343 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
10344 (match_operator:SF 3 "binary_fp_operator"
10345 [(match_operand:SF 1 "register_operand" "%0,0")
10346 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
10347 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
10348 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10349 "* return output_387_binary_op (insn, operands);"
10350 [(set (attr "type")
10351 (if_then_else (eq_attr "alternative" "1")
10352 (const_string "sse")
10353 (if_then_else (match_operand:SF 3 "mult_operator" "")
10354 (const_string "fmul")
10355 (const_string "fop"))))
10356 (set_attr "mode" "SF")])
10357
10358 (define_insn "*fop_sf_comm_sse"
10359 [(set (match_operand:SF 0 "register_operand" "=x")
10360 (match_operator:SF 3 "binary_fp_operator"
10361 [(match_operand:SF 1 "register_operand" "%0")
10362 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
10363 "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10364 "* return output_387_binary_op (insn, operands);"
10365 [(set_attr "type" "sse")
10366 (set_attr "mode" "SF")])
10367
10368 (define_insn "*fop_df_comm"
10369 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
10370 (match_operator:DF 3 "binary_fp_operator"
10371 [(match_operand:DF 1 "register_operand" "%0,0")
10372 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
10373 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
10374 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10375 "* return output_387_binary_op (insn, operands);"
10376 [(set (attr "type")
10377 (if_then_else (eq_attr "alternative" "1")
10378 (const_string "sse")
10379 (if_then_else (match_operand:SF 3 "mult_operator" "")
10380 (const_string "fmul")
10381 (const_string "fop"))))
10382 (set_attr "mode" "DF")])
10383
10384 (define_insn "*fop_df_comm_sse"
10385 [(set (match_operand:DF 0 "register_operand" "=Y")
10386 (match_operator:DF 3 "binary_fp_operator"
10387 [(match_operand:DF 1 "register_operand" "%0")
10388 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
10389 "TARGET_SSE2
10390 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10391 "* return output_387_binary_op (insn, operands);"
10392 [(set_attr "type" "sse")
10393 (set_attr "mode" "DF")])
10394
10395 (define_insn "*fop_xf_comm"
10396 [(set (match_operand:XF 0 "register_operand" "=f")
10397 (match_operator:XF 3 "binary_fp_operator"
10398 [(match_operand:XF 1 "register_operand" "%0")
10399 (match_operand:XF 2 "register_operand" "f")]))]
10400 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10401 "* return output_387_binary_op (insn, operands);"
10402 [(set (attr "type")
10403 (if_then_else (match_operand:XF 3 "mult_operator" "")
10404 (const_string "fmul")
10405 (const_string "fop")))
10406 (set_attr "mode" "XF")])
10407
10408 (define_insn "*fop_tf_comm"
10409 [(set (match_operand:TF 0 "register_operand" "=f")
10410 (match_operator:TF 3 "binary_fp_operator"
10411 [(match_operand:TF 1 "register_operand" "%0")
10412 (match_operand:TF 2 "register_operand" "f")]))]
10413 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10414 "* return output_387_binary_op (insn, operands);"
10415 [(set (attr "type")
10416 (if_then_else (match_operand:TF 3 "mult_operator" "")
10417 (const_string "fmul")
10418 (const_string "fop")))
10419 (set_attr "mode" "XF")])
10420
10421 (define_insn "*fop_sf_1"
10422 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
10423 (match_operator:SF 3 "binary_fp_operator"
10424 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
10425 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
10426 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
10427 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
10428 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10429 "* return output_387_binary_op (insn, operands);"
10430 [(set (attr "type")
10431 (cond [(eq_attr "alternative" "2")
10432 (const_string "sse")
10433 (match_operand:SF 3 "mult_operator" "")
10434 (const_string "fmul")
10435 (match_operand:SF 3 "div_operator" "")
10436 (const_string "fdiv")
10437 ]
10438 (const_string "fop")))
10439 (set_attr "mode" "SF")])
10440
10441 (define_insn "*fop_sf_1_sse"
10442 [(set (match_operand:SF 0 "register_operand" "=x")
10443 (match_operator:SF 3 "binary_fp_operator"
10444 [(match_operand:SF 1 "register_operand" "0")
10445 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
10446 "TARGET_SSE
10447 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10448 "* return output_387_binary_op (insn, operands);"
10449 [(set_attr "type" "sse")
10450 (set_attr "mode" "SF")])
10451
10452 ;; ??? Add SSE splitters for these!
10453 (define_insn "*fop_sf_2"
10454 [(set (match_operand:SF 0 "register_operand" "=f,f")
10455 (match_operator:SF 3 "binary_fp_operator"
10456 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10457 (match_operand:SF 2 "register_operand" "0,0")]))]
10458 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
10459 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10460 [(set (attr "type")
10461 (cond [(match_operand:SF 3 "mult_operator" "")
10462 (const_string "fmul")
10463 (match_operand:SF 3 "div_operator" "")
10464 (const_string "fdiv")
10465 ]
10466 (const_string "fop")))
10467 (set_attr "fp_int_src" "true")
10468 (set_attr "ppro_uops" "many")
10469 (set_attr "mode" "SI")])
10470
10471 (define_insn "*fop_sf_3"
10472 [(set (match_operand:SF 0 "register_operand" "=f,f")
10473 (match_operator:SF 3 "binary_fp_operator"
10474 [(match_operand:SF 1 "register_operand" "0,0")
10475 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10476 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
10477 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10478 [(set (attr "type")
10479 (cond [(match_operand:SF 3 "mult_operator" "")
10480 (const_string "fmul")
10481 (match_operand:SF 3 "div_operator" "")
10482 (const_string "fdiv")
10483 ]
10484 (const_string "fop")))
10485 (set_attr "fp_int_src" "true")
10486 (set_attr "ppro_uops" "many")
10487 (set_attr "mode" "SI")])
10488
10489 (define_insn "*fop_df_1"
10490 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
10491 (match_operator:DF 3 "binary_fp_operator"
10492 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
10493 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
10494 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
10495 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
10496 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10497 "* return output_387_binary_op (insn, operands);"
10498 [(set (attr "type")
10499 (cond [(eq_attr "alternative" "2")
10500 (const_string "sse")
10501 (match_operand:DF 3 "mult_operator" "")
10502 (const_string "fmul")
10503 (match_operand:DF 3 "div_operator" "")
10504 (const_string "fdiv")
10505 ]
10506 (const_string "fop")))
10507 (set_attr "mode" "DF")])
10508
10509 (define_insn "*fop_df_1_sse"
10510 [(set (match_operand:DF 0 "register_operand" "=Y")
10511 (match_operator:DF 3 "binary_fp_operator"
10512 [(match_operand:DF 1 "register_operand" "0")
10513 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
10514 "TARGET_SSE
10515 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10516 "* return output_387_binary_op (insn, operands);"
10517 [(set_attr "type" "sse")])
10518
10519 ;; ??? Add SSE splitters for these!
10520 (define_insn "*fop_df_2"
10521 [(set (match_operand:DF 0 "register_operand" "=f,f")
10522 (match_operator:DF 3 "binary_fp_operator"
10523 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10524 (match_operand:DF 2 "register_operand" "0,0")]))]
10525 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
10526 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10527 [(set (attr "type")
10528 (cond [(match_operand:DF 3 "mult_operator" "")
10529 (const_string "fmul")
10530 (match_operand:DF 3 "div_operator" "")
10531 (const_string "fdiv")
10532 ]
10533 (const_string "fop")))
10534 (set_attr "fp_int_src" "true")
10535 (set_attr "ppro_uops" "many")
10536 (set_attr "mode" "SI")])
10537
10538 (define_insn "*fop_df_3"
10539 [(set (match_operand:DF 0 "register_operand" "=f,f")
10540 (match_operator:DF 3 "binary_fp_operator"
10541 [(match_operand:DF 1 "register_operand" "0,0")
10542 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10543 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
10544 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10545 [(set (attr "type")
10546 (cond [(match_operand:DF 3 "mult_operator" "")
10547 (const_string "fmul")
10548 (match_operand:DF 3 "div_operator" "")
10549 (const_string "fdiv")
10550 ]
10551 (const_string "fop")))
10552 (set_attr "fp_int_src" "true")
10553 (set_attr "ppro_uops" "many")
10554 (set_attr "mode" "SI")])
10555
10556 (define_insn "*fop_df_4"
10557 [(set (match_operand:DF 0 "register_operand" "=f,f")
10558 (match_operator:DF 3 "binary_fp_operator"
10559 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10560 (match_operand:DF 2 "register_operand" "0,f")]))]
10561 "TARGET_80387
10562 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10563 "* return output_387_binary_op (insn, operands);"
10564 [(set (attr "type")
10565 (cond [(match_operand:DF 3 "mult_operator" "")
10566 (const_string "fmul")
10567 (match_operand:DF 3 "div_operator" "")
10568 (const_string "fdiv")
10569 ]
10570 (const_string "fop")))
10571 (set_attr "mode" "SF")])
10572
10573 (define_insn "*fop_df_5"
10574 [(set (match_operand:DF 0 "register_operand" "=f,f")
10575 (match_operator:DF 3 "binary_fp_operator"
10576 [(match_operand:DF 1 "register_operand" "0,f")
10577 (float_extend:DF
10578 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10579 "TARGET_80387 && !TARGET_SSE2"
10580 "* return output_387_binary_op (insn, operands);"
10581 [(set (attr "type")
10582 (cond [(match_operand:DF 3 "mult_operator" "")
10583 (const_string "fmul")
10584 (match_operand:DF 3 "div_operator" "")
10585 (const_string "fdiv")
10586 ]
10587 (const_string "fop")))
10588 (set_attr "mode" "SF")])
10589
10590 (define_insn "*fop_xf_1"
10591 [(set (match_operand:XF 0 "register_operand" "=f,f")
10592 (match_operator:XF 3 "binary_fp_operator"
10593 [(match_operand:XF 1 "register_operand" "0,f")
10594 (match_operand:XF 2 "register_operand" "f,0")]))]
10595 "TARGET_80387
10596 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10597 "* return output_387_binary_op (insn, operands);"
10598 [(set (attr "type")
10599 (cond [(match_operand:XF 3 "mult_operator" "")
10600 (const_string "fmul")
10601 (match_operand:XF 3 "div_operator" "")
10602 (const_string "fdiv")
10603 ]
10604 (const_string "fop")))
10605 (set_attr "mode" "XF")])
10606
10607 (define_insn "*fop_tf_1"
10608 [(set (match_operand:TF 0 "register_operand" "=f,f")
10609 (match_operator:TF 3 "binary_fp_operator"
10610 [(match_operand:TF 1 "register_operand" "0,f")
10611 (match_operand:TF 2 "register_operand" "f,0")]))]
10612 "TARGET_80387
10613 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10614 "* return output_387_binary_op (insn, operands);"
10615 [(set (attr "type")
10616 (cond [(match_operand:TF 3 "mult_operator" "")
10617 (const_string "fmul")
10618 (match_operand:TF 3 "div_operator" "")
10619 (const_string "fdiv")
10620 ]
10621 (const_string "fop")))
10622 (set_attr "mode" "XF")])
10623
10624 (define_insn "*fop_xf_2"
10625 [(set (match_operand:XF 0 "register_operand" "=f,f")
10626 (match_operator:XF 3 "binary_fp_operator"
10627 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10628 (match_operand:XF 2 "register_operand" "0,0")]))]
10629 "TARGET_80387 && TARGET_USE_FIOP"
10630 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10631 [(set (attr "type")
10632 (cond [(match_operand:XF 3 "mult_operator" "")
10633 (const_string "fmul")
10634 (match_operand:XF 3 "div_operator" "")
10635 (const_string "fdiv")
10636 ]
10637 (const_string "fop")))
10638 (set_attr "fp_int_src" "true")
10639 (set_attr "mode" "SI")
10640 (set_attr "ppro_uops" "many")])
10641
10642 (define_insn "*fop_tf_2"
10643 [(set (match_operand:TF 0 "register_operand" "=f,f")
10644 (match_operator:TF 3 "binary_fp_operator"
10645 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10646 (match_operand:TF 2 "register_operand" "0,0")]))]
10647 "TARGET_80387 && TARGET_USE_FIOP"
10648 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10649 [(set (attr "type")
10650 (cond [(match_operand:TF 3 "mult_operator" "")
10651 (const_string "fmul")
10652 (match_operand:TF 3 "div_operator" "")
10653 (const_string "fdiv")
10654 ]
10655 (const_string "fop")))
10656 (set_attr "fp_int_src" "true")
10657 (set_attr "mode" "SI")
10658 (set_attr "ppro_uops" "many")])
10659
10660 (define_insn "*fop_xf_3"
10661 [(set (match_operand:XF 0 "register_operand" "=f,f")
10662 (match_operator:XF 3 "binary_fp_operator"
10663 [(match_operand:XF 1 "register_operand" "0,0")
10664 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10665 "TARGET_80387 && TARGET_USE_FIOP"
10666 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10667 [(set (attr "type")
10668 (cond [(match_operand:XF 3 "mult_operator" "")
10669 (const_string "fmul")
10670 (match_operand:XF 3 "div_operator" "")
10671 (const_string "fdiv")
10672 ]
10673 (const_string "fop")))
10674 (set_attr "fp_int_src" "true")
10675 (set_attr "mode" "SI")
10676 (set_attr "ppro_uops" "many")])
10677
10678 (define_insn "*fop_tf_3"
10679 [(set (match_operand:TF 0 "register_operand" "=f,f")
10680 (match_operator:TF 3 "binary_fp_operator"
10681 [(match_operand:TF 1 "register_operand" "0,0")
10682 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10683 "TARGET_80387 && TARGET_USE_FIOP"
10684 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10685 [(set (attr "type")
10686 (cond [(match_operand:TF 3 "mult_operator" "")
10687 (const_string "fmul")
10688 (match_operand:TF 3 "div_operator" "")
10689 (const_string "fdiv")
10690 ]
10691 (const_string "fop")))
10692 (set_attr "fp_int_src" "true")
10693 (set_attr "mode" "SI")
10694 (set_attr "ppro_uops" "many")])
10695
10696 (define_insn "*fop_xf_4"
10697 [(set (match_operand:XF 0 "register_operand" "=f,f")
10698 (match_operator:XF 3 "binary_fp_operator"
10699 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10700 (match_operand:XF 2 "register_operand" "0,f")]))]
10701 "TARGET_80387"
10702 "* return output_387_binary_op (insn, operands);"
10703 [(set (attr "type")
10704 (cond [(match_operand:XF 3 "mult_operator" "")
10705 (const_string "fmul")
10706 (match_operand:XF 3 "div_operator" "")
10707 (const_string "fdiv")
10708 ]
10709 (const_string "fop")))
10710 (set_attr "mode" "SF")])
10711
10712 (define_insn "*fop_tf_4"
10713 [(set (match_operand:TF 0 "register_operand" "=f,f")
10714 (match_operator:TF 3 "binary_fp_operator"
10715 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10716 (match_operand:TF 2 "register_operand" "0,f")]))]
10717 "TARGET_80387"
10718 "* return output_387_binary_op (insn, operands);"
10719 [(set (attr "type")
10720 (cond [(match_operand:TF 3 "mult_operator" "")
10721 (const_string "fmul")
10722 (match_operand:TF 3 "div_operator" "")
10723 (const_string "fdiv")
10724 ]
10725 (const_string "fop")))
10726 (set_attr "mode" "SF")])
10727
10728 (define_insn "*fop_xf_5"
10729 [(set (match_operand:XF 0 "register_operand" "=f,f")
10730 (match_operator:XF 3 "binary_fp_operator"
10731 [(match_operand:XF 1 "register_operand" "0,f")
10732 (float_extend:XF
10733 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10734 "TARGET_80387"
10735 "* return output_387_binary_op (insn, operands);"
10736 [(set (attr "type")
10737 (cond [(match_operand:XF 3 "mult_operator" "")
10738 (const_string "fmul")
10739 (match_operand:XF 3 "div_operator" "")
10740 (const_string "fdiv")
10741 ]
10742 (const_string "fop")))
10743 (set_attr "mode" "SF")])
10744
10745 (define_insn "*fop_tf_5"
10746 [(set (match_operand:TF 0 "register_operand" "=f,f")
10747 (match_operator:TF 3 "binary_fp_operator"
10748 [(match_operand:TF 1 "register_operand" "0,f")
10749 (float_extend:TF
10750 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10751 "TARGET_80387"
10752 "* return output_387_binary_op (insn, operands);"
10753 [(set (attr "type")
10754 (cond [(match_operand:TF 3 "mult_operator" "")
10755 (const_string "fmul")
10756 (match_operand:TF 3 "div_operator" "")
10757 (const_string "fdiv")
10758 ]
10759 (const_string "fop")))
10760 (set_attr "mode" "SF")])
10761
10762 (define_insn "*fop_xf_6"
10763 [(set (match_operand:XF 0 "register_operand" "=f,f")
10764 (match_operator:XF 3 "binary_fp_operator"
10765 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
10766 (match_operand:XF 2 "register_operand" "0,f")]))]
10767 "TARGET_80387"
10768 "* return output_387_binary_op (insn, operands);"
10769 [(set (attr "type")
10770 (cond [(match_operand:XF 3 "mult_operator" "")
10771 (const_string "fmul")
10772 (match_operand:XF 3 "div_operator" "")
10773 (const_string "fdiv")
10774 ]
10775 (const_string "fop")))
10776 (set_attr "mode" "DF")])
10777
10778 (define_insn "*fop_tf_6"
10779 [(set (match_operand:TF 0 "register_operand" "=f,f")
10780 (match_operator:TF 3 "binary_fp_operator"
10781 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
10782 (match_operand:TF 2 "register_operand" "0,f")]))]
10783 "TARGET_80387"
10784 "* return output_387_binary_op (insn, operands);"
10785 [(set (attr "type")
10786 (cond [(match_operand:TF 3 "mult_operator" "")
10787 (const_string "fmul")
10788 (match_operand:TF 3 "div_operator" "")
10789 (const_string "fdiv")
10790 ]
10791 (const_string "fop")))
10792 (set_attr "mode" "DF")])
10793
10794 (define_insn "*fop_xf_7"
10795 [(set (match_operand:XF 0 "register_operand" "=f,f")
10796 (match_operator:XF 3 "binary_fp_operator"
10797 [(match_operand:XF 1 "register_operand" "0,f")
10798 (float_extend:XF
10799 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
10800 "TARGET_80387"
10801 "* return output_387_binary_op (insn, operands);"
10802 [(set (attr "type")
10803 (cond [(match_operand:XF 3 "mult_operator" "")
10804 (const_string "fmul")
10805 (match_operand:XF 3 "div_operator" "")
10806 (const_string "fdiv")
10807 ]
10808 (const_string "fop")))
10809 (set_attr "mode" "DF")])
10810
10811 (define_insn "*fop_tf_7"
10812 [(set (match_operand:TF 0 "register_operand" "=f,f")
10813 (match_operator:TF 3 "binary_fp_operator"
10814 [(match_operand:TF 1 "register_operand" "0,f")
10815 (float_extend:TF
10816 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
10817 "TARGET_80387"
10818 "* return output_387_binary_op (insn, operands);"
10819 [(set (attr "type")
10820 (cond [(match_operand:TF 3 "mult_operator" "")
10821 (const_string "fmul")
10822 (match_operand:TF 3 "div_operator" "")
10823 (const_string "fdiv")
10824 ]
10825 (const_string "fop")))
10826 (set_attr "mode" "DF")])
10827
10828 (define_split
10829 [(set (match_operand 0 "register_operand" "")
10830 (match_operator 3 "binary_fp_operator"
10831 [(float (match_operand:SI 1 "register_operand" ""))
10832 (match_operand 2 "register_operand" "")]))]
10833 "TARGET_80387 && reload_completed
10834 && FLOAT_MODE_P (GET_MODE (operands[0]))"
10835 [(const_int 0)]
10836 "
10837 {
10838 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
10839 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
10840 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
10841 gen_rtx_fmt_ee (GET_CODE (operands[3]),
10842 GET_MODE (operands[3]),
10843 operands[4],
10844 operands[2])));
10845 ix86_free_from_memory (GET_MODE (operands[1]));
10846 DONE;
10847 }")
10848
10849 (define_split
10850 [(set (match_operand 0 "register_operand" "")
10851 (match_operator 3 "binary_fp_operator"
10852 [(match_operand 1 "register_operand" "")
10853 (float (match_operand:SI 2 "register_operand" ""))]))]
10854 "TARGET_80387 && reload_completed
10855 && FLOAT_MODE_P (GET_MODE (operands[0]))"
10856 [(const_int 0)]
10857 "
10858 {
10859 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10860 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
10861 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
10862 gen_rtx_fmt_ee (GET_CODE (operands[3]),
10863 GET_MODE (operands[3]),
10864 operands[1],
10865 operands[4])));
10866 ix86_free_from_memory (GET_MODE (operands[2]));
10867 DONE;
10868 }")
10869 \f
10870 ;; FPU special functions.
10871
10872 (define_expand "sqrtsf2"
10873 [(set (match_operand:SF 0 "register_operand" "")
10874 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10875 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE"
10876 "
10877 {
10878 if (!TARGET_SSE)
10879 operands[1] = force_reg (SFmode, operands[1]);
10880 }")
10881
10882 (define_insn "sqrtsf2_1"
10883 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
10884 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
10885 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10886 && (TARGET_SSE && TARGET_MIX_SSE_I387)"
10887 "@
10888 fsqrt
10889 sqrtss\\t{%1, %0|%0, %1}"
10890 [(set_attr "type" "fpspc,sse")
10891 (set_attr "mode" "SF,SF")
10892 (set_attr "athlon_decode" "direct,*")])
10893
10894 (define_insn "sqrtsf2_1_sse_only"
10895 [(set (match_operand:SF 0 "register_operand" "=x")
10896 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
10897 "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
10898 "sqrtss\\t{%1, %0|%0, %1}"
10899 [(set_attr "type" "sse")
10900 (set_attr "mode" "SF")
10901 (set_attr "athlon_decode" "*")])
10902
10903 (define_insn "sqrtsf2_i387"
10904 [(set (match_operand:SF 0 "register_operand" "=f")
10905 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
10906 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10907 && (!TARGET_SSE && !TARGET_MIX_SSE_I387)"
10908 "fsqrt"
10909 [(set_attr "type" "fpspc")
10910 (set_attr "mode" "SF")
10911 (set_attr "athlon_decode" "direct")])
10912
10913 (define_expand "sqrtdf2"
10914 [(set (match_operand:DF 0 "register_operand" "")
10915 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10916 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
10917 "
10918 {
10919 if (!TARGET_SSE2)
10920 operands[1] = force_reg (SFmode, operands[1]);
10921 }")
10922
10923 (define_insn "sqrtdf2_1"
10924 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
10925 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
10926 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10927 && (TARGET_SSE2 && TARGET_MIX_SSE_I387)"
10928 "@
10929 fsqrt
10930 sqrtsd\\t{%1, %0|%0, %1}"
10931 [(set_attr "type" "fpspc,sse")
10932 (set_attr "mode" "DF,DF")
10933 (set_attr "athlon_decode" "direct,*")])
10934
10935 (define_insn "sqrtdf2_1_sse_only"
10936 [(set (match_operand:DF 0 "register_operand" "=Y")
10937 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
10938 "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
10939 "sqrtsd\\t{%1, %0|%0, %1}"
10940 [(set_attr "type" "sse")
10941 (set_attr "mode" "DF")
10942 (set_attr "athlon_decode" "*")])
10943
10944 (define_insn "sqrtdf2_i387"
10945 [(set (match_operand:DF 0 "register_operand" "=f")
10946 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
10947 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10948 && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)"
10949 "fsqrt"
10950 [(set_attr "type" "fpspc")
10951 (set_attr "mode" "DF")
10952 (set_attr "athlon_decode" "direct")])
10953
10954 (define_insn "*sqrtextendsfdf2"
10955 [(set (match_operand:DF 0 "register_operand" "=f")
10956 (sqrt:DF (float_extend:DF
10957 (match_operand:SF 1 "register_operand" "0"))))]
10958 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && !TARGET_SSE2"
10959 "fsqrt"
10960 [(set_attr "type" "fpspc")
10961 (set_attr "mode" "DF")
10962 (set_attr "athlon_decode" "direct")])
10963
10964 (define_insn "sqrtxf2"
10965 [(set (match_operand:XF 0 "register_operand" "=f")
10966 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
10967 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10968 && (TARGET_IEEE_FP || flag_fast_math) "
10969 "fsqrt"
10970 [(set_attr "type" "fpspc")
10971 (set_attr "mode" "XF")
10972 (set_attr "athlon_decode" "direct")])
10973
10974 (define_insn "sqrttf2"
10975 [(set (match_operand:TF 0 "register_operand" "=f")
10976 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
10977 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10978 && (TARGET_IEEE_FP || flag_fast_math) "
10979 "fsqrt"
10980 [(set_attr "type" "fpspc")
10981 (set_attr "mode" "XF")
10982 (set_attr "athlon_decode" "direct")])
10983
10984 (define_insn "*sqrtextenddfxf2"
10985 [(set (match_operand:XF 0 "register_operand" "=f")
10986 (sqrt:XF (float_extend:XF
10987 (match_operand:DF 1 "register_operand" "0"))))]
10988 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10989 "fsqrt"
10990 [(set_attr "type" "fpspc")
10991 (set_attr "mode" "XF")
10992 (set_attr "athlon_decode" "direct")])
10993
10994 (define_insn "*sqrtextenddftf2"
10995 [(set (match_operand:TF 0 "register_operand" "=f")
10996 (sqrt:TF (float_extend:TF
10997 (match_operand:DF 1 "register_operand" "0"))))]
10998 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10999 "fsqrt"
11000 [(set_attr "type" "fpspc")
11001 (set_attr "mode" "XF")
11002 (set_attr "athlon_decode" "direct")])
11003
11004 (define_insn "*sqrtextendsfxf2"
11005 [(set (match_operand:XF 0 "register_operand" "=f")
11006 (sqrt:XF (float_extend:XF
11007 (match_operand:SF 1 "register_operand" "0"))))]
11008 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11009 "fsqrt"
11010 [(set_attr "type" "fpspc")
11011 (set_attr "mode" "XF")
11012 (set_attr "athlon_decode" "direct")])
11013
11014 (define_insn "*sqrtextendsftf2"
11015 [(set (match_operand:TF 0 "register_operand" "=f")
11016 (sqrt:TF (float_extend:TF
11017 (match_operand:SF 1 "register_operand" "0"))))]
11018 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11019 "fsqrt"
11020 [(set_attr "type" "fpspc")
11021 (set_attr "mode" "XF")
11022 (set_attr "athlon_decode" "direct")])
11023
11024 (define_insn "sindf2"
11025 [(set (match_operand:DF 0 "register_operand" "=f")
11026 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
11027 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11028 "fsin"
11029 [(set_attr "type" "fpspc")
11030 (set_attr "mode" "DF")])
11031
11032 (define_insn "sinsf2"
11033 [(set (match_operand:SF 0 "register_operand" "=f")
11034 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
11035 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11036 "fsin"
11037 [(set_attr "type" "fpspc")
11038 (set_attr "mode" "SF")])
11039
11040 (define_insn "*sinextendsfdf2"
11041 [(set (match_operand:DF 0 "register_operand" "=f")
11042 (unspec:DF [(float_extend:DF
11043 (match_operand:SF 1 "register_operand" "0"))] 1))]
11044 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11045 "fsin"
11046 [(set_attr "type" "fpspc")
11047 (set_attr "mode" "DF")])
11048
11049 (define_insn "sinxf2"
11050 [(set (match_operand:XF 0 "register_operand" "=f")
11051 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
11052 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11053 "fsin"
11054 [(set_attr "type" "fpspc")
11055 (set_attr "mode" "XF")])
11056
11057 (define_insn "sintf2"
11058 [(set (match_operand:TF 0 "register_operand" "=f")
11059 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
11060 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11061 "fsin"
11062 [(set_attr "type" "fpspc")
11063 (set_attr "mode" "XF")])
11064
11065 (define_insn "cosdf2"
11066 [(set (match_operand:DF 0 "register_operand" "=f")
11067 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
11068 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11069 "fcos"
11070 [(set_attr "type" "fpspc")
11071 (set_attr "mode" "DF")])
11072
11073 (define_insn "cossf2"
11074 [(set (match_operand:SF 0 "register_operand" "=f")
11075 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
11076 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11077 "fcos"
11078 [(set_attr "type" "fpspc")
11079 (set_attr "mode" "SF")])
11080
11081 (define_insn "*cosextendsfdf2"
11082 [(set (match_operand:DF 0 "register_operand" "=f")
11083 (unspec:DF [(float_extend:DF
11084 (match_operand:SF 1 "register_operand" "0"))] 2))]
11085 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11086 "fcos"
11087 [(set_attr "type" "fpspc")
11088 (set_attr "mode" "DF")])
11089
11090 (define_insn "cosxf2"
11091 [(set (match_operand:XF 0 "register_operand" "=f")
11092 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
11093 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11094 "fcos"
11095 [(set_attr "type" "fpspc")
11096 (set_attr "mode" "XF")])
11097
11098 (define_insn "costf2"
11099 [(set (match_operand:TF 0 "register_operand" "=f")
11100 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
11101 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11102 "fcos"
11103 [(set_attr "type" "fpspc")
11104 (set_attr "mode" "XF")])
11105 \f
11106 ;; Block operation instructions
11107
11108 (define_insn "cld"
11109 [(set (reg:SI 19) (const_int 0))]
11110 ""
11111 "cld"
11112 [(set_attr "type" "cld")])
11113
11114 (define_expand "movstrsi"
11115 [(use (match_operand:BLK 0 "memory_operand" ""))
11116 (use (match_operand:BLK 1 "memory_operand" ""))
11117 (use (match_operand:SI 2 "nonmemory_operand" ""))
11118 (use (match_operand:SI 3 "const_int_operand" ""))]
11119 ""
11120 "
11121 {
11122 rtx srcreg, destreg, countreg;
11123 int align = 0;
11124 int count = -1;
11125
11126 if (GET_CODE (operands[3]) == CONST_INT)
11127 align = INTVAL (operands[3]);
11128
11129 /* This simple hack avoids all inlining code and simplifies code bellow. */
11130 if (!TARGET_ALIGN_STRINGOPS)
11131 align = 32;
11132
11133 if (GET_CODE (operands[2]) == CONST_INT)
11134 count = INTVAL (operands[2]);
11135
11136 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11137 srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
11138
11139 emit_insn (gen_cld());
11140
11141 /* When optimizing for size emit simple rep ; movsb instruction for
11142 counts not divisible by 4. */
11143
11144 if ((!optimize || optimize_size)
11145 && (count < 0 || (count & 0x03)))
11146 {
11147 countreg = copy_to_mode_reg (SImode, operands[2]);
11148 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
11149 destreg, srcreg, countreg));
11150 }
11151
11152 /* For constant aligned (or small unaligned) copies use rep movsl
11153 followed by code copying the rest. For PentiumPro ensure 8 byte
11154 alignment to allow rep movsl acceleration. */
11155
11156 else if (count >= 0
11157 && (align >= 8
11158 || (!TARGET_PENTIUMPRO && align >= 4)
11159 || optimize_size || count < 64))
11160 {
11161 if (count & ~0x03)
11162 {
11163 countreg = copy_to_mode_reg (SImode,
11164 GEN_INT ((count >> 2)
11165 & 0x3fffffff));
11166 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
11167 destreg, srcreg, countreg));
11168 }
11169 if (count & 0x02)
11170 emit_insn (gen_strmovhi (destreg, srcreg));
11171 if (count & 0x01)
11172 emit_insn (gen_strmovqi (destreg, srcreg));
11173 }
11174 /* The generic code based on the glibc implementation:
11175 - align destination to 4 bytes (8 byte alignment is used for PentiumPro
11176 allowing accelerated copying there)
11177 - copy the data using rep movsl
11178 - copy the rest. */
11179 else
11180 {
11181 rtx countreg2;
11182 rtx label = NULL;
11183
11184 /* In case we don't know anything about the alignment, default to
11185 library version, since it is usually equally fast and result in
11186 shorter code. */
11187 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
11188 FAIL;
11189
11190 if (TARGET_SINGLE_STRINGOP)
11191 emit_insn (gen_cld());
11192
11193 countreg2 = gen_reg_rtx (SImode);
11194 countreg = copy_to_mode_reg (SImode, operands[2]);
11195
11196 /* We don't use loops to align destination and to copy parts smaller
11197 than 4 bytes, because gcc is able to optimize such code better (in
11198 the case the destination or the count really is aligned, gcc is often
11199 able to predict the branches) and also it is friendlier to the
11200 hardware branch prediction.
11201
11202 Using loops is benefical for generic case, because we can
11203 handle small counts using the loops. Many CPUs (such as Athlon)
11204 have large REP prefix setup costs.
11205
11206 This is quite costy. Maybe we can revisit this decision later or
11207 add some customizability to this code. */
11208
11209 if (count < 0
11210 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11211 {
11212 label = gen_label_rtx ();
11213 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11214 LEU, 0, SImode, 1, 0, label);
11215 }
11216 if (align <= 1)
11217 {
11218 rtx label = gen_label_rtx ();
11219 rtx tmpcount = gen_reg_rtx (SImode);
11220 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11221 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11222 SImode, 1, 0, label);
11223 emit_insn (gen_strmovqi (destreg, srcreg));
11224 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11225 emit_label (label);
11226 LABEL_NUSES (label) = 1;
11227 }
11228 if (align <= 2)
11229 {
11230 rtx label = gen_label_rtx ();
11231 rtx tmpcount = gen_reg_rtx (SImode);
11232 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11233 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11234 SImode, 1, 0, label);
11235 emit_insn (gen_strmovhi (destreg, srcreg));
11236 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11237 emit_label (label);
11238 LABEL_NUSES (label) = 1;
11239 }
11240 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11241 {
11242 rtx label = gen_label_rtx ();
11243 rtx tmpcount = gen_reg_rtx (SImode);
11244 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11245 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11246 SImode, 1, 0, label);
11247 emit_insn (gen_strmovsi (destreg, srcreg));
11248 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11249 emit_label (label);
11250 LABEL_NUSES (label) = 1;
11251 }
11252
11253 if (!TARGET_SINGLE_STRINGOP)
11254 emit_insn (gen_cld());
11255 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11256 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
11257 destreg, srcreg, countreg2));
11258
11259 if (label)
11260 {
11261 emit_label (label);
11262 LABEL_NUSES (label) = 1;
11263 }
11264 if (align > 2 && count > 0 && (count & 2))
11265 emit_insn (gen_strmovhi (destreg, srcreg));
11266 if (align <= 2 || count < 0)
11267 {
11268 rtx label = gen_label_rtx ();
11269 rtx tmpcount = gen_reg_rtx (SImode);
11270 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11271 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11272 SImode, 1, 0, label);
11273 emit_insn (gen_strmovhi (destreg, srcreg));
11274 emit_label (label);
11275 LABEL_NUSES (label) = 1;
11276 }
11277 if (align > 1 && count > 0 && (count & 1))
11278 emit_insn (gen_strmovsi (destreg, srcreg));
11279 if (align <= 1 || count < 0)
11280 {
11281 rtx label = gen_label_rtx ();
11282 rtx tmpcount = gen_reg_rtx (SImode);
11283 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11284 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11285 SImode, 1, 0, label);
11286 emit_insn (gen_strmovqi (destreg, srcreg));
11287 emit_label (label);
11288 LABEL_NUSES (label) = 1;
11289 }
11290 }
11291 DONE;
11292 }")
11293
11294 ;; Most CPUs don't like single string operations
11295 ;; Handle this case here to simplify previous expander.
11296
11297 (define_expand "strmovsi"
11298 [(set (match_dup 2)
11299 (mem:SI (match_operand:SI 1 "register_operand" "")))
11300 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
11301 (match_dup 2))
11302 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11303 (clobber (reg:CC 17))])
11304 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
11305 (clobber (reg:CC 17))])]
11306 ""
11307 "
11308 {
11309 if (TARGET_SINGLE_STRINGOP || optimize_size)
11310 {
11311 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
11312 operands[1]));
11313 DONE;
11314 }
11315 else
11316 operands[2] = gen_reg_rtx (SImode);
11317 }")
11318
11319 (define_expand "strmovhi"
11320 [(set (match_dup 2)
11321 (mem:HI (match_operand:SI 1 "register_operand" "")))
11322 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
11323 (match_dup 2))
11324 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
11325 (clobber (reg:CC 17))])
11326 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
11327 (clobber (reg:CC 17))])]
11328 ""
11329 "
11330 {
11331 if (TARGET_SINGLE_STRINGOP || optimize_size)
11332 {
11333 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
11334 operands[1]));
11335 DONE;
11336 }
11337 else
11338 operands[2] = gen_reg_rtx (HImode);
11339 }")
11340
11341 (define_expand "strmovqi"
11342 [(set (match_dup 2)
11343 (mem:QI (match_operand:SI 1 "register_operand" "")))
11344 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
11345 (match_dup 2))
11346 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11347 (clobber (reg:CC 17))])
11348 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
11349 (clobber (reg:CC 17))])]
11350 ""
11351 "
11352 {
11353 if (TARGET_SINGLE_STRINGOP || optimize_size)
11354 {
11355 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
11356 operands[1]));
11357 DONE;
11358 }
11359 else
11360 operands[2] = gen_reg_rtx (QImode);
11361 }")
11362
11363 (define_insn "strmovsi_1"
11364 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
11365 (mem:SI (match_operand:SI 3 "register_operand" "1")))
11366 (set (match_operand:SI 0 "register_operand" "=D")
11367 (plus:SI (match_dup 2)
11368 (const_int 4)))
11369 (set (match_operand:SI 1 "register_operand" "=S")
11370 (plus:SI (match_dup 3)
11371 (const_int 4)))
11372 (use (reg:SI 19))]
11373 "TARGET_SINGLE_STRINGOP || optimize_size"
11374 "movsl"
11375 [(set_attr "type" "str")
11376 (set_attr "mode" "SI")
11377 (set_attr "memory" "both")])
11378
11379 (define_insn "strmovhi_1"
11380 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
11381 (mem:HI (match_operand:SI 3 "register_operand" "1")))
11382 (set (match_operand:SI 0 "register_operand" "=D")
11383 (plus:SI (match_dup 2)
11384 (const_int 2)))
11385 (set (match_operand:SI 1 "register_operand" "=S")
11386 (plus:SI (match_dup 3)
11387 (const_int 2)))
11388 (use (reg:SI 19))]
11389 "TARGET_SINGLE_STRINGOP || optimize_size"
11390 "movsw"
11391 [(set_attr "type" "str")
11392 (set_attr "memory" "both")
11393 (set_attr "mode" "HI")])
11394
11395 (define_insn "strmovqi_1"
11396 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
11397 (mem:QI (match_operand:SI 3 "register_operand" "1")))
11398 (set (match_operand:SI 0 "register_operand" "=D")
11399 (plus:SI (match_dup 2)
11400 (const_int 1)))
11401 (set (match_operand:SI 1 "register_operand" "=S")
11402 (plus:SI (match_dup 3)
11403 (const_int 1)))
11404 (use (reg:SI 19))]
11405 "TARGET_SINGLE_STRINGOP || optimize_size"
11406 "movsb"
11407 [(set_attr "type" "str")
11408 (set_attr "memory" "both")
11409 (set_attr "mode" "QI")])
11410
11411 (define_insn "rep_movsi"
11412 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
11413 (set (match_operand:SI 0 "register_operand" "=D")
11414 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
11415 (const_int 2))
11416 (match_operand:SI 3 "register_operand" "0")))
11417 (set (match_operand:SI 1 "register_operand" "=S")
11418 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
11419 (match_operand:SI 4 "register_operand" "1")))
11420 (set (mem:BLK (match_dup 3))
11421 (mem:BLK (match_dup 4)))
11422 (use (match_dup 5))
11423 (use (reg:SI 19))]
11424 ""
11425 "rep\;movsl|rep movsd"
11426 [(set_attr "type" "str")
11427 (set_attr "prefix_rep" "1")
11428 (set_attr "memory" "both")
11429 (set_attr "mode" "SI")])
11430
11431 (define_insn "rep_movqi"
11432 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
11433 (set (match_operand:SI 0 "register_operand" "=D")
11434 (plus:SI (match_operand:SI 3 "register_operand" "0")
11435 (match_operand:SI 5 "register_operand" "2")))
11436 (set (match_operand:SI 1 "register_operand" "=S")
11437 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
11438 (set (mem:BLK (match_dup 3))
11439 (mem:BLK (match_dup 4)))
11440 (use (match_dup 5))
11441 (use (reg:SI 19))]
11442 ""
11443 "rep\;movsb|rep movsb"
11444 [(set_attr "type" "str")
11445 (set_attr "prefix_rep" "1")
11446 (set_attr "memory" "both")
11447 (set_attr "mode" "SI")])
11448
11449 (define_expand "clrstrsi"
11450 [(use (match_operand:BLK 0 "memory_operand" ""))
11451 (use (match_operand:SI 1 "nonmemory_operand" ""))
11452 (use (match_operand:SI 2 "const_int_operand" ""))]
11453 ""
11454 "
11455 {
11456 /* See comments in movstr expanders. The code is mostly identical. */
11457
11458 rtx destreg, zeroreg, countreg;
11459 int align = 0;
11460 int count = -1;
11461
11462 if (GET_CODE (operands[2]) == CONST_INT)
11463 align = INTVAL (operands[2]);
11464
11465 /* This simple hack avoids all inlining code and simplifies code bellow. */
11466 if (!TARGET_ALIGN_STRINGOPS)
11467 align = 32;
11468
11469 if (GET_CODE (operands[1]) == CONST_INT)
11470 count = INTVAL (operands[1]);
11471
11472 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11473
11474 emit_insn (gen_cld());
11475
11476 /* When optimizing for size emit simple rep ; movsb instruction for
11477 counts not divisible by 4. */
11478
11479 if ((!optimize || optimize_size)
11480 && (count < 0 || (count & 0x03)))
11481 {
11482 countreg = copy_to_mode_reg (SImode, operands[1]);
11483 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
11484 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
11485 destreg, countreg));
11486 }
11487 else if (count >= 0
11488 && (align >= 8
11489 || (!TARGET_PENTIUMPRO && align >= 4)
11490 || optimize_size || count < 64))
11491 {
11492 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11493 if (INTVAL (operands[1]) & ~0x03)
11494 {
11495 countreg = copy_to_mode_reg (SImode,
11496 GEN_INT ((INTVAL (operands[1]) >> 2)
11497 & 0x3fffffff));
11498 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
11499 destreg, countreg));
11500 }
11501 if (INTVAL (operands[1]) & 0x02)
11502 emit_insn (gen_strsethi (destreg,
11503 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11504 if (INTVAL (operands[1]) & 0x01)
11505 emit_insn (gen_strsetqi (destreg,
11506 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11507 }
11508 else
11509 {
11510 rtx countreg2;
11511 rtx label = NULL;
11512
11513 /* In case we don't know anything about the alignment, default to
11514 library version, since it is usually equally fast and result in
11515 shorter code. */
11516 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
11517 FAIL;
11518
11519 if (TARGET_SINGLE_STRINGOP)
11520 emit_insn (gen_cld());
11521
11522 countreg2 = gen_reg_rtx (SImode);
11523 countreg = copy_to_mode_reg (SImode, operands[1]);
11524 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11525
11526 if (count < 0
11527 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11528 {
11529 label = gen_label_rtx ();
11530 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11531 LEU, 0, SImode, 1, 0, label);
11532 }
11533 if (align <= 1)
11534 {
11535 rtx label = gen_label_rtx ();
11536 rtx tmpcount = gen_reg_rtx (SImode);
11537 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11538 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11539 SImode, 1, 0, label);
11540 emit_insn (gen_strsetqi (destreg,
11541 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11542 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11543 emit_label (label);
11544 LABEL_NUSES (label) = 1;
11545 }
11546 if (align <= 2)
11547 {
11548 rtx label = gen_label_rtx ();
11549 rtx tmpcount = gen_reg_rtx (SImode);
11550 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11551 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11552 SImode, 1, 0, label);
11553 emit_insn (gen_strsethi (destreg,
11554 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11555 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11556 emit_label (label);
11557 LABEL_NUSES (label) = 1;
11558 }
11559 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11560 {
11561 rtx label = gen_label_rtx ();
11562 rtx tmpcount = gen_reg_rtx (SImode);
11563 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11564 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11565 SImode, 1, 0, label);
11566 emit_insn (gen_strsetsi (destreg, zeroreg));
11567 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11568 emit_label (label);
11569 LABEL_NUSES (label) = 1;
11570 }
11571
11572 if (!TARGET_SINGLE_STRINGOP)
11573 emit_insn (gen_cld());
11574 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11575 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
11576 destreg, countreg2));
11577
11578 if (label)
11579 {
11580 emit_label (label);
11581 LABEL_NUSES (label) = 1;
11582 }
11583 if (align > 2 && count > 0 && (count & 2))
11584 emit_insn (gen_strsethi (destreg,
11585 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11586 if (align <= 2 || count < 0)
11587 {
11588 rtx label = gen_label_rtx ();
11589 rtx tmpcount = gen_reg_rtx (SImode);
11590 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11591 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11592 SImode, 1, 0, label);
11593 emit_insn (gen_strsethi (destreg,
11594 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11595 emit_label (label);
11596 LABEL_NUSES (label) = 1;
11597 }
11598 if (align > 1 && count > 0 && (count & 1))
11599 emit_insn (gen_strsetqi (destreg,
11600 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11601 if (align <= 1 || count < 0)
11602 {
11603 rtx label = gen_label_rtx ();
11604 rtx tmpcount = gen_reg_rtx (SImode);
11605 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11606 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11607 SImode, 1, 0, label);
11608 emit_insn (gen_strsetqi (destreg,
11609 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11610 emit_label (label);
11611 LABEL_NUSES (label) = 1;
11612 }
11613 }
11614 DONE;
11615 }")
11616
11617 ;; Most CPUs don't like single string operations
11618 ;; Handle this case here to simplify previous expander.
11619
11620 (define_expand "strsetsi"
11621 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
11622 (match_operand:SI 1 "register_operand" ""))
11623 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11624 (clobber (reg:CC 17))])]
11625 ""
11626 "
11627 {
11628 if (TARGET_SINGLE_STRINGOP || optimize_size)
11629 {
11630 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
11631 DONE;
11632 }
11633 }")
11634
11635 (define_expand "strsethi"
11636 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
11637 (match_operand:HI 1 "register_operand" ""))
11638 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
11639 (clobber (reg:CC 17))])]
11640 ""
11641 "
11642 {
11643 if (TARGET_SINGLE_STRINGOP || optimize_size)
11644 {
11645 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
11646 DONE;
11647 }
11648 }")
11649
11650 (define_expand "strsetqi"
11651 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
11652 (match_operand:QI 1 "register_operand" ""))
11653 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11654 (clobber (reg:CC 17))])]
11655 ""
11656 "
11657 {
11658 if (TARGET_SINGLE_STRINGOP || optimize_size)
11659 {
11660 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
11661 DONE;
11662 }
11663 }")
11664
11665 (define_insn "strsetsi_1"
11666 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
11667 (match_operand:SI 2 "register_operand" "a"))
11668 (set (match_operand:SI 0 "register_operand" "=D")
11669 (plus:SI (match_dup 1)
11670 (const_int 4)))
11671 (use (reg:SI 19))]
11672 "TARGET_SINGLE_STRINGOP || optimize_size"
11673 "stosl"
11674 [(set_attr "type" "str")
11675 (set_attr "memory" "store")
11676 (set_attr "mode" "SI")])
11677
11678 (define_insn "strsethi_1"
11679 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
11680 (match_operand:HI 2 "register_operand" "a"))
11681 (set (match_operand:SI 0 "register_operand" "=D")
11682 (plus:SI (match_dup 1)
11683 (const_int 2)))
11684 (use (reg:SI 19))]
11685 "TARGET_SINGLE_STRINGOP || optimize_size"
11686 "stosw"
11687 [(set_attr "type" "str")
11688 (set_attr "memory" "store")
11689 (set_attr "mode" "HI")])
11690
11691 (define_insn "strsetqi_1"
11692 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
11693 (match_operand:QI 2 "register_operand" "a"))
11694 (set (match_operand:SI 0 "register_operand" "=D")
11695 (plus:SI (match_dup 1)
11696 (const_int 1)))
11697 (use (reg:SI 19))]
11698 "TARGET_SINGLE_STRINGOP || optimize_size"
11699 "stosb"
11700 [(set_attr "type" "str")
11701 (set_attr "memory" "store")
11702 (set_attr "mode" "QI")])
11703
11704 (define_insn "rep_stossi"
11705 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
11706 (set (match_operand:SI 0 "register_operand" "=D")
11707 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
11708 (const_int 2))
11709 (match_operand:SI 3 "register_operand" "0")))
11710 (set (mem:BLK (match_dup 3))
11711 (const_int 0))
11712 (use (match_operand:SI 2 "register_operand" "a"))
11713 (use (match_dup 4))
11714 (use (reg:SI 19))]
11715 ""
11716 "rep\;stosl|rep stosd"
11717 [(set_attr "type" "str")
11718 (set_attr "prefix_rep" "1")
11719 (set_attr "memory" "store")
11720 (set_attr "mode" "SI")])
11721
11722 (define_insn "rep_stosqi"
11723 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
11724 (set (match_operand:SI 0 "register_operand" "=D")
11725 (plus:SI (match_operand:SI 3 "register_operand" "0")
11726 (match_operand:SI 4 "register_operand" "1")))
11727 (set (mem:BLK (match_dup 3))
11728 (const_int 0))
11729 (use (match_operand:QI 2 "register_operand" "a"))
11730 (use (match_dup 4))
11731 (use (reg:SI 19))]
11732 ""
11733 "rep\;stosb|rep stosb"
11734 [(set_attr "type" "str")
11735 (set_attr "prefix_rep" "1")
11736 (set_attr "memory" "store")
11737 (set_attr "mode" "QI")])
11738
11739 (define_expand "cmpstrsi"
11740 [(set (match_operand:SI 0 "register_operand" "")
11741 (compare:SI (match_operand:BLK 1 "general_operand" "")
11742 (match_operand:BLK 2 "general_operand" "")))
11743 (use (match_operand:SI 3 "general_operand" ""))
11744 (use (match_operand:SI 4 "immediate_operand" ""))]
11745 ""
11746 "
11747 {
11748 rtx addr1, addr2, out, outlow, count, countreg, align;
11749
11750 out = operands[0];
11751 if (GET_CODE (out) != REG)
11752 out = gen_reg_rtx (SImode);
11753
11754 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
11755 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
11756
11757 count = operands[3];
11758 countreg = copy_to_mode_reg (SImode, count);
11759
11760 /* %%% Iff we are testing strict equality, we can use known alignment
11761 to good advantage. This may be possible with combine, particularly
11762 once cc0 is dead. */
11763 align = operands[4];
11764
11765 emit_insn (gen_cld ());
11766 if (GET_CODE (count) == CONST_INT)
11767 {
11768 if (INTVAL (count) == 0)
11769 {
11770 emit_move_insn (operands[0], const0_rtx);
11771 DONE;
11772 }
11773 emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align,
11774 addr1, addr2, countreg));
11775 }
11776 else
11777 {
11778 emit_insn (gen_cmpsi_1 (countreg, countreg));
11779 emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align,
11780 addr1, addr2, countreg));
11781 }
11782
11783 outlow = gen_lowpart (QImode, out);
11784 emit_insn (gen_cmpintqi (outlow));
11785 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
11786
11787 if (operands[0] != out)
11788 emit_move_insn (operands[0], out);
11789
11790 DONE;
11791 }")
11792
11793 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
11794
11795 (define_expand "cmpintqi"
11796 [(set (match_dup 1)
11797 (gtu:QI (reg:CC 17) (const_int 0)))
11798 (set (match_dup 2)
11799 (ltu:QI (reg:CC 17) (const_int 0)))
11800 (parallel [(set (match_operand:QI 0 "register_operand" "")
11801 (minus:QI (match_dup 1)
11802 (match_dup 2)))
11803 (clobber (reg:CC 17))])]
11804 ""
11805 "operands[1] = gen_reg_rtx (QImode);
11806 operands[2] = gen_reg_rtx (QImode);")
11807
11808 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
11809 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
11810
11811 (define_insn "cmpstrsi_nz_1"
11812 [(set (reg:CC 17)
11813 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
11814 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
11815 (use (match_operand:SI 6 "register_operand" "2"))
11816 (use (match_operand:SI 3 "immediate_operand" "i"))
11817 (use (reg:SI 19))
11818 (clobber (match_operand:SI 0 "register_operand" "=S"))
11819 (clobber (match_operand:SI 1 "register_operand" "=D"))
11820 (clobber (match_operand:SI 2 "register_operand" "=c"))]
11821 ""
11822 "repz{\;| }cmpsb"
11823 [(set_attr "type" "str")
11824 (set_attr "mode" "QI")
11825 (set_attr "prefix_rep" "1")])
11826
11827 ;; The same, but the count is not known to not be zero.
11828
11829 (define_insn "cmpstrsi_1"
11830 [(set (reg:CC 17)
11831 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
11832 (const_int 0))
11833 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
11834 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
11835 (const_int 0)))
11836 (use (match_operand:SI 3 "immediate_operand" "i"))
11837 (use (reg:CC 17))
11838 (use (reg:SI 19))
11839 (clobber (match_operand:SI 0 "register_operand" "=S"))
11840 (clobber (match_operand:SI 1 "register_operand" "=D"))
11841 (clobber (match_operand:SI 2 "register_operand" "=c"))]
11842 ""
11843 "repz{\;| }cmpsb"
11844 [(set_attr "type" "str")
11845 (set_attr "mode" "QI")
11846 (set_attr "prefix_rep" "1")])
11847
11848 (define_expand "strlensi"
11849 [(set (match_operand:SI 0 "register_operand" "")
11850 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
11851 (match_operand:QI 2 "immediate_operand" "")
11852 (match_operand:SI 3 "immediate_operand" "")] 0))]
11853 ""
11854 "
11855 {
11856 rtx out, addr, scratch1, scratch2, scratch3;
11857 rtx eoschar = operands[2];
11858 rtx align = operands[3];
11859
11860 /* The generic case of strlen expander is long. Avoid it's
11861 expanding unless TARGET_INLINE_ALL_STRINGOPS. */
11862
11863 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
11864 && !TARGET_INLINE_ALL_STRINGOPS
11865 && !optimize_size
11866 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
11867 FAIL;
11868
11869 out = operands[0];
11870 addr = force_reg (Pmode, XEXP (operands[1], 0));
11871 scratch1 = gen_reg_rtx (SImode);
11872
11873 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
11874 && !optimize_size)
11875 {
11876 /* Well it seems that some optimizer does not combine a call like
11877 foo(strlen(bar), strlen(bar));
11878 when the move and the subtraction is done here. It does calculate
11879 the length just once when these instructions are done inside of
11880 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
11881 often used and I use one fewer register for the lifetime of
11882 output_strlen_unroll() this is better. */
11883
11884 if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
11885 emit_move_insn (scratch1, addr);
11886
11887 emit_move_insn (out, addr);
11888
11889 ix86_expand_strlensi_unroll_1 (out, align, scratch1);
11890
11891 /* strlensi_unroll_1 returns the address of the zero at the end of
11892 the string, like memchr(), so compute the length by subtracting
11893 the start address. */
11894 emit_insn (gen_subsi3 (out, out, addr));
11895 }
11896 else
11897 {
11898 scratch2 = gen_reg_rtx (SImode);
11899 scratch3 = gen_reg_rtx (SImode);
11900
11901 emit_move_insn (scratch3, addr);
11902
11903 emit_insn (gen_cld ());
11904 emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
11905 align, constm1_rtx, scratch3));
11906 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
11907 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
11908 }
11909 DONE;
11910 }")
11911
11912 (define_insn "strlensi_1"
11913 [(set (match_operand:SI 0 "register_operand" "=&c")
11914 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
11915 (match_operand:QI 2 "general_operand" "a")
11916 (match_operand:SI 3 "immediate_operand" "i")
11917 (match_operand:SI 4 "immediate_operand" "0")] 0))
11918 (use (reg:SI 19))
11919 (clobber (match_operand:SI 1 "register_operand" "=D"))
11920 (clobber (reg:CC 17))]
11921 ""
11922 "repnz{\;| }scasb"
11923 [(set_attr "type" "str")
11924 (set_attr "mode" "QI")
11925 (set_attr "prefix_rep" "1")])
11926 \f
11927 ;; Conditional move instructions.
11928
11929 (define_expand "movsicc"
11930 [(set (match_operand:SI 0 "register_operand" "")
11931 (if_then_else:SI (match_operand 1 "comparison_operator" "")
11932 (match_operand:SI 2 "general_operand" "")
11933 (match_operand:SI 3 "general_operand" "")))]
11934 ""
11935 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
11936
11937 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
11938 ;; the register first winds up with `sbbl $0,reg', which is also weird.
11939 ;; So just document what we're doing explicitly.
11940
11941 (define_insn "x86_movsicc_0_m1"
11942 [(set (match_operand:SI 0 "register_operand" "=r")
11943 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
11944 (const_int -1)
11945 (const_int 0)))
11946 (clobber (reg:CC 17))]
11947 ""
11948 "sbb{l}\\t%0, %0"
11949 ; Since we don't have the proper number of operands for an alu insn,
11950 ; fill in all the blanks.
11951 [(set_attr "type" "alu")
11952 (set_attr "memory" "none")
11953 (set_attr "imm_disp" "false")
11954 (set_attr "mode" "SI")
11955 (set_attr "length_immediate" "0")])
11956
11957 (define_insn "*movsicc_noc"
11958 [(set (match_operand:SI 0 "register_operand" "=r,r")
11959 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
11960 [(reg 17) (const_int 0)])
11961 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
11962 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
11963 "TARGET_CMOVE
11964 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
11965 "@
11966 cmov%C1\\t{%2, %0|%0, %2}
11967 cmov%c1\\t{%3, %0|%0, %3}"
11968 [(set_attr "type" "icmov")
11969 (set_attr "mode" "SI")])
11970
11971 (define_expand "movhicc"
11972 [(set (match_operand:HI 0 "register_operand" "")
11973 (if_then_else:HI (match_operand 1 "comparison_operator" "")
11974 (match_operand:HI 2 "nonimmediate_operand" "")
11975 (match_operand:HI 3 "nonimmediate_operand" "")))]
11976 "TARGET_CMOVE && TARGET_HIMODE_MATH"
11977 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
11978
11979 (define_insn "*movhicc_noc"
11980 [(set (match_operand:HI 0 "register_operand" "=r,r")
11981 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
11982 [(reg 17) (const_int 0)])
11983 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
11984 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
11985 "TARGET_CMOVE
11986 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
11987 "@
11988 cmov%C1\\t{%2, %0|%0, %2}
11989 cmov%c1\\t{%3, %0|%0, %3}"
11990 [(set_attr "type" "icmov")
11991 (set_attr "mode" "HI")])
11992
11993 (define_expand "movsfcc"
11994 [(set (match_operand:SF 0 "register_operand" "")
11995 (if_then_else:SF (match_operand 1 "comparison_operator" "")
11996 (match_operand:SF 2 "register_operand" "")
11997 (match_operand:SF 3 "register_operand" "")))]
11998 "TARGET_CMOVE"
11999 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12000
12001 (define_insn "*movsfcc_1"
12002 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
12003 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
12004 [(reg 17) (const_int 0)])
12005 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
12006 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
12007 "TARGET_CMOVE
12008 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12009 "@
12010 fcmov%F1\\t{%2, %0|%0, %2}
12011 fcmov%f1\\t{%3, %0|%0, %3}
12012 cmov%C1\\t{%2, %0|%0, %2}
12013 cmov%c1\\t{%3, %0|%0, %3}"
12014 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
12015 (set_attr "mode" "SF,SF,SI,SI")])
12016
12017 (define_expand "movdfcc"
12018 [(set (match_operand:DF 0 "register_operand" "")
12019 (if_then_else:DF (match_operand 1 "comparison_operator" "")
12020 (match_operand:DF 2 "register_operand" "")
12021 (match_operand:DF 3 "register_operand" "")))]
12022 "TARGET_CMOVE"
12023 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12024
12025 (define_insn "*movdfcc_1"
12026 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
12027 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12028 [(reg 17) (const_int 0)])
12029 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
12030 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
12031 "TARGET_CMOVE
12032 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12033 "@
12034 fcmov%F1\\t{%2, %0|%0, %2}
12035 fcmov%f1\\t{%3, %0|%0, %3}
12036 #
12037 #"
12038 [(set_attr "type" "fcmov,fcmov,multi,multi")
12039 (set_attr "mode" "DF")])
12040
12041 (define_split
12042 [(set (match_operand:DF 0 "register_operand" "")
12043 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12044 [(match_operand 4 "" "") (const_int 0)])
12045 (match_operand:DF 2 "nonimmediate_operand" "")
12046 (match_operand:DF 3 "nonimmediate_operand" "")))]
12047 "!ANY_FP_REG_P (operands[0]) && reload_completed"
12048 [(set (match_dup 2)
12049 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
12050 (match_dup 5)
12051 (match_dup 7)))
12052 (set (match_dup 3)
12053 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
12054 (match_dup 6)
12055 (match_dup 8)))]
12056 "split_di (operands+2, 1, operands+5, operands+6);
12057 split_di (operands+3, 1, operands+7, operands+8);
12058 split_di (operands, 1, operands+2, operands+3);")
12059
12060 (define_expand "movxfcc"
12061 [(set (match_operand:XF 0 "register_operand" "")
12062 (if_then_else:XF (match_operand 1 "comparison_operator" "")
12063 (match_operand:XF 2 "register_operand" "")
12064 (match_operand:XF 3 "register_operand" "")))]
12065 "TARGET_CMOVE"
12066 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12067
12068 (define_expand "movtfcc"
12069 [(set (match_operand:TF 0 "register_operand" "")
12070 (if_then_else:TF (match_operand 1 "comparison_operator" "")
12071 (match_operand:TF 2 "register_operand" "")
12072 (match_operand:TF 3 "register_operand" "")))]
12073 "TARGET_CMOVE"
12074 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12075
12076 (define_insn "*movxfcc_1"
12077 [(set (match_operand:XF 0 "register_operand" "=f,f")
12078 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
12079 [(reg 17) (const_int 0)])
12080 (match_operand:XF 2 "register_operand" "f,0")
12081 (match_operand:XF 3 "register_operand" "0,f")))]
12082 "TARGET_CMOVE"
12083 "@
12084 fcmov%F1\\t{%2, %0|%0, %2}
12085 fcmov%f1\\t{%3, %0|%0, %3}"
12086 [(set_attr "type" "fcmov")
12087 (set_attr "mode" "XF")])
12088
12089 (define_insn "*movtfcc_1"
12090 [(set (match_operand:TF 0 "register_operand" "=f,f")
12091 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
12092 [(reg 17) (const_int 0)])
12093 (match_operand:TF 2 "register_operand" "f,0")
12094 (match_operand:TF 3 "register_operand" "0,f")))]
12095 "TARGET_CMOVE"
12096 "@
12097 fcmov%F1\\t{%2, %0|%0, %2}
12098 fcmov%f1\\t{%3, %0|%0, %3}"
12099 [(set_attr "type" "fcmov")
12100 (set_attr "mode" "XF")])
12101 \f
12102 ;; Misc patterns (?)
12103
12104 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
12105 ;; Otherwise there will be nothing to keep
12106 ;;
12107 ;; [(set (reg ebp) (reg esp))]
12108 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
12109 ;; (clobber (eflags)]
12110 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
12111 ;;
12112 ;; in proper program order.
12113
12114 (define_insn "pro_epilogue_adjust_stack"
12115 [(set (match_operand:SI 0 "register_operand" "=r,r")
12116 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
12117 (match_operand:SI 2 "immediate_operand" "i,i")))
12118 (set (match_operand:SI 3 "register_operand" "+r,r")
12119 (match_dup 3))
12120 (clobber (reg:CC 17))]
12121 ""
12122 "*
12123 {
12124 switch (get_attr_type (insn))
12125 {
12126 case TYPE_IMOV:
12127 return \"mov{l}\\t{%1, %0|%0, %1}\";
12128
12129 case TYPE_ALU:
12130 if (GET_CODE (operands[2]) == CONST_INT
12131 && (INTVAL (operands[2]) == 128
12132 || (INTVAL (operands[2]) < 0
12133 && INTVAL (operands[2]) != -128)))
12134 {
12135 operands[2] = GEN_INT (-INTVAL (operands[2]));
12136 return \"sub{l}\\t{%2, %0|%0, %2}\";
12137 }
12138 return \"add{l}\\t{%2, %0|%0, %2}\";
12139
12140 case TYPE_LEA:
12141 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
12142 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
12143
12144 default:
12145 abort ();
12146 }
12147 }"
12148 [(set (attr "type")
12149 (cond [(eq_attr "alternative" "0")
12150 (const_string "alu")
12151 (match_operand:SI 2 "const0_operand" "")
12152 (const_string "imov")
12153 ]
12154 (const_string "lea")))
12155 (set_attr "mode" "SI")])
12156
12157 (define_insn "allocate_stack_worker"
12158 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
12159 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
12160 (clobber (match_dup 0))
12161 (clobber (reg:CC 17))]
12162 "TARGET_STACK_PROBE"
12163 "call\\t__alloca"
12164 [(set_attr "type" "multi")
12165 (set_attr "length" "5")])
12166
12167 (define_expand "allocate_stack"
12168 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
12169 (minus:SI (reg:SI 7)
12170 (match_operand:SI 1 "general_operand" "")))
12171 (clobber (reg:CC 17))])
12172 (parallel [(set (reg:SI 7)
12173 (minus:SI (reg:SI 7) (match_dup 1)))
12174 (clobber (reg:CC 17))])]
12175 "TARGET_STACK_PROBE"
12176 "
12177 {
12178 #ifdef CHECK_STACK_LIMIT
12179 if (GET_CODE (operands[1]) == CONST_INT
12180 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
12181 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
12182 operands[1]));
12183 else
12184 #endif
12185 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
12186 operands[1])));
12187
12188 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
12189 DONE;
12190 }")
12191
12192 (define_expand "exception_receiver"
12193 [(const_int 0)]
12194 "flag_pic"
12195 "
12196 {
12197 load_pic_register ();
12198 DONE;
12199 }")
12200
12201 (define_expand "builtin_setjmp_receiver"
12202 [(label_ref (match_operand 0 "" ""))]
12203 "flag_pic"
12204 "
12205 {
12206 load_pic_register ();
12207 DONE;
12208 }")
12209 \f
12210 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
12211
12212 (define_split
12213 [(set (match_operand 0 "register_operand" "")
12214 (match_operator 3 "promotable_binary_operator"
12215 [(match_operand 1 "register_operand" "")
12216 (match_operand 2 "aligned_operand" "")]))
12217 (clobber (reg:CC 17))]
12218 "! TARGET_PARTIAL_REG_STALL && reload_completed
12219 && ((GET_MODE (operands[0]) == HImode
12220 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
12221 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
12222 || (GET_MODE (operands[0]) == QImode
12223 && (TARGET_PROMOTE_QImode || optimize_size)))"
12224 [(parallel [(set (match_dup 0)
12225 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
12226 (clobber (reg:CC 17))])]
12227 "operands[0] = gen_lowpart (SImode, operands[0]);
12228 operands[1] = gen_lowpart (SImode, operands[1]);
12229 if (GET_CODE (operands[3]) != ASHIFT)
12230 operands[2] = gen_lowpart (SImode, operands[2]);
12231 GET_MODE (operands[3]) = SImode;")
12232
12233 (define_split
12234 [(set (reg 17)
12235 (compare (and (match_operand 1 "aligned_operand" "")
12236 (match_operand 2 "const_int_operand" ""))
12237 (const_int 0)))
12238 (set (match_operand 0 "register_operand" "")
12239 (and (match_dup 1) (match_dup 2)))]
12240 "! TARGET_PARTIAL_REG_STALL && reload_completed
12241 && ix86_match_ccmode (insn, CCNOmode)
12242 && (GET_MODE (operands[0]) == HImode
12243 || (GET_MODE (operands[0]) == QImode
12244 && (TARGET_PROMOTE_QImode || optimize_size)))"
12245 [(parallel [(set (reg:CCNO 17)
12246 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
12247 (const_int 0)))
12248 (set (match_dup 0)
12249 (and:SI (match_dup 1) (match_dup 2)))])]
12250 "operands[2]
12251 = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
12252 operands[0] = gen_lowpart (SImode, operands[0]);
12253 operands[1] = gen_lowpart (SImode, operands[1]);")
12254
12255 (define_split
12256 [(set (reg 17)
12257 (compare (and (match_operand 0 "aligned_operand" "")
12258 (match_operand 1 "const_int_operand" ""))
12259 (const_int 0)))]
12260 "! TARGET_PARTIAL_REG_STALL && reload_completed
12261 && ix86_match_ccmode (insn, CCNOmode)
12262 && (GET_MODE (operands[0]) == HImode
12263 || (GET_MODE (operands[0]) == QImode
12264 && (TARGET_PROMOTE_QImode || optimize_size)))"
12265 [(set (reg:CCNO 17)
12266 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
12267 (const_int 0)))]
12268 "operands[1]
12269 = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
12270 operands[0] = gen_lowpart (SImode, operands[0]);")
12271
12272 (define_split
12273 [(set (match_operand 0 "register_operand" "")
12274 (neg (match_operand 1 "register_operand" "")))
12275 (clobber (reg:CC 17))]
12276 "! TARGET_PARTIAL_REG_STALL && reload_completed
12277 && (GET_MODE (operands[0]) == HImode
12278 || (GET_MODE (operands[0]) == QImode
12279 && (TARGET_PROMOTE_QImode || optimize_size)))"
12280 [(parallel [(set (match_dup 0)
12281 (neg:SI (match_dup 1)))
12282 (clobber (reg:CC 17))])]
12283 "operands[0] = gen_lowpart (SImode, operands[0]);
12284 operands[1] = gen_lowpart (SImode, operands[1]);")
12285
12286 (define_split
12287 [(set (match_operand 0 "register_operand" "")
12288 (not (match_operand 1 "register_operand" "")))]
12289 "! TARGET_PARTIAL_REG_STALL && reload_completed
12290 && (GET_MODE (operands[0]) == HImode
12291 || (GET_MODE (operands[0]) == QImode
12292 && (TARGET_PROMOTE_QImode || optimize_size)))"
12293 [(set (match_dup 0)
12294 (not:SI (match_dup 1)))]
12295 "operands[0] = gen_lowpart (SImode, operands[0]);
12296 operands[1] = gen_lowpart (SImode, operands[1]);")
12297
12298 (define_split
12299 [(set (match_operand 0 "register_operand" "")
12300 (if_then_else (match_operator 1 "comparison_operator"
12301 [(reg 17) (const_int 0)])
12302 (match_operand 2 "register_operand" "")
12303 (match_operand 3 "register_operand" "")))]
12304 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
12305 && (GET_MODE (operands[0]) == HImode
12306 || (GET_MODE (operands[0]) == QImode
12307 && (TARGET_PROMOTE_QImode || optimize_size)))"
12308 [(set (match_dup 0)
12309 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
12310 "operands[0] = gen_lowpart (SImode, operands[0]);
12311 operands[2] = gen_lowpart (SImode, operands[2]);
12312 operands[3] = gen_lowpart (SImode, operands[3]);")
12313
12314 \f
12315 ;; RTL Peephole optimizations, run before sched2. These primarily look to
12316 ;; transform a complex memory operation into two memory to register operations.
12317
12318 ;; Don't push memory operands
12319 (define_peephole2
12320 [(set (match_operand:SI 0 "push_operand" "")
12321 (match_operand:SI 1 "memory_operand" ""))
12322 (match_scratch:SI 2 "r")]
12323 "! optimize_size && ! TARGET_PUSH_MEMORY"
12324 [(set (match_dup 2) (match_dup 1))
12325 (set (match_dup 0) (match_dup 2))]
12326 "")
12327
12328 ;; We need to handle SFmode only, because DFmode and XFmode is split to
12329 ;; SImode pushes.
12330 (define_peephole2
12331 [(set (match_operand:SF 0 "push_operand" "")
12332 (match_operand:SF 1 "memory_operand" ""))
12333 (match_scratch:SF 2 "r")]
12334 "! optimize_size && ! TARGET_PUSH_MEMORY"
12335 [(set (match_dup 2) (match_dup 1))
12336 (set (match_dup 0) (match_dup 2))]
12337 "")
12338
12339 (define_peephole2
12340 [(set (match_operand:HI 0 "push_operand" "")
12341 (match_operand:HI 1 "memory_operand" ""))
12342 (match_scratch:HI 2 "r")]
12343 "! optimize_size && ! TARGET_PUSH_MEMORY"
12344 [(set (match_dup 2) (match_dup 1))
12345 (set (match_dup 0) (match_dup 2))]
12346 "")
12347
12348 (define_peephole2
12349 [(set (match_operand:QI 0 "push_operand" "")
12350 (match_operand:QI 1 "memory_operand" ""))
12351 (match_scratch:QI 2 "q")]
12352 "! optimize_size && ! TARGET_PUSH_MEMORY"
12353 [(set (match_dup 2) (match_dup 1))
12354 (set (match_dup 0) (match_dup 2))]
12355 "")
12356
12357 ;; Don't move an immediate directly to memory when the instruction
12358 ;; gets too big.
12359 (define_peephole2
12360 [(match_scratch:SI 1 "r")
12361 (set (match_operand:SI 0 "memory_operand" "")
12362 (const_int 0))]
12363 "! optimize_size
12364 && ! TARGET_USE_MOV0
12365 && TARGET_SPLIT_LONG_MOVES
12366 && get_attr_length (insn) >= ix86_cost->large_insn
12367 && peep2_regno_dead_p (0, FLAGS_REG)"
12368 [(parallel [(set (match_dup 1) (const_int 0))
12369 (clobber (reg:CC 17))])
12370 (set (match_dup 0) (match_dup 1))]
12371 "")
12372
12373 (define_peephole2
12374 [(match_scratch:HI 1 "r")
12375 (set (match_operand:HI 0 "memory_operand" "")
12376 (const_int 0))]
12377 "! optimize_size
12378 && ! TARGET_USE_MOV0
12379 && TARGET_SPLIT_LONG_MOVES
12380 && get_attr_length (insn) >= ix86_cost->large_insn
12381 && peep2_regno_dead_p (0, FLAGS_REG)"
12382 [(parallel [(set (match_dup 2) (const_int 0))
12383 (clobber (reg:CC 17))])
12384 (set (match_dup 0) (match_dup 1))]
12385 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
12386
12387 (define_peephole2
12388 [(match_scratch:QI 1 "q")
12389 (set (match_operand:QI 0 "memory_operand" "")
12390 (const_int 0))]
12391 "! optimize_size
12392 && ! TARGET_USE_MOV0
12393 && TARGET_SPLIT_LONG_MOVES
12394 && get_attr_length (insn) >= ix86_cost->large_insn
12395 && peep2_regno_dead_p (0, FLAGS_REG)"
12396 [(parallel [(set (match_dup 2) (const_int 0))
12397 (clobber (reg:CC 17))])
12398 (set (match_dup 0) (match_dup 1))]
12399 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
12400
12401 (define_peephole2
12402 [(match_scratch:SI 2 "r")
12403 (set (match_operand:SI 0 "memory_operand" "")
12404 (match_operand:SI 1 "immediate_operand" ""))]
12405 "! optimize_size
12406 && get_attr_length (insn) >= ix86_cost->large_insn
12407 && TARGET_SPLIT_LONG_MOVES"
12408 [(set (match_dup 2) (match_dup 1))
12409 (set (match_dup 0) (match_dup 2))]
12410 "")
12411
12412 (define_peephole2
12413 [(match_scratch:HI 2 "r")
12414 (set (match_operand:HI 0 "memory_operand" "")
12415 (match_operand:HI 1 "immediate_operand" ""))]
12416 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
12417 && TARGET_SPLIT_LONG_MOVES"
12418 [(set (match_dup 2) (match_dup 1))
12419 (set (match_dup 0) (match_dup 2))]
12420 "")
12421
12422 (define_peephole2
12423 [(match_scratch:QI 2 "q")
12424 (set (match_operand:QI 0 "memory_operand" "")
12425 (match_operand:QI 1 "immediate_operand" ""))]
12426 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
12427 && TARGET_SPLIT_LONG_MOVES"
12428 [(set (match_dup 2) (match_dup 1))
12429 (set (match_dup 0) (match_dup 2))]
12430 "")
12431
12432 ;; Don't compare memory with zero, load and use a test instead.
12433 (define_peephole2
12434 [(set (reg 17)
12435 (compare (match_operand:SI 0 "memory_operand" "")
12436 (const_int 0)))
12437 (match_scratch:SI 3 "r")]
12438 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
12439 [(set (match_dup 3) (match_dup 0))
12440 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
12441 "")
12442
12443 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
12444 ;; Don't split NOTs with a displacement operand, because resulting XOR
12445 ;; will not be pariable anyway.
12446 ;;
12447 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
12448 ;; represented using a modRM byte. The XOR replacement is long decoded,
12449 ;; so this split helps here as well.
12450 ;;
12451 ;; Note: Can't do this as a regular split because we can't get proper
12452 ;; lifetime information then.
12453
12454 (define_peephole2
12455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12456 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
12457 "!optimize_size
12458 && peep2_regno_dead_p (0, FLAGS_REG)
12459 && ((TARGET_PENTIUM
12460 && (GET_CODE (operands[0]) != MEM
12461 || !memory_displacement_operand (operands[0], SImode)))
12462 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
12463 [(parallel [(set (match_dup 0)
12464 (xor:SI (match_dup 1) (const_int -1)))
12465 (clobber (reg:CC 17))])]
12466 "")
12467
12468 (define_peephole2
12469 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12470 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
12471 "!optimize_size
12472 && peep2_regno_dead_p (0, FLAGS_REG)
12473 && ((TARGET_PENTIUM
12474 && (GET_CODE (operands[0]) != MEM
12475 || !memory_displacement_operand (operands[0], HImode)))
12476 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
12477 [(parallel [(set (match_dup 0)
12478 (xor:HI (match_dup 1) (const_int -1)))
12479 (clobber (reg:CC 17))])]
12480 "")
12481
12482 (define_peephole2
12483 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
12484 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
12485 "!optimize_size
12486 && peep2_regno_dead_p (0, FLAGS_REG)
12487 && ((TARGET_PENTIUM
12488 && (GET_CODE (operands[0]) != MEM
12489 || !memory_displacement_operand (operands[0], QImode)))
12490 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
12491 [(parallel [(set (match_dup 0)
12492 (xor:QI (match_dup 1) (const_int -1)))
12493 (clobber (reg:CC 17))])]
12494 "")
12495
12496 ;; Non pairable "test imm, reg" instructions can be translated to
12497 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
12498 ;; byte opcode instead of two, have a short form for byte operands),
12499 ;; so do it for other CPUs as well. Given that the value was dead,
12500 ;; this should not create any new dependancies. Pass on the sub-word
12501 ;; versions if we're concerned about partial register stalls.
12502
12503 (define_peephole2
12504 [(set (reg 17)
12505 (compare (and:SI (match_operand:SI 0 "register_operand" "")
12506 (match_operand:SI 1 "immediate_operand" ""))
12507 (const_int 0)))]
12508 "ix86_match_ccmode (insn, CCNOmode)
12509 && (true_regnum (operands[0]) != 0
12510 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
12511 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12512 [(parallel
12513 [(set (reg:CCNO 17)
12514 (compare:CCNO (and:SI (match_dup 0)
12515 (match_dup 1))
12516 (const_int 0)))
12517 (set (match_dup 0)
12518 (and:SI (match_dup 0) (match_dup 1)))])]
12519 "")
12520
12521 ;; We don't need to handle HImode case, because it will be promoted to SImode
12522 ;; on ! TARGET_PARTIAL_REG_STALL
12523
12524 (define_peephole2
12525 [(set (reg 17)
12526 (compare (and:QI (match_operand:QI 0 "register_operand" "")
12527 (match_operand:QI 1 "immediate_operand" ""))
12528 (const_int 0)))]
12529 "! TARGET_PARTIAL_REG_STALL
12530 && ix86_match_ccmode (insn, CCNOmode)
12531 && true_regnum (operands[0]) != 0
12532 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12533 [(parallel
12534 [(set (reg:CCNO 17)
12535 (compare:CCNO (and:QI (match_dup 0)
12536 (match_dup 1))
12537 (const_int 0)))
12538 (set (match_dup 0)
12539 (and:QI (match_dup 0) (match_dup 1)))])]
12540 "")
12541
12542 (define_peephole2
12543 [(set (reg 17)
12544 (compare
12545 (and:SI
12546 (zero_extract:SI
12547 (match_operand 0 "ext_register_operand" "q")
12548 (const_int 8)
12549 (const_int 8))
12550 (match_operand 1 "const_int_operand" "n"))
12551 (const_int 0)))]
12552 "! TARGET_PARTIAL_REG_STALL
12553 && ix86_match_ccmode (insn, CCNOmode)
12554 && true_regnum (operands[0]) != 0
12555 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12556 [(parallel [(set (reg:CCNO 17)
12557 (compare:CCNO
12558 (and:SI
12559 (zero_extract:SI
12560 (match_dup 0)
12561 (const_int 8)
12562 (const_int 8))
12563 (match_dup 1))
12564 (const_int 0)))
12565 (set (zero_extract:SI (match_dup 0)
12566 (const_int 8)
12567 (const_int 8))
12568 (and:SI
12569 (zero_extract:SI
12570 (match_dup 0)
12571 (const_int 8)
12572 (const_int 8))
12573 (match_dup 1)))])]
12574 "")
12575
12576 ;; Don't do logical operations with memory inputs.
12577 (define_peephole2
12578 [(match_scratch:SI 2 "r")
12579 (parallel [(set (match_operand:SI 0 "register_operand" "")
12580 (match_operator:SI 3 "arith_or_logical_operator"
12581 [(match_dup 0)
12582 (match_operand:SI 1 "memory_operand" "")]))
12583 (clobber (reg:CC 17))])]
12584 "! optimize_size && ! TARGET_READ_MODIFY"
12585 [(set (match_dup 2) (match_dup 1))
12586 (parallel [(set (match_dup 0)
12587 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
12588 (clobber (reg:CC 17))])]
12589 "")
12590
12591 (define_peephole2
12592 [(match_scratch:SI 2 "r")
12593 (parallel [(set (match_operand:SI 0 "register_operand" "")
12594 (match_operator:SI 3 "arith_or_logical_operator"
12595 [(match_operand:SI 1 "memory_operand" "")
12596 (match_dup 0)]))
12597 (clobber (reg:CC 17))])]
12598 "! optimize_size && ! TARGET_READ_MODIFY"
12599 [(set (match_dup 2) (match_dup 1))
12600 (parallel [(set (match_dup 0)
12601 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
12602 (clobber (reg:CC 17))])]
12603 "")
12604
12605 ; Don't do logical operations with memory outputs
12606 ;
12607 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
12608 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
12609 ; the same decoder scheduling characteristics as the original.
12610
12611 (define_peephole2
12612 [(match_scratch:SI 2 "r")
12613 (parallel [(set (match_operand:SI 0 "memory_operand" "")
12614 (match_operator:SI 3 "arith_or_logical_operator"
12615 [(match_dup 0)
12616 (match_operand:SI 1 "nonmemory_operand" "")]))
12617 (clobber (reg:CC 17))])]
12618 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
12619 [(set (match_dup 2) (match_dup 0))
12620 (parallel [(set (match_dup 2)
12621 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
12622 (clobber (reg:CC 17))])
12623 (set (match_dup 0) (match_dup 2))]
12624 "")
12625
12626 (define_peephole2
12627 [(match_scratch:SI 2 "r")
12628 (parallel [(set (match_operand:SI 0 "memory_operand" "")
12629 (match_operator:SI 3 "arith_or_logical_operator"
12630 [(match_operand:SI 1 "nonmemory_operand" "")
12631 (match_dup 0)]))
12632 (clobber (reg:CC 17))])]
12633 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
12634 [(set (match_dup 2) (match_dup 0))
12635 (parallel [(set (match_dup 2)
12636 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
12637 (clobber (reg:CC 17))])
12638 (set (match_dup 0) (match_dup 2))]
12639 "")
12640
12641 ;; Attempt to always use XOR for zeroing registers.
12642 (define_peephole2
12643 [(set (match_operand 0 "register_operand" "")
12644 (const_int 0))]
12645 "(GET_MODE (operands[0]) == QImode
12646 || GET_MODE (operands[0]) == HImode
12647 || GET_MODE (operands[0]) == SImode)
12648 && (! TARGET_USE_MOV0 || optimize_size)
12649 && peep2_regno_dead_p (0, FLAGS_REG)"
12650 [(parallel [(set (match_dup 0) (const_int 0))
12651 (clobber (reg:CC 17))])]
12652 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
12653
12654 (define_peephole2
12655 [(set (strict_low_part (match_operand 0 "register_operand" ""))
12656 (const_int 0))]
12657 "(GET_MODE (operands[0]) == QImode
12658 || GET_MODE (operands[0]) == HImode)
12659 && (! TARGET_USE_MOV0 || optimize_size)
12660 && peep2_regno_dead_p (0, FLAGS_REG)"
12661 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
12662 (clobber (reg:CC 17))])])
12663
12664 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
12665 (define_peephole2
12666 [(set (match_operand 0 "register_operand" "")
12667 (const_int -1))]
12668 "(GET_MODE (operands[0]) == HImode
12669 || GET_MODE (operands[0]) == SImode)
12670 && (optimize_size || TARGET_PENTIUM)
12671 && peep2_regno_dead_p (0, FLAGS_REG)"
12672 [(parallel [(set (match_dup 0) (const_int -1))
12673 (clobber (reg:CC 17))])]
12674 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
12675
12676 ;; Attempt to convert simple leas to adds. These can be created by
12677 ;; move expanders.
12678 (define_peephole2
12679 [(set (match_operand:SI 0 "register_operand" "")
12680 (plus:SI (match_dup 0)
12681 (match_operand:SI 1 "nonmemory_operand" "")))]
12682 "peep2_regno_dead_p (0, FLAGS_REG)"
12683 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
12684 (clobber (reg:CC 17))])]
12685 "")
12686
12687 (define_peephole2
12688 [(set (match_operand:SI 0 "register_operand" "")
12689 (mult:SI (match_dup 0)
12690 (match_operand:SI 1 "immediate_operand" "")))]
12691 "exact_log2 (INTVAL (operands[1])) >= 0
12692 && peep2_regno_dead_p (0, FLAGS_REG)"
12693 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
12694 (clobber (reg:CC 17))])]
12695 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
12696
12697 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
12698 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
12699 ;; many CPUs it is also faster, since special hardware to avoid esp
12700 ;; dependancies is present.
12701
12702 ;; While some of these converisons may be done using splitters, we use peepholes
12703 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
12704
12705 ;; Convert prologue esp substractions to push.
12706 ;; We need register to push. In order to keep verify_flow_info happy we have
12707 ;; two choices
12708 ;; - use scratch and clobber it in order to avoid dependencies
12709 ;; - use already live register
12710 ;; We can't use the second way right now, since there is no reliable way how to
12711 ;; verify that given register is live. First choice will also most likely in
12712 ;; fewer dependencies. On the place of esp adjustments it is very likely that
12713 ;; call clobbered registers are dead. We may want to use base pointer as an
12714 ;; alternative when no register is available later.
12715
12716 (define_peephole2
12717 [(match_scratch:SI 0 "r")
12718 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
12719 (set (reg:SI 6) (reg:SI 6))
12720 (clobber (reg:CC 17))])]
12721 "optimize_size || !TARGET_SUB_ESP_4"
12722 [(clobber (match_dup 0))
12723 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12724 (set (reg:SI 6) (reg:SI 6))])])
12725
12726 (define_peephole2
12727 [(match_scratch:SI 0 "r")
12728 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12729 (set (reg:SI 6) (reg:SI 6))
12730 (clobber (reg:CC 17))])]
12731 "optimize_size || !TARGET_SUB_ESP_8"
12732 [(clobber (match_dup 0))
12733 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12734 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12735 (set (reg:SI 6) (reg:SI 6))])])
12736
12737 ;; Convert esp substractions to push.
12738 (define_peephole2
12739 [(match_scratch:SI 0 "r")
12740 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
12741 (clobber (reg:CC 17))])]
12742 "optimize_size || !TARGET_SUB_ESP_4"
12743 [(clobber (match_dup 0))
12744 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
12745
12746 (define_peephole2
12747 [(match_scratch:SI 0 "r")
12748 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12749 (clobber (reg:CC 17))])]
12750 "optimize_size || !TARGET_SUB_ESP_8"
12751 [(clobber (match_dup 0))
12752 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12753 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
12754
12755 ;; Convert epilogue deallocator to pop.
12756 (define_peephole2
12757 [(match_scratch:SI 0 "r")
12758 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12759 (set (reg:SI 6) (reg:SI 6))
12760 (clobber (reg:CC 17))])]
12761 "optimize_size || !TARGET_ADD_ESP_4"
12762 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12763 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12764 (set (reg:SI 6) (reg:SI 6))])]
12765 "")
12766
12767 ;; Two pops case is tricky, since pop causes dependency on destination register.
12768 ;; We use two registers if available.
12769 (define_peephole2
12770 [(match_scratch:SI 0 "r")
12771 (match_scratch:SI 1 "r")
12772 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12773 (set (reg:SI 6) (reg:SI 6))
12774 (clobber (reg:CC 17))])]
12775 "optimize_size || !TARGET_ADD_ESP_8"
12776 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12777 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12778 (set (reg:SI 6) (reg:SI 6))])
12779 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
12780 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12781 "")
12782
12783 (define_peephole2
12784 [(match_scratch:SI 0 "r")
12785 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12786 (set (reg:SI 6) (reg:SI 6))
12787 (clobber (reg:CC 17))])]
12788 "optimize_size"
12789 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12790 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12791 (set (reg:SI 6) (reg:SI 6))])
12792 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12793 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12794 "")
12795
12796 ;; Convert esp additions to pop.
12797 (define_peephole2
12798 [(match_scratch:SI 0 "r")
12799 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12800 (clobber (reg:CC 17))])]
12801 ""
12802 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12803 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12804 "")
12805
12806 ;; Two pops case is tricky, since pop causes dependency on destination register.
12807 ;; We use two registers if available.
12808 (define_peephole2
12809 [(match_scratch:SI 0 "r")
12810 (match_scratch:SI 1 "r")
12811 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12812 (clobber (reg:CC 17))])]
12813 ""
12814 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12815 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
12816 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
12817 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12818 "")
12819
12820 (define_peephole2
12821 [(match_scratch:SI 0 "r")
12822 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12823 (clobber (reg:CC 17))])]
12824 "optimize_size"
12825 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12826 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
12827 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12828 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12829 "")
12830 \f
12831 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
12832 ;; required and register dies.
12833 (define_peephole2
12834 [(set (reg 17)
12835 (compare (match_operand:SI 0 "register_operand" "")
12836 (match_operand:SI 1 "incdec_operand" "")))]
12837 "ix86_match_ccmode (insn, CCGCmode)
12838 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12839 [(parallel [(set (reg:CCGC 17)
12840 (compare:CCGC (match_dup 0)
12841 (match_dup 1)))
12842 (clobber (match_dup 0))])]
12843 "")
12844
12845 (define_peephole2
12846 [(set (reg 17)
12847 (compare (match_operand:HI 0 "register_operand" "")
12848 (match_operand:HI 1 "incdec_operand" "")))]
12849 "ix86_match_ccmode (insn, CCGCmode)
12850 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12851 [(parallel [(set (reg:CCGC 17)
12852 (compare:CCGC (match_dup 0)
12853 (match_dup 1)))
12854 (clobber (match_dup 0))])]
12855 "")
12856
12857 (define_peephole2
12858 [(set (reg 17)
12859 (compare (match_operand:QI 0 "register_operand" "")
12860 (match_operand:QI 1 "incdec_operand" "")))]
12861 "ix86_match_ccmode (insn, CCGCmode)
12862 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12863 [(parallel [(set (reg:CCGC 17)
12864 (compare:CCGC (match_dup 0)
12865 (match_dup 1)))
12866 (clobber (match_dup 0))])]
12867 "")
12868
12869 ;; Convert compares with 128 to shorter add -128
12870 (define_peephole2
12871 [(set (reg 17)
12872 (compare (match_operand:SI 0 "register_operand" "")
12873 (const_int 128)))]
12874 "ix86_match_ccmode (insn, CCGCmode)
12875 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12876 [(parallel [(set (reg:CCGC 17)
12877 (compare:CCGC (match_dup 0)
12878 (const_int 128)))
12879 (clobber (match_dup 0))])]
12880 "")
12881
12882 (define_peephole2
12883 [(set (reg 17)
12884 (compare (match_operand:HI 0 "register_operand" "")
12885 (const_int 128)))]
12886 "ix86_match_ccmode (insn, CCGCmode)
12887 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12888 [(parallel [(set (reg:CCGC 17)
12889 (compare:CCGC (match_dup 0)
12890 (const_int 128)))
12891 (clobber (match_dup 0))])]
12892 "")
12893 \f
12894 ;; Call-value patterns last so that the wildcard operand does not
12895 ;; disrupt insn-recog's switch tables.
12896
12897 (define_insn "*call_value_pop_0"
12898 [(set (match_operand 0 "" "")
12899 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
12900 (match_operand:SI 2 "" "")))
12901 (set (reg:SI 7) (plus:SI (reg:SI 7)
12902 (match_operand:SI 3 "immediate_operand" "")))]
12903 ""
12904 "*
12905 {
12906 if (SIBLING_CALL_P (insn))
12907 return \"jmp\\t%P1\";
12908 else
12909 return \"call\\t%P1\";
12910 }"
12911 [(set_attr "type" "callv")])
12912
12913 (define_insn "*call_value_pop_1"
12914 [(set (match_operand 0 "" "")
12915 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
12916 (match_operand:SI 2 "" "")))
12917 (set (reg:SI 7) (plus:SI (reg:SI 7)
12918 (match_operand:SI 3 "immediate_operand" "i")))]
12919 ""
12920 "*
12921 {
12922 if (constant_call_address_operand (operands[1], QImode))
12923 {
12924 if (SIBLING_CALL_P (insn))
12925 return \"jmp\\t%P1\";
12926 else
12927 return \"call\\t%P1\";
12928 }
12929 if (SIBLING_CALL_P (insn))
12930 return \"jmp\\t%A1\";
12931 else
12932 return \"call\\t%A1\";
12933 }"
12934 [(set_attr "type" "callv")])
12935
12936 (define_insn "*call_value_0"
12937 [(set (match_operand 0 "" "")
12938 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
12939 (match_operand:SI 2 "" "")))]
12940 ""
12941 "*
12942 {
12943 if (SIBLING_CALL_P (insn))
12944 return \"jmp\\t%P1\";
12945 else
12946 return \"call\\t%P1\";
12947 }"
12948 [(set_attr "type" "callv")])
12949
12950 (define_insn "*call_value_1"
12951 [(set (match_operand 0 "" "")
12952 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
12953 (match_operand:SI 2 "" "")))]
12954 ""
12955 "*
12956 {
12957 if (constant_call_address_operand (operands[1], QImode))
12958 {
12959 if (SIBLING_CALL_P (insn))
12960 return \"jmp\\t%P1\";
12961 else
12962 return \"call\\t%P1\";
12963 }
12964 if (SIBLING_CALL_P (insn))
12965 return \"jmp\\t%A1\";
12966 else
12967 return \"call\\t%A1\";
12968 }"
12969 [(set_attr "type" "callv")])
12970 \f
12971 (define_insn "trap"
12972 [(trap_if (const_int 1) (const_int 5))]
12973 ""
12974 "int\\t$5")
12975
12976 ;;; ix86 doesn't have conditional trap instructions, but we fake them
12977 ;;; for the sake of bounds checking. By emitting bounds checks as
12978 ;;; conditional traps rather than as conditional jumps around
12979 ;;; unconditional traps we avoid introducing spurious basic-block
12980 ;;; boundaries and facilitate elimination of redundant checks. In
12981 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
12982 ;;; interrupt 5.
12983 ;;;
12984 ;;; FIXME: Static branch prediction rules for ix86 are such that
12985 ;;; forward conditional branches predict as untaken. As implemented
12986 ;;; below, pseudo conditional traps violate that rule. We should use
12987 ;;; .pushsection/.popsection to place all of the `int 5's in a special
12988 ;;; section loaded at the end of the text segment and branch forward
12989 ;;; there on bounds-failure, and then jump back immediately (in case
12990 ;;; the system chooses to ignore bounds violations, or to report
12991 ;;; violations and continue execution).
12992
12993 (define_expand "conditional_trap"
12994 [(trap_if (match_operator 0 "comparison_operator"
12995 [(match_dup 2) (const_int 0)])
12996 (match_operand 1 "const_int_operand" ""))]
12997 ""
12998 "
12999 {
13000 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
13001 ix86_expand_compare (GET_CODE (operands[0]),
13002 NULL_RTX, NULL_RTX),
13003 operands[1]));
13004 DONE;
13005 }")
13006
13007 (define_insn ""
13008 [(trap_if (match_operator 0 "comparison_operator"
13009 [(reg 17) (const_int 0)])
13010 (match_operand 1 "const_int_operand" ""))]
13011 ""
13012 "*
13013 {
13014 operands[2] = gen_label_rtx ();
13015 output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands);
13016 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
13017 CODE_LABEL_NUMBER (operands[2]));
13018 RET;
13019 }")
13020
13021 ;; Pentium III SIMD instructions.
13022
13023 ;; Moves for SSE/MMX regs.
13024
13025 (define_insn "movv4sf_internal"
13026 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13027 (match_operand:V4SF 1 "general_operand" "xm,x"))]
13028 "TARGET_SSE"
13029 ;; @@@ let's try to use movaps here.
13030 "movaps\\t{%1, %0|%0, %1}"
13031 [(set_attr "type" "sse")])
13032
13033 (define_insn "movv4si_internal"
13034 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
13035 (match_operand:V4SI 1 "general_operand" "xm,x"))]
13036 "TARGET_SSE"
13037 ;; @@@ let's try to use movaps here.
13038 "movaps\\t{%1, %0|%0, %1}"
13039 [(set_attr "type" "sse")])
13040
13041 (define_insn "movv8qi_internal"
13042 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
13043 (match_operand:V8QI 1 "general_operand" "ym,y"))]
13044 "TARGET_MMX"
13045 "movq\\t{%1, %0|%0, %1}"
13046 [(set_attr "type" "mmx")])
13047
13048 (define_insn "movv4hi_internal"
13049 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
13050 (match_operand:V4HI 1 "general_operand" "ym,y"))]
13051 "TARGET_MMX"
13052 "movq\\t{%1, %0|%0, %1}"
13053 [(set_attr "type" "mmx")])
13054
13055 (define_insn "movv2si_internal"
13056 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
13057 (match_operand:V2SI 1 "general_operand" "ym,y"))]
13058 "TARGET_MMX"
13059 "movq\\t{%1, %0|%0, %1}"
13060 [(set_attr "type" "mmx")])
13061
13062 (define_expand "movti"
13063 [(set (match_operand:TI 0 "general_operand" "")
13064 (match_operand:TI 1 "general_operand" ""))]
13065 "TARGET_SSE"
13066 "
13067 {
13068 /* For constants other than zero into memory. We do not know how the
13069 instructions used to build constants modify the upper 64 bits
13070 of the register, once we have that information we may be able
13071 to handle some of them more efficiently. */
13072 if ((reload_in_progress | reload_completed) == 0
13073 && register_operand (operands[0], TImode)
13074 && CONSTANT_P (operands[1]))
13075 {
13076 rtx addr = gen_reg_rtx (Pmode);
13077
13078 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
13079 operands[1] = gen_rtx_MEM (TImode, addr);
13080 }
13081
13082 /* Make operand1 a register if it isn't already. */
13083 if ((reload_in_progress | reload_completed) == 0
13084 && !register_operand (operands[0], TImode)
13085 && !register_operand (operands[1], TImode)
13086 && operands[1] != CONST0_RTX (TImode))
13087 {
13088 rtx temp = force_reg (TImode, operands[1]);
13089 emit_move_insn (operands[0], temp);
13090 DONE;
13091 }
13092 }")
13093
13094 (define_expand "movv4sf"
13095 [(set (match_operand:V4SF 0 "general_operand" "")
13096 (match_operand:V4SF 1 "general_operand" ""))]
13097 "TARGET_SSE"
13098 "
13099 {
13100 /* For constants other than zero into memory. We do not know how the
13101 instructions used to build constants modify the upper 64 bits
13102 of the register, once we have that information we may be able
13103 to handle some of them more efficiently. */
13104 if ((reload_in_progress | reload_completed) == 0
13105 && register_operand (operands[0], V4SFmode)
13106 && CONSTANT_P (operands[1]))
13107 {
13108 rtx addr = gen_reg_rtx (Pmode);
13109
13110 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
13111 operands[1] = gen_rtx_MEM (V4SFmode, addr);
13112 }
13113
13114 /* Make operand1 a register if it isn't already. */
13115 if ((reload_in_progress | reload_completed) == 0
13116 && !register_operand (operands[0], V4SFmode)
13117 && !register_operand (operands[1], V4SFmode)
13118 && operands[1] != CONST0_RTX (V4SFmode))
13119 {
13120 rtx temp = force_reg (V4SFmode, operands[1]);
13121 emit_move_insn (operands[0], temp);
13122 DONE;
13123 }
13124 }")
13125
13126 (define_expand "movv4si"
13127 [(set (match_operand:V4SI 0 "general_operand" "")
13128 (match_operand:V4SI 1 "general_operand" ""))]
13129 "TARGET_MMX"
13130 "
13131 {
13132 /* For constants other than zero into memory. We do not know how the
13133 instructions used to build constants modify the upper 64 bits
13134 of the register, once we have that information we may be able
13135 to handle some of them more efficiently. */
13136 if ((reload_in_progress | reload_completed) == 0
13137 && register_operand (operands[0], V4SImode)
13138 && CONSTANT_P (operands[1]))
13139 {
13140 rtx addr = gen_reg_rtx (Pmode);
13141
13142 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
13143 operands[1] = gen_rtx_MEM (V4SImode, addr);
13144 }
13145
13146 /* Make operand1 a register if it isn't already. */
13147 if ((reload_in_progress | reload_completed) == 0
13148 && !register_operand (operands[0], V4SImode)
13149 && !register_operand (operands[1], V4SImode)
13150 && operands[1] != CONST0_RTX (V4SImode))
13151 {
13152 rtx temp = force_reg (V4SImode, operands[1]);
13153 emit_move_insn (operands[0], temp);
13154 DONE;
13155 }
13156 }")
13157
13158 (define_expand "movv2si"
13159 [(set (match_operand:V2SI 0 "general_operand" "")
13160 (match_operand:V2SI 1 "general_operand" ""))]
13161 "TARGET_MMX"
13162 "
13163 {
13164 /* For constants other than zero into memory. We do not know how the
13165 instructions used to build constants modify the upper 64 bits
13166 of the register, once we have that information we may be able
13167 to handle some of them more efficiently. */
13168 if ((reload_in_progress | reload_completed) == 0
13169 && register_operand (operands[0], V2SImode)
13170 && CONSTANT_P (operands[1]))
13171 {
13172 rtx addr = gen_reg_rtx (Pmode);
13173
13174 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
13175 operands[1] = gen_rtx_MEM (V2SImode, addr);
13176 }
13177
13178 /* Make operand1 a register if it isn't already. */
13179 if ((reload_in_progress | reload_completed) == 0
13180 && !register_operand (operands[0], V2SImode)
13181 && !register_operand (operands[1], V2SImode)
13182 && operands[1] != CONST0_RTX (V2SImode))
13183 {
13184 rtx temp = force_reg (V2SImode, operands[1]);
13185 emit_move_insn (operands[0], temp);
13186 DONE;
13187 }
13188 }")
13189
13190 (define_expand "movv4hi"
13191 [(set (match_operand:V4HI 0 "general_operand" "")
13192 (match_operand:V4HI 1 "general_operand" ""))]
13193 "TARGET_MMX"
13194 "
13195 {
13196 /* For constants other than zero into memory. We do not know how the
13197 instructions used to build constants modify the upper 64 bits
13198 of the register, once we have that information we may be able
13199 to handle some of them more efficiently. */
13200 if ((reload_in_progress | reload_completed) == 0
13201 && register_operand (operands[0], V4HImode)
13202 && CONSTANT_P (operands[1]))
13203 {
13204 rtx addr = gen_reg_rtx (Pmode);
13205
13206 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
13207 operands[1] = gen_rtx_MEM (V4HImode, addr);
13208 }
13209
13210 /* Make operand1 a register if it isn't already. */
13211 if ((reload_in_progress | reload_completed) == 0
13212 && !register_operand (operands[0], V4HImode)
13213 && !register_operand (operands[1], V4HImode)
13214 && operands[1] != CONST0_RTX (V4HImode))
13215 {
13216 rtx temp = force_reg (V4HImode, operands[1]);
13217 emit_move_insn (operands[0], temp);
13218 DONE;
13219 }
13220 }")
13221
13222 (define_expand "movv8qi"
13223 [(set (match_operand:V8QI 0 "general_operand" "")
13224 (match_operand:V8QI 1 "general_operand" ""))]
13225 "TARGET_MMX"
13226 "
13227 {
13228 /* For constants other than zero into memory. We do not know how the
13229 instructions used to build constants modify the upper 64 bits
13230 of the register, once we have that information we may be able
13231 to handle some of them more efficiently. */
13232 if ((reload_in_progress | reload_completed) == 0
13233 && register_operand (operands[0], V8QImode)
13234 && CONSTANT_P (operands[1]))
13235 {
13236 rtx addr = gen_reg_rtx (Pmode);
13237
13238 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
13239 operands[1] = gen_rtx_MEM (V8QImode, addr);
13240 }
13241
13242 /* Make operand1 a register if it isn't already. */
13243 if ((reload_in_progress | reload_completed) == 0
13244 && !register_operand (operands[0], V8QImode)
13245 && !register_operand (operands[1], V8QImode)
13246 && operands[1] != CONST0_RTX (V8QImode))
13247 {
13248 rtx temp = force_reg (V8QImode, operands[1]);
13249 emit_move_insn (operands[0], temp);
13250 DONE;
13251 }
13252 }")
13253
13254 (define_insn_and_split "*pushti"
13255 [(set (match_operand:TI 0 "push_operand" "=<")
13256 (match_operand:TI 1 "nonmemory_operand" "x"))]
13257 "TARGET_SSE"
13258 "#"
13259 ""
13260 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
13261 (set (mem:TI (reg:SI 7)) (match_dup 1))]
13262 ""
13263 [(set_attr "type" "sse")])
13264
13265 (define_insn_and_split "*pushv4sf"
13266 [(set (match_operand:V4SF 0 "push_operand" "=<")
13267 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
13268 "TARGET_SSE"
13269 "#"
13270 ""
13271 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
13272 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
13273 ""
13274 [(set_attr "type" "sse")])
13275
13276 (define_insn_and_split "*pushv4si"
13277 [(set (match_operand:V4SI 0 "push_operand" "=<")
13278 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
13279 "TARGET_SSE"
13280 "#"
13281 ""
13282 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
13283 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
13284 ""
13285 [(set_attr "type" "sse")])
13286
13287 (define_insn_and_split "*pushv2si"
13288 [(set (match_operand:V2SI 0 "push_operand" "=<")
13289 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
13290 "TARGET_MMX"
13291 "#"
13292 ""
13293 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13294 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
13295 ""
13296 [(set_attr "type" "mmx")])
13297
13298 (define_insn_and_split "*pushv4hi"
13299 [(set (match_operand:V4HI 0 "push_operand" "=<")
13300 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
13301 "TARGET_MMX"
13302 "#"
13303 ""
13304 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13305 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
13306 ""
13307 [(set_attr "type" "mmx")])
13308
13309 (define_insn_and_split "*pushv8qi"
13310 [(set (match_operand:V8QI 0 "push_operand" "=<")
13311 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
13312 "TARGET_MMX"
13313 "#"
13314 ""
13315 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13316 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
13317 ""
13318 [(set_attr "type" "mmx")])
13319
13320 (define_insn "movti_internal"
13321 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
13322 (match_operand:TI 1 "general_operand" "xm,x"))]
13323 "TARGET_SSE"
13324 "@
13325 movaps\\t{%1, %0|%0, %1}
13326 movaps\\t{%1, %0|%0, %1}"
13327 [(set_attr "type" "sse")])
13328
13329 ;; These two patterns are useful for specifying exactly whether to use
13330 ;; movaps or movups
13331 (define_insn "sse_movaps"
13332 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13333 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
13334 "TARGET_SSE"
13335 "@
13336 movaps\\t{%1, %0|%0, %1}
13337 movaps\\t{%1, %0|%0, %1}"
13338 [(set_attr "type" "sse")])
13339
13340 (define_insn "sse_movups"
13341 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13342 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
13343 "TARGET_SSE"
13344 "@
13345 movups\\t{%1, %0|%0, %1}
13346 movups\\t{%1, %0|%0, %1}"
13347 [(set_attr "type" "sse")])
13348
13349
13350 ;; SSE Strange Moves.
13351
13352 (define_insn "sse_movmskps"
13353 [(set (match_operand:SI 0 "register_operand" "=r")
13354 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
13355 "TARGET_SSE"
13356 "movmskps\\t{%1, %0|%0, %1}"
13357 [(set_attr "type" "sse")])
13358
13359 (define_insn "mmx_pmovmskb"
13360 [(set (match_operand:SI 0 "register_operand" "=r")
13361 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
13362 "TARGET_SSE"
13363 "pmovmskb\\t{%1, %0|%0, %1}"
13364 [(set_attr "type" "sse")])
13365
13366 (define_insn "mmx_maskmovq"
13367 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
13368 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
13369 (match_operand:V8QI 2 "register_operand" "y")] 32))]
13370 "TARGET_SSE"
13371 ;; @@@ check ordering of operands in intel/nonintel syntax
13372 "maskmovq\\t{%2, %1|%1, %2}"
13373 [(set_attr "type" "sse")])
13374
13375 (define_insn "sse_movntv4sf"
13376 [(set (match_operand:V4SF 0 "memory_operand" "=m")
13377 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
13378 "TARGET_SSE"
13379 "movntps\\t{%1, %0|%0, %1}"
13380 [(set_attr "type" "sse")])
13381
13382 (define_insn "sse_movntdi"
13383 [(set (match_operand:DI 0 "memory_operand" "=m")
13384 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
13385 "TARGET_SSE"
13386 "movntq\\t{%1, %0|%0, %1}"
13387 [(set_attr "type" "sse")])
13388
13389 (define_insn "sse_movhlps"
13390 [(set (match_operand:V4SF 0 "register_operand" "=x")
13391 (vec_merge:V4SF
13392 (match_operand:V4SF 1 "register_operand" "0")
13393 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
13394 (parallel [(const_int 2)
13395 (const_int 3)
13396 (const_int 0)
13397 (const_int 1)]))
13398 (const_int 3)))]
13399 "TARGET_SSE"
13400 "movhlps\\t{%2, %0|%0, %2}"
13401 [(set_attr "type" "sse")])
13402
13403 (define_insn "sse_movlhps"
13404 [(set (match_operand:V4SF 0 "register_operand" "=x")
13405 (vec_merge:V4SF
13406 (match_operand:V4SF 1 "register_operand" "0")
13407 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
13408 (parallel [(const_int 2)
13409 (const_int 3)
13410 (const_int 0)
13411 (const_int 1)]))
13412 (const_int 12)))]
13413 "TARGET_SSE"
13414 "movlhps\\t{%2, %0|%0, %2}"
13415 [(set_attr "type" "sse")])
13416
13417 (define_insn "sse_movhps"
13418 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13419 (vec_merge:V4SF
13420 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
13421 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
13422 (const_int 12)))]
13423 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
13424 "movhps\\t{%2, %0|%0, %2}"
13425 [(set_attr "type" "sse")])
13426
13427 (define_insn "sse_movlps"
13428 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13429 (vec_merge:V4SF
13430 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
13431 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
13432 (const_int 3)))]
13433 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
13434 "movlps\\t{%2, %0|%0, %2}"
13435 [(set_attr "type" "sse")])
13436
13437 (define_insn "sse_loadss"
13438 [(set (match_operand:V4SF 0 "register_operand" "=x")
13439 (vec_merge:V4SF
13440 (match_operand:V4SF 1 "memory_operand" "m")
13441 (vec_duplicate:V4SF (float:SF (const_int 0)))
13442 (const_int 1)))]
13443 "TARGET_SSE"
13444 "movss\\t{%1, %0|%0, %1}"
13445 [(set_attr "type" "sse")])
13446
13447 (define_insn "sse_movss"
13448 [(set (match_operand:V4SF 0 "register_operand" "=x")
13449 (vec_merge:V4SF
13450 (match_operand:V4SF 1 "register_operand" "0")
13451 (match_operand:V4SF 2 "register_operand" "x")
13452 (const_int 1)))]
13453 "TARGET_SSE"
13454 "movss\\t{%2, %0|%0, %2}"
13455 [(set_attr "type" "sse")])
13456
13457 (define_insn "sse_storess"
13458 [(set (match_operand:SF 0 "memory_operand" "=m")
13459 (vec_select:SF
13460 (match_operand:V4SF 1 "register_operand" "x")
13461 (parallel [(const_int 0)])))]
13462 "TARGET_SSE"
13463 "movss\\t{%1, %0|%0, %1}"
13464 [(set_attr "type" "sse")])
13465
13466 (define_insn "sse_shufps"
13467 [(set (match_operand:V4SF 0 "register_operand" "=x")
13468 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
13469 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
13470 (match_operand:SI 3 "immediate_operand" "i")] 41))]
13471 "TARGET_SSE"
13472 ;; @@@ check operand order for intel/nonintel syntax
13473 "shufps\\t{%3, %2, %0|%0, %2, %3}"
13474 [(set_attr "type" "sse")])
13475
13476
13477 ;; SSE arithmetic
13478
13479 (define_insn "addv4sf3"
13480 [(set (match_operand:V4SF 0 "register_operand" "=x")
13481 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13482 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13483 "TARGET_SSE"
13484 "addps\\t{%2, %0|%0, %2}"
13485 [(set_attr "type" "sse")])
13486
13487 (define_insn "vmaddv4sf3"
13488 [(set (match_operand:V4SF 0 "register_operand" "=x")
13489 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13490 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13491 (match_dup 1)
13492 (const_int 1)))]
13493 "TARGET_SSE"
13494 "addss\\t{%2, %0|%0, %2}"
13495 [(set_attr "type" "sse")])
13496
13497 (define_insn "subv4sf3"
13498 [(set (match_operand:V4SF 0 "register_operand" "=x")
13499 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13500 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13501 "TARGET_SSE"
13502 "subps\\t{%2, %0|%0, %2}"
13503 [(set_attr "type" "sse")])
13504
13505 (define_insn "vmsubv4sf3"
13506 [(set (match_operand:V4SF 0 "register_operand" "=x")
13507 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13508 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13509 (match_dup 1)
13510 (const_int 1)))]
13511 "TARGET_SSE"
13512 "subss\\t{%2, %0|%0, %2}"
13513 [(set_attr "type" "sse")])
13514
13515 (define_insn "mulv4sf3"
13516 [(set (match_operand:V4SF 0 "register_operand" "=x")
13517 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
13518 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13519 "TARGET_SSE"
13520 "mulps\\t{%2, %0|%0, %2}"
13521 [(set_attr "type" "sse")])
13522
13523 (define_insn "vmmulv4sf3"
13524 [(set (match_operand:V4SF 0 "register_operand" "=x")
13525 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
13526 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13527 (match_dup 1)
13528 (const_int 1)))]
13529 "TARGET_SSE"
13530 "mulss\\t{%2, %0|%0, %2}"
13531 [(set_attr "type" "sse")])
13532
13533 (define_insn "divv4sf3"
13534 [(set (match_operand:V4SF 0 "register_operand" "=x")
13535 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
13536 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13537 "TARGET_SSE"
13538 "divps\\t{%2, %0|%0, %2}"
13539 [(set_attr "type" "sse")])
13540
13541 (define_insn "vmdivv4sf3"
13542 [(set (match_operand:V4SF 0 "register_operand" "=x")
13543 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
13544 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13545 (match_dup 1)
13546 (const_int 1)))]
13547 "TARGET_SSE"
13548 "divss\\t{%2, %0|%0, %2}"
13549 [(set_attr "type" "sse")])
13550
13551
13552 ;; SSE square root/reciprocal
13553
13554 (define_insn "rcpv4sf2"
13555 [(set (match_operand:V4SF 0 "register_operand" "=x")
13556 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
13557 "TARGET_SSE"
13558 "rcpps\\t{%1, %0|%0, %1}"
13559 [(set_attr "type" "sse")])
13560
13561 (define_insn "vmrcpv4sf2"
13562 [(set (match_operand:V4SF 0 "register_operand" "=x")
13563 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
13564 (match_operand:V4SF 2 "register_operand" "0")
13565 (const_int 1)))]
13566 "TARGET_SSE"
13567 "rcpss\\t{%1, %0|%0, %1}"
13568 [(set_attr "type" "sse")])
13569
13570 (define_insn "rsqrtv4sf2"
13571 [(set (match_operand:V4SF 0 "register_operand" "=x")
13572 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
13573 "TARGET_SSE"
13574 "rsqrtps\\t{%1, %0|%0, %1}"
13575 [(set_attr "type" "sse")])
13576
13577 (define_insn "vmrsqrtv4sf2"
13578 [(set (match_operand:V4SF 0 "register_operand" "=x")
13579 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
13580 (match_operand:V4SF 2 "register_operand" "0")
13581 (const_int 1)))]
13582 "TARGET_SSE"
13583 "rsqrtss\\t{%1, %0|%0, %1}"
13584 [(set_attr "type" "sse")])
13585
13586 (define_insn "sqrtv4sf2"
13587 [(set (match_operand:V4SF 0 "register_operand" "=x")
13588 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
13589 "TARGET_SSE"
13590 "sqrtps\\t{%1, %0|%0, %1}"
13591 [(set_attr "type" "sse")])
13592
13593 (define_insn "vmsqrtv4sf2"
13594 [(set (match_operand:V4SF 0 "register_operand" "=x")
13595 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
13596 (match_operand:V4SF 2 "register_operand" "0")
13597 (const_int 1)))]
13598 "TARGET_SSE"
13599 "sqrtss\\t{%1, %0|%0, %1}"
13600 [(set_attr "type" "sse")])
13601
13602
13603 ;; SSE logical operations.
13604
13605 ;; These are not called andti3 etc. because we really really don't want
13606 ;; the compiler to widen DImode ands to TImode ands and then try to move
13607 ;; into DImode subregs of SSE registers, and them together, and move out
13608 ;; of DImode subregs again!
13609
13610 (define_insn "sse_andti3"
13611 [(set (match_operand:TI 0 "register_operand" "=x")
13612 (and:TI (match_operand:TI 1 "register_operand" "0")
13613 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13614 "TARGET_SSE"
13615 "andps\\t{%2, %0|%0, %2}"
13616 [(set_attr "type" "sse")])
13617
13618 (define_insn "sse_nandti3"
13619 [(set (match_operand:TI 0 "register_operand" "=x")
13620 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
13621 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13622 "TARGET_SSE"
13623 "andnps\\t{%2, %0|%0, %2}"
13624 [(set_attr "type" "sse")])
13625
13626 (define_insn "sse_iorti3"
13627 [(set (match_operand:TI 0 "register_operand" "=x")
13628 (ior:TI (match_operand:TI 1 "register_operand" "0")
13629 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13630 "TARGET_SSE"
13631 "iorps\\t{%2, %0|%0, %2}"
13632 [(set_attr "type" "sse")])
13633
13634 (define_insn "sse_xorti3"
13635 [(set (match_operand:TI 0 "register_operand" "=x")
13636 (xor:TI (match_operand:TI 1 "register_operand" "0")
13637 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13638 "TARGET_SSE"
13639 "xorps\\t{%2, %0|%0, %2}"
13640 [(set_attr "type" "sse")])
13641
13642 ;; Use xor, but don't show input operands so they aren't live before
13643 ;; this insn.
13644 (define_insn "sse_clrti"
13645 [(set (match_operand:TI 0 "register_operand" "=x")
13646 (unspec:TI [(const_int 0)] 45))]
13647 "TARGET_SSE"
13648 "xorps\\t{%0, %0|%0, %0}"
13649 [(set_attr "type" "sse")])
13650
13651
13652 ;; SSE mask-generating compares
13653
13654 (define_insn "maskcmpv4sf3"
13655 [(set (match_operand:V4SI 0 "register_operand" "=x")
13656 (match_operator:V4SI 3 "sse_comparison_operator"
13657 [(match_operand:V4SF 1 "register_operand" "0")
13658 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
13659 "TARGET_SSE"
13660 "*
13661 {
13662 switch (GET_CODE (operands[3]))
13663 {
13664 case EQ:
13665 return \"cmpeqps\\t{%2, %0|%0, %2}\";
13666 case LT:
13667 return \"cmpltps\\t{%2, %0|%0, %2}\";
13668 case LE:
13669 return \"cmpleps\\t{%2, %0|%0, %2}\";
13670 case UNORDERED:
13671 return \"cmpunordps\\t{%2, %0|%0, %2}\";
13672 default:
13673 abort ();
13674 }
13675 }"
13676 [(set_attr "type" "sse")])
13677
13678 (define_insn "maskncmpv4sf3"
13679 [(set (match_operand:V4SI 0 "register_operand" "=x")
13680 (not:V4SI
13681 (match_operator:V4SI 3 "sse_comparison_operator"
13682 [(match_operand:V4SF 1 "register_operand" "0")
13683 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
13684 "TARGET_SSE"
13685 "*
13686 {
13687 switch (GET_CODE (operands[3]))
13688 {
13689 case EQ:
13690 return \"cmpneqps\\t{%2, %0|%0, %2}\";
13691 case LT:
13692 return \"cmpnltps\\t{%2, %0|%0, %2}\";
13693 case LE:
13694 return \"cmpnleps\\t{%2, %0|%0, %2}\";
13695 case UNORDERED:
13696 return \"cmpordps\\t{%2, %0|%0, %2}\";
13697 default:
13698 abort ();
13699 }
13700 }"
13701 [(set_attr "type" "sse")])
13702
13703 (define_insn "vmmaskcmpv4sf3"
13704 [(set (match_operand:V4SI 0 "register_operand" "=x")
13705 (vec_merge:V4SI
13706 (match_operator:V4SI 3 "sse_comparison_operator"
13707 [(match_operand:V4SF 1 "register_operand" "0")
13708 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
13709 (match_dup 1)
13710 (const_int 1)))]
13711 "TARGET_SSE"
13712 "*
13713 {
13714 switch (GET_CODE (operands[3]))
13715 {
13716 case EQ:
13717 return \"cmpeqss\\t{%2, %0|%0, %2}\";
13718 case LT:
13719 return \"cmpltss\\t{%2, %0|%0, %2}\";
13720 case LE:
13721 return \"cmpless\\t{%2, %0|%0, %2}\";
13722 case UNORDERED:
13723 return \"cmpunordss\\t{%2, %0|%0, %2}\";
13724 default:
13725 abort ();
13726 }
13727 }"
13728 [(set_attr "type" "sse")])
13729
13730 (define_insn "vmmaskncmpv4sf3"
13731 [(set (match_operand:V4SI 0 "register_operand" "=x")
13732 (vec_merge:V4SI
13733 (not:V4SI
13734 (match_operator:V4SI 3 "sse_comparison_operator"
13735 [(match_operand:V4SF 1 "register_operand" "0")
13736 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
13737 (subreg:V4SI (match_dup 1) 0)
13738 (const_int 1)))]
13739 "TARGET_SSE"
13740 "*
13741 {
13742 switch (GET_CODE (operands[3]))
13743 {
13744 case EQ:
13745 return \"cmpneqss\\t{%2, %0|%0, %2}\";
13746 case LT:
13747 return \"cmpnltss\\t{%2, %0|%0, %2}\";
13748 case LE:
13749 return \"cmpnless\\t{%2, %0|%0, %2}\";
13750 case UNORDERED:
13751 return \"cmpordss\\t{%2, %0|%0, %2}\";
13752 default:
13753 abort ();
13754 }
13755 }"
13756 [(set_attr "type" "sse")])
13757
13758 (define_insn "sse_comi"
13759 [(set (reg:CCFP 17)
13760 (match_operator:CCFP 2 "sse_comparison_operator"
13761 [(vec_select:SF
13762 (match_operand:V4SF 0 "register_operand" "x")
13763 (parallel [(const_int 0)]))
13764 (vec_select:SF
13765 (match_operand:V4SF 1 "register_operand" "x")
13766 (parallel [(const_int 0)]))]))]
13767 "TARGET_SSE"
13768 "comiss\\t{%2, %0|%0, %2}"
13769 [(set_attr "type" "sse")])
13770
13771 (define_insn "sse_ucomi"
13772 [(set (reg:CCFPU 17)
13773 (match_operator:CCFPU 2 "sse_comparison_operator"
13774 [(vec_select:SF
13775 (match_operand:V4SF 0 "register_operand" "x")
13776 (parallel [(const_int 0)]))
13777 (vec_select:SF
13778 (match_operand:V4SF 1 "register_operand" "x")
13779 (parallel [(const_int 0)]))]))]
13780 "TARGET_SSE"
13781 "ucomiss\\t{%2, %0|%0, %2}"
13782 [(set_attr "type" "sse")])
13783
13784
13785 ;; SSE unpack
13786
13787 (define_insn "sse_unpckhps"
13788 [(set (match_operand:V4SF 0 "register_operand" "=x")
13789 (vec_merge:V4SF
13790 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
13791 (parallel [(const_int 2)
13792 (const_int 0)
13793 (const_int 3)
13794 (const_int 1)]))
13795 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
13796 (parallel [(const_int 0)
13797 (const_int 2)
13798 (const_int 1)
13799 (const_int 3)]))
13800 (const_int 5)))]
13801 "TARGET_SSE"
13802 "unpckhps\\t{%2, %0|%0, %2}"
13803 [(set_attr "type" "sse")])
13804
13805 (define_insn "sse_unpcklps"
13806 [(set (match_operand:V4SF 0 "register_operand" "=x")
13807 (vec_merge:V4SF
13808 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
13809 (parallel [(const_int 0)
13810 (const_int 2)
13811 (const_int 1)
13812 (const_int 3)]))
13813 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
13814 (parallel [(const_int 2)
13815 (const_int 0)
13816 (const_int 3)
13817 (const_int 1)]))
13818 (const_int 5)))]
13819 "TARGET_SSE"
13820 "unpcklps\\t{%2, %0|%0, %2}"
13821 [(set_attr "type" "sse")])
13822
13823
13824 ;; SSE min/max
13825
13826 (define_insn "smaxv4sf3"
13827 [(set (match_operand:V4SF 0 "register_operand" "=x")
13828 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
13829 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13830 "TARGET_SSE"
13831 "maxps\\t{%2, %0|%0, %2}"
13832 [(set_attr "type" "sse")])
13833
13834 (define_insn "vmsmaxv4sf3"
13835 [(set (match_operand:V4SF 0 "register_operand" "=x")
13836 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
13837 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13838 (match_dup 1)
13839 (const_int 1)))]
13840 "TARGET_SSE"
13841 "maxss\\t{%2, %0|%0, %2}"
13842 [(set_attr "type" "sse")])
13843
13844 (define_insn "sminv4sf3"
13845 [(set (match_operand:V4SF 0 "register_operand" "=x")
13846 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
13847 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13848 "TARGET_SSE"
13849 "minps\\t{%2, %0|%0, %2}"
13850 [(set_attr "type" "sse")])
13851
13852 (define_insn "vmsminv4sf3"
13853 [(set (match_operand:V4SF 0 "register_operand" "=x")
13854 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
13855 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13856 (match_dup 1)
13857 (const_int 1)))]
13858 "TARGET_SSE"
13859 "minss\\t{%2, %0|%0, %2}"
13860 [(set_attr "type" "sse")])
13861
13862
13863 ;; SSE <-> integer/MMX conversions
13864
13865 (define_insn "cvtpi2ps"
13866 [(set (match_operand:V4SF 0 "register_operand" "=x")
13867 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
13868 (vec_duplicate:V4SF
13869 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
13870 (const_int 12)))]
13871 "TARGET_SSE"
13872 "cvtpi2ps\\t{%2, %0|%0, %2}"
13873 [(set_attr "type" "sse")])
13874
13875 (define_insn "cvtps2pi"
13876 [(set (match_operand:V2SI 0 "register_operand" "=y")
13877 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
13878 (parallel
13879 [(const_int 0)
13880 (const_int 1)])))]
13881 "TARGET_SSE"
13882 "cvtps2pi\\t{%1, %0|%0, %1}"
13883 [(set_attr "type" "sse")])
13884
13885 (define_insn "cvttps2pi"
13886 [(set (match_operand:V2SI 0 "register_operand" "=y")
13887 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
13888 (parallel
13889 [(const_int 0)
13890 (const_int 1)])))]
13891 "TARGET_SSE"
13892 "cvttps2pi\\t{%1, %0|%0, %1}"
13893 [(set_attr "type" "sse")])
13894
13895 (define_insn "cvtsi2ss"
13896 [(set (match_operand:V4SF 0 "register_operand" "=x")
13897 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
13898 (vec_duplicate:V4SF
13899 (float:SF (match_operand:SI 2 "register_operand" "rm")))
13900 (const_int 15)))]
13901 "TARGET_SSE"
13902 "cvtsi2ss\\t{%2, %0|%0, %2}"
13903 [(set_attr "type" "sse")])
13904
13905 (define_insn "cvtss2si"
13906 [(set (match_operand:SI 0 "register_operand" "=y")
13907 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
13908 (parallel [(const_int 0)])))]
13909 "TARGET_SSE"
13910 "cvtss2si\\t{%1, %0|%0, %1}"
13911 [(set_attr "type" "sse")])
13912
13913 (define_insn "cvttss2si"
13914 [(set (match_operand:SI 0 "register_operand" "=y")
13915 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
13916 (parallel [(const_int 0)])))]
13917 "TARGET_SSE"
13918 "cvttss2si\\t{%1, %0|%0, %1}"
13919 [(set_attr "type" "sse")])
13920
13921
13922 ;; MMX insns
13923
13924 ;; MMX arithmetic
13925
13926 (define_insn "addv8qi3"
13927 [(set (match_operand:V8QI 0 "register_operand" "=y")
13928 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13929 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13930 "TARGET_MMX"
13931 "paddb\\t{%2, %0|%0, %2}"
13932 [(set_attr "type" "mmx")])
13933
13934 (define_insn "addv4hi3"
13935 [(set (match_operand:V4HI 0 "register_operand" "=y")
13936 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13937 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13938 "TARGET_MMX"
13939 "paddw\\t{%2, %0|%0, %2}"
13940 [(set_attr "type" "mmx")])
13941
13942 (define_insn "addv2si3"
13943 [(set (match_operand:V2SI 0 "register_operand" "=y")
13944 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
13945 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
13946 "TARGET_MMX"
13947 "paddd\\t{%2, %0|%0, %2}"
13948 [(set_attr "type" "mmx")])
13949
13950 (define_insn "ssaddv8qi3"
13951 [(set (match_operand:V8QI 0 "register_operand" "=y")
13952 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13953 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13954 "TARGET_MMX"
13955 "paddsb\\t{%2, %0|%0, %2}"
13956 [(set_attr "type" "mmx")])
13957
13958 (define_insn "ssaddv4hi3"
13959 [(set (match_operand:V4HI 0 "register_operand" "=y")
13960 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13961 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13962 "TARGET_MMX"
13963 "paddsw\\t{%2, %0|%0, %2}"
13964 [(set_attr "type" "mmx")])
13965
13966 (define_insn "usaddv8qi3"
13967 [(set (match_operand:V8QI 0 "register_operand" "=y")
13968 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13969 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13970 "TARGET_MMX"
13971 "paddusb\\t{%2, %0|%0, %2}"
13972 [(set_attr "type" "mmx")])
13973
13974 (define_insn "usaddv4hi3"
13975 [(set (match_operand:V4HI 0 "register_operand" "=y")
13976 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13977 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13978 "TARGET_MMX"
13979 "paddusw\\t{%2, %0|%0, %2}"
13980 [(set_attr "type" "mmx")])
13981
13982 (define_insn "subv8qi3"
13983 [(set (match_operand:V8QI 0 "register_operand" "=y")
13984 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13985 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13986 "TARGET_MMX"
13987 "psubb\\t{%2, %0|%0, %2}"
13988 [(set_attr "type" "mmx")])
13989
13990 (define_insn "subv4hi3"
13991 [(set (match_operand:V4HI 0 "register_operand" "=y")
13992 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13993 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13994 "TARGET_MMX"
13995 "psubw\\t{%2, %0|%0, %2}"
13996 [(set_attr "type" "mmx")])
13997
13998 (define_insn "subv2si3"
13999 [(set (match_operand:V2SI 0 "register_operand" "=y")
14000 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
14001 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14002 "TARGET_MMX"
14003 "psubd\\t{%2, %0|%0, %2}"
14004 [(set_attr "type" "mmx")])
14005
14006 (define_insn "sssubv8qi3"
14007 [(set (match_operand:V8QI 0 "register_operand" "=y")
14008 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14009 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14010 "TARGET_MMX"
14011 "psubsb\\t{%2, %0|%0, %2}"
14012 [(set_attr "type" "mmx")])
14013
14014 (define_insn "sssubv4hi3"
14015 [(set (match_operand:V4HI 0 "register_operand" "=y")
14016 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14017 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14018 "TARGET_MMX"
14019 "psubsw\\t{%2, %0|%0, %2}"
14020 [(set_attr "type" "mmx")])
14021
14022 (define_insn "ussubv8qi3"
14023 [(set (match_operand:V8QI 0 "register_operand" "=y")
14024 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14025 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14026 "TARGET_MMX"
14027 "psubusb\\t{%2, %0|%0, %2}"
14028 [(set_attr "type" "mmx")])
14029
14030 (define_insn "ussubv4hi3"
14031 [(set (match_operand:V4HI 0 "register_operand" "=y")
14032 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14033 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14034 "TARGET_MMX"
14035 "psubusw\\t{%2, %0|%0, %2}"
14036 [(set_attr "type" "mmx")])
14037
14038 (define_insn "mulv4hi3"
14039 [(set (match_operand:V4HI 0 "register_operand" "=y")
14040 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
14041 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14042 "TARGET_MMX"
14043 "pmullw\\t{%2, %0|%0, %2}"
14044 [(set_attr "type" "mmx")])
14045
14046 (define_insn "smulv4hi3_highpart"
14047 [(set (match_operand:V4HI 0 "register_operand" "=y")
14048 (truncate:V4HI
14049 (lshiftrt:V4SI
14050 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
14051 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
14052 (const_int 16))))]
14053 "TARGET_MMX"
14054 "pmulhw\\t{%2, %0|%0, %2}"
14055 [(set_attr "type" "mmx")])
14056
14057 (define_insn "umulv4hi3_highpart"
14058 [(set (match_operand:V4HI 0 "register_operand" "=y")
14059 (truncate:V4HI
14060 (lshiftrt:V4SI
14061 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
14062 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
14063 (const_int 16))))]
14064 "TARGET_MMX"
14065 "pmulhuw\\t{%2, %0|%0, %2}"
14066 [(set_attr "type" "mmx")])
14067
14068 (define_insn "mmx_pmaddwd"
14069 [(set (match_operand:V2SI 0 "register_operand" "=y")
14070 (plus:V2SI
14071 (mult:V2SI
14072 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
14073 (parallel [(const_int 0)
14074 (const_int 2)])))
14075 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
14076 (parallel [(const_int 0)
14077 (const_int 2)]))))
14078 (mult:V2SI
14079 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
14080 (parallel [(const_int 1)
14081 (const_int 3)])))
14082 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
14083 (parallel [(const_int 1)
14084 (const_int 3)]))))))]
14085 "TARGET_MMX"
14086 "pmaddwd\\t{%2, %0|%0, %2}"
14087 [(set_attr "type" "mmx")])
14088
14089
14090 ;; MMX logical operations
14091 ;; Note we don't want to declare these as regular iordi3 insns to prevent
14092 ;; normal code that also wants to use the FPU from getting broken.
14093 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
14094 (define_insn "mmx_iordi3"
14095 [(set (match_operand:DI 0 "register_operand" "=y")
14096 (unspec:DI
14097 [(ior:DI (match_operand:DI 1 "register_operand" "0")
14098 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14099 "TARGET_MMX"
14100 "por\\t{%2, %0|%0, %2}"
14101 [(set_attr "type" "mmx")])
14102
14103 (define_insn "mmx_xordi3"
14104 [(set (match_operand:DI 0 "register_operand" "=y")
14105 (unspec:DI
14106 [(xor:DI (match_operand:DI 1 "register_operand" "0")
14107 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14108 "TARGET_MMX"
14109 "pxor\\t{%2, %0|%0, %2}"
14110 [(set_attr "type" "mmx")])
14111
14112 ;; Same as pxor, but don't show input operands so that we don't think
14113 ;; they are live.
14114 (define_insn "mmx_clrdi"
14115 [(set (match_operand:DI 0 "register_operand" "=y")
14116 (unspec:DI [(const_int 0)] 45))]
14117 "TARGET_MMX"
14118 "pxor\\t{%0, %0|%0, %0}"
14119 [(set_attr "type" "mmx")])
14120
14121 (define_insn "mmx_anddi3"
14122 [(set (match_operand:DI 0 "register_operand" "=y")
14123 (unspec:DI
14124 [(and:DI (match_operand:DI 1 "register_operand" "0")
14125 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14126 "TARGET_MMX"
14127 "pand\\t{%2, %0|%0, %2}"
14128 [(set_attr "type" "mmx")])
14129
14130 (define_insn "mmx_nanddi3"
14131 [(set (match_operand:DI 0 "register_operand" "=y")
14132 (unspec:DI
14133 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
14134 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14135 "TARGET_MMX"
14136 "pandn\\t{%2, %0|%0, %2}"
14137 [(set_attr "type" "mmx")])
14138
14139
14140 ;; MMX unsigned averages/sum of absolute differences
14141
14142 (define_insn "mmx_uavgv8qi3"
14143 [(set (match_operand:V8QI 0 "register_operand" "=y")
14144 (ashiftrt:V8QI
14145 (plus:V8QI (plus:V8QI
14146 (match_operand:V8QI 1 "register_operand" "0")
14147 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
14148 (vec_const:V8QI (parallel [(const_int 1)
14149 (const_int 1)
14150 (const_int 1)
14151 (const_int 1)
14152 (const_int 1)
14153 (const_int 1)
14154 (const_int 1)
14155 (const_int 1)])))
14156 (const_int 1)))]
14157 "TARGET_SSE"
14158 "pavgb\\t{%2, %0|%0, %2}"
14159 [(set_attr "type" "sse")])
14160
14161 (define_insn "mmx_uavgv4hi3"
14162 [(set (match_operand:V4HI 0 "register_operand" "=y")
14163 (ashiftrt:V4HI
14164 (plus:V4HI (plus:V4HI
14165 (match_operand:V4HI 1 "register_operand" "0")
14166 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
14167 (vec_const:V4HI (parallel [(const_int 1)
14168 (const_int 1)
14169 (const_int 1)
14170 (const_int 1)])))
14171 (const_int 1)))]
14172 "TARGET_SSE"
14173 "pavgw\\t{%2, %0|%0, %2}"
14174 [(set_attr "type" "sse")])
14175
14176 (define_insn "mmx_psadbw"
14177 [(set (match_operand:V8QI 0 "register_operand" "=y")
14178 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14179 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
14180 "TARGET_SSE"
14181 "psadbw\\t{%2, %0|%0, %2}"
14182 [(set_attr "type" "sse")])
14183
14184
14185 ;; MMX insert/extract/shuffle
14186
14187 (define_insn "mmx_pinsrw"
14188 [(set (match_operand:V4HI 0 "register_operand" "=y")
14189 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
14190 (vec_duplicate:V4HI
14191 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
14192 (match_operand:SI 3 "immediate_operand" "i")))]
14193 "TARGET_SSE"
14194 "pinsrw\\t{%3, %2, %0|%0, %2, %3}"
14195 [(set_attr "type" "sse")])
14196
14197 (define_insn "mmx_pextrw"
14198 [(set (match_operand:SI 0 "register_operand" "=r")
14199 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
14200 (parallel
14201 [(match_operand:SI 2 "immediate_operand" "i")]))))]
14202 "TARGET_SSE"
14203 "pextrw\\t{%2, %1, %0|%0, %1, %2}"
14204 [(set_attr "type" "sse")])
14205
14206 (define_insn "mmx_pshufw"
14207 [(set (match_operand:V4HI 0 "register_operand" "=y")
14208 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
14209 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
14210 (match_operand:SI 3 "immediate_operand" "i")] 41))]
14211 "TARGET_SSE"
14212 "pshufw\\t{%3, %2, %0|%0, %2, %3}"
14213 [(set_attr "type" "sse")])
14214
14215
14216 ;; MMX mask-generating comparisons
14217
14218 (define_insn "eqv8qi3"
14219 [(set (match_operand:V8QI 0 "register_operand" "=y")
14220 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
14221 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14222 "TARGET_MMX"
14223 "pcmpeqb\\t{%2, %0|%0, %2}"
14224 [(set_attr "type" "mmx")])
14225
14226 (define_insn "eqv4hi3"
14227 [(set (match_operand:V4HI 0 "register_operand" "=y")
14228 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
14229 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14230 "TARGET_MMX"
14231 "pcmpeqw\\t{%2, %0|%0, %2}"
14232 [(set_attr "type" "mmx")])
14233
14234 (define_insn "eqv2si3"
14235 [(set (match_operand:V2SI 0 "register_operand" "=y")
14236 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
14237 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14238 "TARGET_MMX"
14239 "pcmpeqd\\t{%2, %0|%0, %2}"
14240 [(set_attr "type" "mmx")])
14241
14242 (define_insn "gtv8qi3"
14243 [(set (match_operand:V8QI 0 "register_operand" "=y")
14244 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
14245 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14246 "TARGET_MMX"
14247 "pcmpgtb\\t{%2, %0|%0, %2}"
14248 [(set_attr "type" "mmx")])
14249
14250 (define_insn "gtv4hi3"
14251 [(set (match_operand:V4HI 0 "register_operand" "=y")
14252 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14253 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14254 "TARGET_MMX"
14255 "pcmpgtw\\t{%2, %0|%0, %2}"
14256 [(set_attr "type" "mmx")])
14257
14258 (define_insn "gtv2si3"
14259 [(set (match_operand:V2SI 0 "register_operand" "=y")
14260 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14261 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14262 "TARGET_MMX"
14263 "pcmpgtd\\t{%2, %0|%0, %2}"
14264 [(set_attr "type" "mmx")])
14265
14266
14267 ;; MMX max/min insns
14268
14269 (define_insn "umaxv8qi3"
14270 [(set (match_operand:V8QI 0 "register_operand" "=y")
14271 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
14272 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14273 "TARGET_SSE"
14274 "pmaxub\\t{%2, %0|%0, %2}"
14275 [(set_attr "type" "sse")])
14276
14277 (define_insn "smaxv4hi3"
14278 [(set (match_operand:V4HI 0 "register_operand" "=y")
14279 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
14280 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14281 "TARGET_SSE"
14282 "pmaxsw\\t{%2, %0|%0, %2}"
14283 [(set_attr "type" "sse")])
14284
14285 (define_insn "uminv8qi3"
14286 [(set (match_operand:V8QI 0 "register_operand" "=y")
14287 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
14288 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14289 "TARGET_SSE"
14290 "pminub\\t{%2, %0|%0, %2}"
14291 [(set_attr "type" "sse")])
14292
14293 (define_insn "sminv4hi3"
14294 [(set (match_operand:V4HI 0 "register_operand" "=y")
14295 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
14296 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14297 "TARGET_SSE"
14298 "pminsw\\t{%2, %0|%0, %2}"
14299 [(set_attr "type" "sse")])
14300
14301
14302 ;; MMX shifts
14303
14304 (define_insn "ashrv4hi3"
14305 [(set (match_operand:V4HI 0 "register_operand" "=y")
14306 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14307 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14308 "TARGET_MMX"
14309 "psraw\\t{%2, %0|%0, %2}"
14310 [(set_attr "type" "mmx")])
14311
14312 (define_insn "ashrv2si3"
14313 [(set (match_operand:V2SI 0 "register_operand" "=y")
14314 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14315 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14316 "TARGET_MMX"
14317 "psrad\\t{%2, %0|%0, %2}"
14318 [(set_attr "type" "mmx")])
14319
14320 (define_insn "lshrv4hi3"
14321 [(set (match_operand:V4HI 0 "register_operand" "=y")
14322 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14323 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14324 "TARGET_MMX"
14325 "psrlw\\t{%2, %0|%0, %2}"
14326 [(set_attr "type" "mmx")])
14327
14328 (define_insn "lshrv2si3"
14329 [(set (match_operand:V2SI 0 "register_operand" "=y")
14330 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14331 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14332 "TARGET_MMX"
14333 "psrld\\t{%2, %0|%0, %2}"
14334 [(set_attr "type" "mmx")])
14335
14336 ;; See logical MMX insns.
14337 (define_insn "mmx_lshrdi3"
14338 [(set (match_operand:DI 0 "register_operand" "=y")
14339 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
14340 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14341 "TARGET_MMX"
14342 "psrlq\\t{%2, %0|%0, %2}"
14343 [(set_attr "type" "mmx")])
14344
14345 (define_insn "ashlv4hi3"
14346 [(set (match_operand:V4HI 0 "register_operand" "=y")
14347 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
14348 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14349 "TARGET_MMX"
14350 "psllw\\t{%2, %0|%0, %2}"
14351 [(set_attr "type" "mmx")])
14352
14353 (define_insn "ashlv2si3"
14354 [(set (match_operand:V2SI 0 "register_operand" "=y")
14355 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
14356 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14357 "TARGET_MMX"
14358 "pslld\\t{%2, %0|%0, %2}"
14359 [(set_attr "type" "mmx")])
14360
14361 ;; See logical MMX insns.
14362 (define_insn "mmx_ashldi3"
14363 [(set (match_operand:DI 0 "register_operand" "=y")
14364 (ashift:DI (match_operand:DI 1 "register_operand" "0")
14365 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14366 "TARGET_MMX"
14367 "psllq\\t{%2, %0|%0, %2}"
14368 [(set_attr "type" "mmx")])
14369
14370
14371 ;; MMX pack/unpack insns.
14372
14373 (define_insn "mmx_packsswb"
14374 [(set (match_operand:V8QI 0 "register_operand" "=y")
14375 (vec_concat:V8QI
14376 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
14377 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
14378 "TARGET_MMX"
14379 "packsswb\\t{%2, %0|%0, %2}"
14380 [(set_attr "type" "mmx")])
14381
14382 (define_insn "mmx_packssdw"
14383 [(set (match_operand:V4HI 0 "register_operand" "=y")
14384 (vec_concat:V4HI
14385 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
14386 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
14387 "TARGET_MMX"
14388 "packssdw\\t{%2, %0|%0, %2}"
14389 [(set_attr "type" "mmx")])
14390
14391 (define_insn "mmx_packuswb"
14392 [(set (match_operand:V8QI 0 "register_operand" "=y")
14393 (vec_concat:V8QI
14394 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
14395 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
14396 "TARGET_MMX"
14397 "packuswb\\t{%2, %0|%0, %2}"
14398 [(set_attr "type" "mmx")])
14399
14400 (define_insn "mmx_punpckhbw"
14401 [(set (match_operand:V8QI 0 "register_operand" "=y")
14402 (vec_merge:V8QI
14403 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
14404 (parallel [(const_int 4)
14405 (const_int 0)
14406 (const_int 5)
14407 (const_int 1)
14408 (const_int 6)
14409 (const_int 2)
14410 (const_int 7)
14411 (const_int 3)]))
14412 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
14413 (parallel [(const_int 0)
14414 (const_int 4)
14415 (const_int 1)
14416 (const_int 5)
14417 (const_int 2)
14418 (const_int 6)
14419 (const_int 3)
14420 (const_int 7)]))
14421 (const_int 85)))]
14422 "TARGET_MMX"
14423 "punpckhbw\\t{%2, %0|%0, %2}"
14424 [(set_attr "type" "mmx")])
14425
14426 (define_insn "mmx_punpckhwd"
14427 [(set (match_operand:V4HI 0 "register_operand" "=y")
14428 (vec_merge:V4HI
14429 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
14430 (parallel [(const_int 0)
14431 (const_int 2)
14432 (const_int 1)
14433 (const_int 3)]))
14434 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
14435 (parallel [(const_int 2)
14436 (const_int 0)
14437 (const_int 3)
14438 (const_int 1)]))
14439 (const_int 5)))]
14440 "TARGET_MMX"
14441 "punpckhwd\\t{%2, %0|%0, %2}"
14442 [(set_attr "type" "mmx")])
14443
14444 (define_insn "mmx_punpckhdq"
14445 [(set (match_operand:V2SI 0 "register_operand" "=y")
14446 (vec_merge:V2SI
14447 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
14448 (parallel [(const_int 0)
14449 (const_int 1)]))
14450 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
14451 (parallel [(const_int 1)
14452 (const_int 0)]))
14453 (const_int 1)))]
14454 "TARGET_MMX"
14455 "punpckhdq\\t{%2, %0|%0, %2}"
14456 [(set_attr "type" "mmx")])
14457
14458 (define_insn "mmx_punpcklbw"
14459 [(set (match_operand:V8QI 0 "register_operand" "=y")
14460 (vec_merge:V8QI
14461 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
14462 (parallel [(const_int 0)
14463 (const_int 4)
14464 (const_int 1)
14465 (const_int 5)
14466 (const_int 2)
14467 (const_int 6)
14468 (const_int 3)
14469 (const_int 7)]))
14470 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
14471 (parallel [(const_int 4)
14472 (const_int 0)
14473 (const_int 5)
14474 (const_int 1)
14475 (const_int 6)
14476 (const_int 2)
14477 (const_int 7)
14478 (const_int 3)]))
14479 (const_int 85)))]
14480 "TARGET_MMX"
14481 "punpcklbw\\t{%2, %0|%0, %2}"
14482 [(set_attr "type" "mmx")])
14483
14484 (define_insn "mmx_punpcklwd"
14485 [(set (match_operand:V4HI 0 "register_operand" "=y")
14486 (vec_merge:V4HI
14487 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
14488 (parallel [(const_int 2)
14489 (const_int 0)
14490 (const_int 3)
14491 (const_int 1)]))
14492 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
14493 (parallel [(const_int 0)
14494 (const_int 2)
14495 (const_int 1)
14496 (const_int 3)]))
14497 (const_int 5)))]
14498 "TARGET_MMX"
14499 "punpcklwd\\t{%2, %0|%0, %2}"
14500 [(set_attr "type" "mmx")])
14501
14502 (define_insn "mmx_punpckldq"
14503 [(set (match_operand:V2SI 0 "register_operand" "=y")
14504 (vec_merge:V2SI
14505 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
14506 (parallel [(const_int 1)
14507 (const_int 0)]))
14508 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
14509 (parallel [(const_int 0)
14510 (const_int 1)]))
14511 (const_int 1)))]
14512 "TARGET_MMX"
14513 "punpckldq\\t{%2, %0|%0, %2}"
14514 [(set_attr "type" "mmx")])
14515
14516
14517 ;; Miscellaneous stuff
14518
14519 (define_insn "emms"
14520 [(unspec_volatile [(const_int 0)] 31)
14521 (clobber (reg:XF 8))
14522 (clobber (reg:XF 9))
14523 (clobber (reg:XF 10))
14524 (clobber (reg:XF 11))
14525 (clobber (reg:XF 12))
14526 (clobber (reg:XF 13))
14527 (clobber (reg:XF 14))
14528 (clobber (reg:XF 15))
14529 (clobber (reg:DI 29))
14530 (clobber (reg:DI 30))
14531 (clobber (reg:DI 31))
14532 (clobber (reg:DI 32))
14533 (clobber (reg:DI 33))
14534 (clobber (reg:DI 34))
14535 (clobber (reg:DI 35))
14536 (clobber (reg:DI 36))]
14537 "TARGET_MMX"
14538 "emms"
14539 [(set_attr "type" "mmx")
14540 (set_attr "memory" "unknown")])
14541
14542 (define_insn "ldmxcsr"
14543 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
14544 "TARGET_MMX"
14545 "ldmxcsr\\t%0"
14546 [(set_attr "type" "mmx")])
14547
14548 (define_insn "stmxcsr"
14549 [(set (match_operand:SI 0 "memory_operand" "=m")
14550 (unspec_volatile:SI [(const_int 0)] 40))]
14551 "TARGET_MMX"
14552 "stmxcsr\\t%0"
14553 [(set_attr "type" "mmx")])
14554
14555 (define_expand "sfence"
14556 [(set (match_dup 0)
14557 (unspec:BLK [(match_dup 0)] 44))]
14558 "TARGET_SSE"
14559 "
14560 {
14561 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14562 MEM_VOLATILE_P (operands[0]) = 1;
14563 }")
14564
14565 (define_insn "*sfence_insn"
14566 [(set (match_operand:BLK 0 "" "")
14567 (unspec:BLK [(match_dup 0)] 44))]
14568 "TARGET_SSE"
14569 "sfence"
14570 [(set_attr "type" "sse")
14571 (set_attr "memory" "unknown")])
14572
14573 (define_insn "prefetch"
14574 [(unspec [(match_operand:SI 0 "address_operand" "p")
14575 (match_operand:SI 1 "immediate_operand" "n")] 35)]
14576 "TARGET_SSE"
14577 "*
14578 {
14579 switch (INTVAL (operands[1]))
14580 {
14581 case 0:
14582 return \"prefetchnta\\t%a0\";
14583 case 1:
14584 return \"prefetcht0\\t%a0\";
14585 case 2:
14586 return \"prefetcht1\\t%a0\";
14587 case 3:
14588 return \"prefetcht2\\t%a0\";
14589 default:
14590 abort ();
14591 }
14592 }"
14593 [(set_attr "type" "sse")])
14594