]> gcc.gnu.org Git - gcc.git/blob - gcc/config/i386/i386.md
i386.md (movsfcc_1): Support integer cmove instruction.
[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"))]
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"))]
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,Ym#f")
3370 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f,Y#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 case 3:
3394 return \"cvtss2sd\\t{%1, %0|%0, %1}\";
3395
3396 default:
3397 abort ();
3398 }
3399 }"
3400 [(set_attr "type" "fmov,fmov,sse,sse")
3401 (set_attr "mode" "SF,XF,DF,DF")])
3402
3403 (define_insn "*extendsfdf2_1_sse_only"
3404 [(set (match_operand:DF 0 "register_operand" "=Y")
3405 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3406 "!TARGET_80387 && TARGET_SSE2
3407 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3408 "cvtss2sd\\t{%1, %0|%0, %1}"
3409 [(set_attr "type" "sse")
3410 (set_attr "mode" "DF")])
3411
3412 (define_expand "extendsfxf2"
3413 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3414 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
3415 "TARGET_80387"
3416 "
3417 {
3418 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3419 operands[1] = force_reg (SFmode, operands[1]);
3420 }")
3421
3422 (define_insn "*extendsfxf2_1"
3423 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3424 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3425 "TARGET_80387
3426 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3427 "*
3428 {
3429 switch (which_alternative)
3430 {
3431 case 0:
3432 if (REG_P (operands[1])
3433 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3434 return \"fstp\\t%y0\";
3435 else if (STACK_TOP_P (operands[0]))
3436 return \"fld%z1\\t%y1\";
3437 else
3438 return \"fst\\t%y0\";
3439
3440 case 1:
3441 /* There is no non-popping store to memory for XFmode. So if
3442 we need one, follow the store with a load. */
3443 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3444 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3445 else
3446 return \"fstp%z0\\t%y0\";
3447
3448 default:
3449 abort ();
3450 }
3451 }"
3452 [(set_attr "type" "fmov")
3453 (set_attr "mode" "SF,XF")])
3454
3455 (define_expand "extendsftf2"
3456 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3457 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3458 "TARGET_80387"
3459 "
3460 {
3461 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3462 operands[1] = force_reg (SFmode, operands[1]);
3463 }")
3464
3465 (define_insn "*extendsftf2_1"
3466 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3467 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3468 "TARGET_80387
3469 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3470 "*
3471 {
3472 switch (which_alternative)
3473 {
3474 case 0:
3475 if (REG_P (operands[1])
3476 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3477 return \"fstp\\t%y0\";
3478 else if (STACK_TOP_P (operands[0]))
3479 return \"fld%z1\\t%y1\";
3480 else
3481 return \"fst\\t%y0\";
3482
3483 case 1:
3484 /* There is no non-popping store to memory for XFmode. So if
3485 we need one, follow the store with a load. */
3486 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3487 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3488 else
3489 return \"fstp%z0\\t%y0\";
3490
3491 default:
3492 abort ();
3493 }
3494 }"
3495 [(set_attr "type" "fmov")
3496 (set_attr "mode" "SF,XF")])
3497
3498 (define_expand "extenddfxf2"
3499 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3500 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
3501 "TARGET_80387"
3502 "
3503 {
3504 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3505 operands[1] = force_reg (DFmode, operands[1]);
3506 }")
3507
3508 (define_insn "*extenddfxf2_1"
3509 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3510 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3511 "TARGET_80387
3512 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3513 "*
3514 {
3515 switch (which_alternative)
3516 {
3517 case 0:
3518 if (REG_P (operands[1])
3519 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3520 return \"fstp\\t%y0\";
3521 else if (STACK_TOP_P (operands[0]))
3522 return \"fld%z1\\t%y1\";
3523 else
3524 return \"fst\\t%y0\";
3525
3526 case 1:
3527 /* There is no non-popping store to memory for XFmode. So if
3528 we need one, follow the store with a load. */
3529 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3530 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3531 else
3532 return \"fstp%z0\\t%y0\";
3533
3534 default:
3535 abort ();
3536 }
3537 }"
3538 [(set_attr "type" "fmov")
3539 (set_attr "mode" "DF,XF")])
3540
3541 (define_expand "extenddftf2"
3542 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3543 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3544 "TARGET_80387"
3545 "
3546 {
3547 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3548 operands[1] = force_reg (DFmode, operands[1]);
3549 }")
3550
3551 (define_insn "*extenddftf2_1"
3552 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3553 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3554 "TARGET_80387
3555 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3556 "*
3557 {
3558 switch (which_alternative)
3559 {
3560 case 0:
3561 if (REG_P (operands[1])
3562 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3563 return \"fstp\\t%y0\";
3564 else if (STACK_TOP_P (operands[0]))
3565 return \"fld%z1\\t%y1\";
3566 else
3567 return \"fst\\t%y0\";
3568
3569 case 1:
3570 /* There is no non-popping store to memory for XFmode. So if
3571 we need one, follow the store with a load. */
3572 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3573 return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
3574 else
3575 return \"fstp%z0\\t%y0\";
3576
3577 default:
3578 abort ();
3579 }
3580 }"
3581 [(set_attr "type" "fmov")
3582 (set_attr "mode" "DF,XF")])
3583
3584 ;; %%% This seems bad bad news.
3585 ;; This cannot output into an f-reg because there is no way to be sure
3586 ;; of truncating in that case. Otherwise this is just like a simple move
3587 ;; insn. So we pretend we can output to a reg in order to get better
3588 ;; register preferencing, but we really use a stack slot.
3589
3590 (define_expand "truncdfsf2"
3591 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3592 (float_truncate:SF
3593 (match_operand:DF 1 "register_operand" "")))
3594 (clobber (match_dup 2))])]
3595 "TARGET_80387 || TARGET_SSE2"
3596 "
3597 if (TARGET_80387)
3598 operands[2] = assign_386_stack_local (SFmode, 0);
3599 else
3600 {
3601 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3602 DONE;
3603 }
3604 ")
3605
3606 (define_insn "*truncdfsf2_1"
3607 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f")
3608 (float_truncate:SF
3609 (match_operand:DF 1 "register_operand" "f,0")))
3610 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3611 "TARGET_80387 && !TARGET_SSE2"
3612 "*
3613 {
3614 switch (which_alternative)
3615 {
3616 case 0:
3617 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3618 return \"fstp%z0\\t%y0\";
3619 else
3620 return \"fst%z0\\t%y0\";
3621 case 1:
3622 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3623 }
3624 abort ();
3625 }"
3626 [(set_attr "type" "fmov,multi")
3627 (set_attr "mode" "SF,SF")])
3628
3629 (define_insn "*truncdfsf2_1_sse"
3630 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,Y")
3631 (float_truncate:SF
3632 (match_operand:DF 1 "nonimmediate_operand" "f,0,mY")))
3633 (clobber (match_operand:SF 2 "memory_operand" "=X,m,X"))]
3634 "TARGET_80387 && TARGET_SSE2"
3635 "*
3636 {
3637 switch (which_alternative)
3638 {
3639 case 0:
3640 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3641 return \"fstp%z0\\t%y0\";
3642 else
3643 return \"fst%z0\\t%y0\";
3644 case 1:
3645 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3646 case 2:
3647 case 3:
3648 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
3649 }
3650 abort ();
3651 }"
3652 [(set_attr "type" "fmov,multi,sse")
3653 (set_attr "mode" "SF,SF,DF")])
3654
3655 (define_insn "*truncdfsf2_2"
3656 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y")
3657 (float_truncate:SF
3658 (match_operand:DF 1 "nonimmediate_operand" "f,mY")))]
3659 "TARGET_80387 && TARGET_SSE2"
3660 "*
3661 {
3662 switch (which_alternative)
3663 {
3664 case 0:
3665 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3666 return \"fstp%z0\\t%y0\";
3667 else
3668 return \"fst%z0\\t%y0\";
3669 case 1:
3670 case 2:
3671 return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
3672 }
3673 }"
3674 [(set_attr "type" "fmov,sse")
3675 (set_attr "mode" "SF,DF")])
3676
3677 (define_insn "truncdfsf2_3"
3678 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3679 (float_truncate:SF
3680 (match_operand:DF 1 "register_operand" "f")))]
3681 "TARGET_80387"
3682 "*
3683 {
3684 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return \"fstp%z0\\t%y0\";
3686 else
3687 return \"fst%z0\\t%y0\";
3688 }"
3689 [(set_attr "type" "fmov")
3690 (set_attr "mode" "SF")])
3691
3692 (define_insn "truncdfsf2_sse_only"
3693 [(set (match_operand:SF 0 "register_operand" "=Y")
3694 (float_truncate:SF
3695 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3696 "!TARGET_80387 && TARGET_SSE2"
3697 "cvtsd2ss\\t{%1, %0|%0, %1}"
3698 [(set_attr "type" "sse")
3699 (set_attr "mode" "DF")])
3700
3701 (define_split
3702 [(set (match_operand:SF 0 "memory_operand" "")
3703 (float_truncate:SF
3704 (match_operand:DF 1 "register_operand" "")))
3705 (clobber (match_operand:SF 2 "memory_operand" ""))]
3706 "TARGET_80387"
3707 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3708 "")
3709
3710 (define_split
3711 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3712 (float_truncate:SF
3713 (match_operand:DF 1 "nonimmediate_operand" "")))
3714 (clobber (match_operand 2 "" ""))]
3715 "TARGET_80387 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
3716 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3717 "")
3718
3719 (define_split
3720 [(set (match_operand:SF 0 "register_operand" "")
3721 (float_truncate:SF
3722 (match_operand:DF 1 "register_operand" "")))
3723 (clobber (match_operand:SF 2 "memory_operand" ""))]
3724 "TARGET_80387 && reload_completed
3725 && FP_REG_P (operands[0])"
3726 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3727 (set (match_dup 0) (match_dup 2))]
3728 "")
3729
3730 (define_expand "truncxfsf2"
3731 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3732 (float_truncate:SF
3733 (match_operand:XF 1 "register_operand" "")))
3734 (clobber (match_dup 2))])]
3735 "TARGET_80387"
3736 "operands[2] = assign_386_stack_local (SFmode, 0);")
3737
3738 (define_insn "*truncxfsf2_1"
3739 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3740 (float_truncate:SF
3741 (match_operand:XF 1 "register_operand" "f,0")))
3742 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3743 "TARGET_80387"
3744 "*
3745 {
3746 switch (which_alternative)
3747 {
3748 case 0:
3749 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3750 return \"fstp%z0\\t%y0\";
3751 else
3752 return \"fst%z0\\t%y0\";
3753 case 1:
3754 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3755 }
3756 abort ();
3757 }"
3758 [(set_attr "type" "fmov,multi")
3759 (set_attr "mode" "SF")])
3760
3761 (define_insn "*truncxfsf2_2"
3762 [(set (match_operand:SF 0 "memory_operand" "=m")
3763 (float_truncate:SF
3764 (match_operand:XF 1 "register_operand" "f")))]
3765 "TARGET_80387"
3766 "*
3767 {
3768 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3769 return \"fstp%z0\\t%y0\";
3770 else
3771 return \"fst%z0\\t%y0\";
3772 }"
3773 [(set_attr "type" "fmov")
3774 (set_attr "mode" "SF")])
3775
3776 (define_split
3777 [(set (match_operand:SF 0 "memory_operand" "")
3778 (float_truncate:SF
3779 (match_operand:XF 1 "register_operand" "")))
3780 (clobber (match_operand:SF 2 "memory_operand" ""))]
3781 "TARGET_80387"
3782 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3783 "")
3784
3785 (define_split
3786 [(set (match_operand:SF 0 "register_operand" "")
3787 (float_truncate:SF
3788 (match_operand:XF 1 "register_operand" "")))
3789 (clobber (match_operand:SF 2 "memory_operand" ""))]
3790 "TARGET_80387 && reload_completed"
3791 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3792 (set (match_dup 0) (match_dup 2))]
3793 "")
3794
3795 (define_expand "trunctfsf2"
3796 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3797 (float_truncate:SF
3798 (match_operand:TF 1 "register_operand" "")))
3799 (clobber (match_dup 2))])]
3800 "TARGET_80387"
3801 "operands[2] = assign_386_stack_local (SFmode, 0);")
3802
3803 (define_insn "*trunctfsf2_1"
3804 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
3805 (float_truncate:SF
3806 (match_operand:TF 1 "register_operand" "f,0")))
3807 (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
3808 "TARGET_80387"
3809 "*
3810 {
3811 switch (which_alternative)
3812 {
3813 case 0:
3814 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3815 return \"fstp%z0\\t%y0\";
3816 else
3817 return \"fst%z0\\t%y0\";
3818 case 1:
3819 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3820 }
3821 abort ();
3822 }"
3823 [(set_attr "type" "fmov,multi")
3824 (set_attr "mode" "SF")])
3825
3826 (define_insn "*truncxfsf2_2"
3827 [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
3828 (float_truncate:SF
3829 (match_operand:TF 1 "register_operand" "f")))]
3830 "TARGET_80387"
3831 "*
3832 {
3833 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return \"fstp%z0\\t%y0\";
3835 else
3836 return \"fst%z0\\t%y0\";
3837 }"
3838 [(set_attr "type" "fmov")
3839 (set_attr "mode" "SF")])
3840
3841 (define_split
3842 [(set (match_operand:SF 0 "memory_operand" "")
3843 (float_truncate:SF
3844 (match_operand:TF 1 "register_operand" "")))
3845 (clobber (match_operand:SF 2 "memory_operand" ""))]
3846 "TARGET_80387"
3847 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3848 "")
3849
3850 (define_split
3851 [(set (match_operand:SF 0 "register_operand" "")
3852 (float_truncate:SF
3853 (match_operand:TF 1 "register_operand" "")))
3854 (clobber (match_operand:SF 2 "memory_operand" ""))]
3855 "TARGET_80387 && reload_completed"
3856 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3857 (set (match_dup 0) (match_dup 2))]
3858 "")
3859
3860
3861 (define_expand "truncxfdf2"
3862 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3863 (float_truncate:DF
3864 (match_operand:XF 1 "register_operand" "")))
3865 (clobber (match_dup 2))])]
3866 "TARGET_80387"
3867 "operands[2] = assign_386_stack_local (DFmode, 0);")
3868
3869 (define_insn "*truncxfdf2_1"
3870 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3871 (float_truncate:DF
3872 (match_operand:XF 1 "register_operand" "f,0")))
3873 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3874 "TARGET_80387"
3875 "*
3876 {
3877 switch (which_alternative)
3878 {
3879 case 0:
3880 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881 return \"fstp%z0\\t%y0\";
3882 else
3883 return \"fst%z0\\t%y0\";
3884 case 1:
3885 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3886 }
3887 abort ();
3888 }"
3889 [(set_attr "type" "fmov,multi")
3890 (set_attr "mode" "DF")])
3891
3892 (define_insn "*truncxfdf2_2"
3893 [(set (match_operand:DF 0 "memory_operand" "=m")
3894 (float_truncate:DF
3895 (match_operand:XF 1 "register_operand" "f")))]
3896 "TARGET_80387"
3897 "*
3898 {
3899 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3900 return \"fstp%z0\\t%y0\";
3901 else
3902 return \"fst%z0\\t%y0\";
3903 }"
3904 [(set_attr "type" "fmov")
3905 (set_attr "mode" "DF")])
3906
3907 (define_split
3908 [(set (match_operand:DF 0 "memory_operand" "")
3909 (float_truncate:DF
3910 (match_operand:XF 1 "register_operand" "")))
3911 (clobber (match_operand:DF 2 "memory_operand" ""))]
3912 "TARGET_80387"
3913 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3914 "")
3915
3916 (define_split
3917 [(set (match_operand:DF 0 "register_operand" "")
3918 (float_truncate:DF
3919 (match_operand:XF 1 "register_operand" "")))
3920 (clobber (match_operand:DF 2 "memory_operand" ""))]
3921 "TARGET_80387 && reload_completed"
3922 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3923 (set (match_dup 0) (match_dup 2))]
3924 "")
3925
3926 (define_expand "trunctfdf2"
3927 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3928 (float_truncate:DF
3929 (match_operand:TF 1 "register_operand" "")))
3930 (clobber (match_dup 2))])]
3931 "TARGET_80387"
3932 "operands[2] = assign_386_stack_local (DFmode, 0);")
3933
3934 (define_insn "*trunctfdf2_1"
3935 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
3936 (float_truncate:DF
3937 (match_operand:TF 1 "register_operand" "f,0")))
3938 (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
3939 "TARGET_80387"
3940 "*
3941 {
3942 switch (which_alternative)
3943 {
3944 case 0:
3945 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946 return \"fstp%z0\\t%y0\";
3947 else
3948 return \"fst%z0\\t%y0\";
3949 case 1:
3950 return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
3951 }
3952 abort ();
3953 }"
3954 [(set_attr "type" "fmov,multi")
3955 (set_attr "mode" "DF")])
3956
3957 (define_insn "*truncxfdf2_2"
3958 [(set (match_operand:DF 0 "memory_operand" "=m")
3959 (float_truncate:DF
3960 (match_operand:TF 1 "register_operand" "f")))]
3961 "TARGET_80387"
3962 "*
3963 {
3964 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3965 return \"fstp%z0\\t%y0\";
3966 else
3967 return \"fst%z0\\t%y0\";
3968 }"
3969 [(set_attr "type" "fmov")
3970 (set_attr "mode" "DF")])
3971
3972 (define_split
3973 [(set (match_operand:DF 0 "memory_operand" "")
3974 (float_truncate:DF
3975 (match_operand:TF 1 "register_operand" "")))
3976 (clobber (match_operand:DF 2 "memory_operand" ""))]
3977 "TARGET_80387"
3978 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3979 "")
3980
3981 (define_split
3982 [(set (match_operand:DF 0 "register_operand" "")
3983 (float_truncate:DF
3984 (match_operand:TF 1 "register_operand" "")))
3985 (clobber (match_operand:DF 2 "memory_operand" ""))]
3986 "TARGET_80387 && reload_completed"
3987 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3988 (set (match_dup 0) (match_dup 2))]
3989 "")
3990
3991 \f
3992 ;; %%% Break up all these bad boys.
3993
3994 ;; Signed conversion to DImode.
3995
3996 (define_expand "fix_truncxfdi2"
3997 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
3998 (fix:DI (match_operand:XF 1 "register_operand" "")))
3999 (clobber (match_dup 2))
4000 (clobber (match_dup 3))
4001 (clobber (match_scratch:SI 4 ""))
4002 (clobber (match_scratch:XF 5 ""))])]
4003 "TARGET_80387"
4004 "operands[2] = assign_386_stack_local (SImode, 0);
4005 operands[3] = assign_386_stack_local (DImode, 1);")
4006
4007 (define_expand "fix_trunctfdi2"
4008 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4009 (fix:DI (match_operand:TF 1 "register_operand" "")))
4010 (clobber (match_dup 2))
4011 (clobber (match_dup 3))
4012 (clobber (match_scratch:SI 4 ""))
4013 (clobber (match_scratch:TF 5 ""))])]
4014 "TARGET_80387"
4015 "operands[2] = assign_386_stack_local (SImode, 0);
4016 operands[3] = assign_386_stack_local (DImode, 1);")
4017
4018 (define_expand "fix_truncdfdi2"
4019 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020 (fix:DI (match_operand:DF 1 "register_operand" "")))
4021 (clobber (match_dup 2))
4022 (clobber (match_dup 3))
4023 (clobber (match_scratch:SI 4 ""))
4024 (clobber (match_scratch:DF 5 ""))])]
4025 "TARGET_80387"
4026 "operands[2] = assign_386_stack_local (SImode, 0);
4027 operands[3] = assign_386_stack_local (DImode, 1);")
4028
4029 (define_expand "fix_truncsfdi2"
4030 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4031 (fix:DI (match_operand:SF 1 "register_operand" "")))
4032 (clobber (match_dup 2))
4033 (clobber (match_dup 3))
4034 (clobber (match_scratch:SI 4 ""))
4035 (clobber (match_scratch:SF 5 ""))])]
4036 "TARGET_80387"
4037 "operands[2] = assign_386_stack_local (SImode, 0);
4038 operands[3] = assign_386_stack_local (DImode, 1);")
4039
4040 (define_insn "*fix_truncdi_1"
4041 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4042 (fix:DI (match_operand 1 "register_operand" "f,f")))
4043 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4044 (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
4045 (clobber (match_scratch:SI 4 "=&r,&r"))
4046 (clobber (match_scratch 5 "=&f,&f"))]
4047 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
4048 "* return output_fix_trunc (insn, operands);"
4049 [(set_attr "type" "multi")])
4050
4051 (define_split
4052 [(set (match_operand:DI 0 "register_operand" "")
4053 (fix:DI (match_operand 1 "register_operand" "")))
4054 (clobber (match_operand:SI 2 "memory_operand" ""))
4055 (clobber (match_operand:DI 3 "memory_operand" ""))
4056 (clobber (match_scratch:SI 4 ""))
4057 (clobber (match_scratch 5 ""))]
4058 "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
4059 [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
4060 (clobber (match_dup 2))
4061 (clobber (match_dup 3))
4062 (clobber (match_dup 4))
4063 (clobber (match_dup 5))])
4064 (set (match_dup 0) (match_dup 3))]
4065 "")
4066
4067 ;; Signed conversion to SImode.
4068
4069 (define_expand "fix_truncxfsi2"
4070 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4071 (fix:SI (match_operand:XF 1 "register_operand" "")))
4072 (clobber (match_dup 2))
4073 (clobber (match_dup 3))
4074 (clobber (match_scratch:SI 4 ""))])]
4075 "TARGET_80387"
4076 "operands[2] = assign_386_stack_local (SImode, 0);
4077 operands[3] = assign_386_stack_local (SImode, 1);")
4078
4079 (define_expand "fix_trunctfsi2"
4080 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4081 (fix:SI (match_operand:TF 1 "register_operand" "")))
4082 (clobber (match_dup 2))
4083 (clobber (match_dup 3))
4084 (clobber (match_scratch:SI 4 ""))])]
4085 "TARGET_80387"
4086 "operands[2] = assign_386_stack_local (SImode, 0);
4087 operands[3] = assign_386_stack_local (SImode, 1);")
4088
4089 (define_expand "fix_truncdfsi2"
4090 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4091 (fix:SI (match_operand:DF 1 "register_operand" "")))
4092 (clobber (match_dup 2))
4093 (clobber (match_dup 3))
4094 (clobber (match_scratch:SI 4 ""))])]
4095 "TARGET_80387 || TARGET_SSE2"
4096 "
4097 {
4098 if (TARGET_SSE2)
4099 {
4100 rtx out = force_reg (SImode, operands[0]);
4101 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4102 if (out != operands[0])
4103 emit_move_insn (operands[0], out);
4104 DONE;
4105 }
4106 else
4107 {
4108 operands[2] = assign_386_stack_local (SImode, 0);
4109 operands[3] = assign_386_stack_local (SImode, 1);
4110 }
4111 }")
4112
4113 (define_expand "fix_truncsfsi2"
4114 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4115 (fix:SI (match_operand:SF 1 "register_operand" "")))
4116 (clobber (match_dup 2))
4117 (clobber (match_dup 3))
4118 (clobber (match_scratch:SI 4 ""))])]
4119 "TARGET_80387 || TARGET_SSE"
4120 "
4121 {
4122 if (TARGET_SSE2)
4123 {
4124 rtx out = force_reg (SImode, operands[0]);
4125 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4126 if (out != operands[0])
4127 emit_move_insn (operands[0], out);
4128 DONE;
4129 }
4130 else
4131 {
4132 operands[2] = assign_386_stack_local (SImode, 0);
4133 operands[3] = assign_386_stack_local (SImode, 1);
4134 }
4135 }")
4136
4137 (define_insn "*fix_truncsi_1"
4138 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4139 (fix:SI (match_operand 1 "register_operand" "f,f")))
4140 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4141 (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
4142 (clobber (match_scratch:SI 4 "=&r,r"))]
4143 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4144 && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4145 "* return output_fix_trunc (insn, operands);"
4146 [(set_attr "type" "multi")])
4147
4148 ;; When SSE available, it is always faster to use it!
4149 (define_insn "fix_truncsfsi_sse"
4150 [(set (match_operand:SI 0 "register_operand" "=r")
4151 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4152 "TARGET_SSE"
4153 "cvttss2si\\t{%1, %0|%0, %1}"
4154 [(set_attr "type" "sse")])
4155
4156 (define_insn "fix_truncdfsi_sse"
4157 [(set (match_operand:SI 0 "register_operand" "=r")
4158 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
4159 "TARGET_SSE2"
4160 "cvttsd2si\\t{%1, %0|%0, %1}"
4161 [(set_attr "type" "sse")])
4162
4163 (define_split
4164 [(set (match_operand:SI 0 "register_operand" "")
4165 (fix:SI (match_operand 1 "register_operand" "")))
4166 (clobber (match_operand:SI 2 "memory_operand" ""))
4167 (clobber (match_operand:SI 3 "memory_operand" ""))
4168 (clobber (match_scratch:SI 4 ""))]
4169 "reload_completed"
4170 [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
4171 (clobber (match_dup 2))
4172 (clobber (match_dup 3))
4173 (clobber (match_dup 4))])
4174 (set (match_dup 0) (match_dup 3))]
4175 "")
4176
4177 ;; Signed conversion to HImode.
4178
4179 (define_expand "fix_truncxfhi2"
4180 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4181 (fix:HI (match_operand:XF 1 "register_operand" "")))
4182 (clobber (match_dup 2))
4183 (clobber (match_dup 3))
4184 (clobber (match_scratch:SI 4 ""))])]
4185 "TARGET_80387"
4186 "operands[2] = assign_386_stack_local (SImode, 0);
4187 operands[3] = assign_386_stack_local (HImode, 1);")
4188
4189 (define_expand "fix_trunctfhi2"
4190 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4191 (fix:HI (match_operand:TF 1 "register_operand" "")))
4192 (clobber (match_dup 2))
4193 (clobber (match_dup 3))
4194 (clobber (match_scratch:SI 4 ""))])]
4195 "TARGET_80387"
4196 "operands[2] = assign_386_stack_local (SImode, 0);
4197 operands[3] = assign_386_stack_local (HImode, 1);")
4198
4199 (define_expand "fix_truncdfhi2"
4200 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4201 (fix:HI (match_operand:DF 1 "register_operand" "")))
4202 (clobber (match_dup 2))
4203 (clobber (match_dup 3))
4204 (clobber (match_scratch:SI 4 ""))])]
4205 "TARGET_80387 && !TARGET_SSE2"
4206 "operands[2] = assign_386_stack_local (SImode, 0);
4207 operands[3] = assign_386_stack_local (HImode, 1);")
4208
4209 (define_expand "fix_truncsfhi2"
4210 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4211 (fix:HI (match_operand:SF 1 "register_operand" "")))
4212 (clobber (match_dup 2))
4213 (clobber (match_dup 3))
4214 (clobber (match_scratch:SI 4 ""))])]
4215 "TARGET_80387 && !TARGET_SSE"
4216 "operands[2] = assign_386_stack_local (SImode, 0);
4217 operands[3] = assign_386_stack_local (HImode, 1);")
4218
4219 (define_insn "*fix_trunchi_1"
4220 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4221 (fix:HI (match_operand 1 "register_operand" "f,f")))
4222 (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
4223 (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
4224 (clobber (match_scratch:SI 4 "=&r,r"))]
4225 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4226 && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4227 "* return output_fix_trunc (insn, operands);"
4228 [(set_attr "type" "multi")])
4229
4230 (define_split
4231 [(set (match_operand:HI 0 "register_operand" "")
4232 (fix:HI (match_operand 1 "register_operand" "")))
4233 (clobber (match_operand:SI 2 "memory_operand" ""))
4234 (clobber (match_operand:HI 3 "memory_operand" ""))
4235 (clobber (match_scratch:SI 4 ""))]
4236 "reload_completed"
4237 [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
4238 (clobber (match_dup 2))
4239 (clobber (match_dup 3))
4240 (clobber (match_dup 4))])
4241 (set (match_dup 0) (match_dup 3))]
4242 "")
4243
4244 ;; %%% Kill these when reload knows how to do it.
4245 (define_split
4246 [(set (match_operand 0 "register_operand" "")
4247 (fix (match_operand 1 "register_operand" "")))]
4248 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1]))
4249 && FP_REG_P (operands[1])"
4250 [(const_int 0)]
4251 "
4252 {
4253 operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]);
4254 operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]);
4255 emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
4256 emit_move_insn (operands[0], operands[2]);
4257 ix86_free_from_memory (GET_MODE (operands[0]));
4258 DONE;
4259 }")
4260
4261 ;; %% Not used yet.
4262 (define_insn "x86_fnstcw_1"
4263 [(set (match_operand:HI 0 "memory_operand" "=m")
4264 (unspec:HI [(reg:HI 18)] 11))]
4265 "TARGET_80387"
4266 "fnstcw\\t%0"
4267 [(set_attr "length" "2")
4268 (set_attr "mode" "HI")
4269 (set_attr "i387" "1")
4270 (set_attr "ppro_uops" "few")])
4271
4272 (define_insn "x86_fldcw_1"
4273 [(set (reg:HI 18)
4274 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
4275 "TARGET_80387"
4276 "fldcw\\t%0"
4277 [(set_attr "length" "2")
4278 (set_attr "mode" "HI")
4279 (set_attr "i387" "1")
4280 (set_attr "athlon_decode" "vector")
4281 (set_attr "ppro_uops" "few")])
4282 \f
4283 ;; Conversion between fixed point and floating point.
4284
4285 ;; Even though we only accept memory inputs, the backend _really_
4286 ;; wants to be able to do this between registers.
4287
4288 (define_insn "floathisf2"
4289 [(set (match_operand:SF 0 "register_operand" "=f,f")
4290 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4291 "TARGET_80387 && !TARGET_SSE"
4292 "@
4293 fild%z1\\t%1
4294 #"
4295 [(set_attr "type" "fmov,multi")
4296 (set_attr "mode" "SF")
4297 (set_attr "fp_int_src" "true")])
4298
4299 (define_expand "floatsisf2"
4300 [(set (match_operand:SF 0 "register_operand" "")
4301 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4302 "TARGET_SSE || TARGET_80387"
4303 "")
4304
4305 (define_insn "*floatsisf2_i387"
4306 [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
4307 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4308 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4309 "@
4310 fild%z1\\t%1
4311 #
4312 cvtsi2ss\\t{%1, %0|%0, %1}"
4313 [(set_attr "type" "fmov,multi,sse")
4314 (set_attr "mode" "SF")
4315 (set_attr "fp_int_src" "true")])
4316
4317 (define_insn "*floatsisf2_sse"
4318 [(set (match_operand:SF 0 "register_operand" "=x")
4319 (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4320 "TARGET_80387 && TARGET_SSE"
4321 "cvtsi2ss\\t{%1, %0|%0, %1}"
4322 [(set_attr "type" "sse")
4323 (set_attr "mode" "SF")
4324 (set_attr "fp_int_src" "true")])
4325
4326 (define_insn "floatdisf2"
4327 [(set (match_operand:SF 0 "register_operand" "=f,f")
4328 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4329 "TARGET_80387"
4330 "@
4331 fild%z1\\t%1
4332 #"
4333 [(set_attr "type" "fmov,multi")
4334 (set_attr "mode" "SF")
4335 (set_attr "fp_int_src" "true")])
4336
4337 (define_insn "floathidf2"
4338 [(set (match_operand:DF 0 "register_operand" "=f,f")
4339 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4340 "TARGET_80387 && !TARGET_SSE2"
4341 "@
4342 fild%z1\\t%1
4343 #"
4344 [(set_attr "type" "fmov,multi")
4345 (set_attr "mode" "DF")
4346 (set_attr "fp_int_src" "true")])
4347
4348 (define_expand "floatsidf2"
4349 [(set (match_operand:DF 0 "register_operand" "")
4350 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4351 ""
4352 "")
4353
4354 (define_insn "*floatsidf2_i387"
4355 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
4356 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
4357 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4358 "@
4359 fild%z1\\t%1
4360 #
4361 cvtsi2sd\\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "fmov,multi,sse")
4363 (set_attr "mode" "DF")
4364 (set_attr "fp_int_src" "true")])
4365
4366 (define_insn "*floatsidf2_sse"
4367 [(set (match_operand:DF 0 "register_operand" "=Y")
4368 (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
4369 "TARGET_SSE2"
4370 "cvtsi2sd\\t{%1, %0|%0, %1}"
4371 [(set_attr "type" "sse")
4372 (set_attr "mode" "DF")
4373 (set_attr "fp_int_src" "true")])
4374
4375 (define_insn "floatdidf2"
4376 [(set (match_operand:DF 0 "register_operand" "=f,f")
4377 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4378 "TARGET_80387 && TARGET_SSE2"
4379 "@
4380 fild%z1\\t%1
4381 #"
4382 [(set_attr "type" "fmov,multi")
4383 (set_attr "mode" "DF")
4384 (set_attr "fp_int_src" "true")])
4385
4386 (define_insn "floathixf2"
4387 [(set (match_operand:XF 0 "register_operand" "=f,f")
4388 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4389 "TARGET_80387"
4390 "@
4391 fild%z1\\t%1
4392 #"
4393 [(set_attr "type" "fmov,multi")
4394 (set_attr "mode" "XF")
4395 (set_attr "fp_int_src" "true")])
4396
4397 (define_insn "floathitf2"
4398 [(set (match_operand:TF 0 "register_operand" "=f,f")
4399 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4400 "TARGET_80387"
4401 "@
4402 fild%z1\\t%1
4403 #"
4404 [(set_attr "type" "fmov,multi")
4405 (set_attr "mode" "XF")
4406 (set_attr "fp_int_src" "true")])
4407
4408 (define_insn "floatsixf2"
4409 [(set (match_operand:XF 0 "register_operand" "=f,f")
4410 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4411 "TARGET_80387"
4412 "@
4413 fild%z1\\t%1
4414 #"
4415 [(set_attr "type" "fmov,multi")
4416 (set_attr "mode" "XF")
4417 (set_attr "fp_int_src" "true")])
4418
4419 (define_insn "floatsitf2"
4420 [(set (match_operand:TF 0 "register_operand" "=f,f")
4421 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4422 "TARGET_80387"
4423 "@
4424 fild%z1\\t%1
4425 #"
4426 [(set_attr "type" "fmov,multi")
4427 (set_attr "mode" "XF")
4428 (set_attr "fp_int_src" "true")])
4429
4430 (define_insn "floatdixf2"
4431 [(set (match_operand:XF 0 "register_operand" "=f,f")
4432 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4433 "TARGET_80387"
4434 "@
4435 fild%z1\\t%1
4436 #"
4437 [(set_attr "type" "fmov,multi")
4438 (set_attr "mode" "XF")
4439 (set_attr "fp_int_src" "true")])
4440
4441 (define_insn "floatditf2"
4442 [(set (match_operand:TF 0 "register_operand" "=f,f")
4443 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4444 "TARGET_80387"
4445 "@
4446 fild%z1\\t%1
4447 #"
4448 [(set_attr "type" "fmov,multi")
4449 (set_attr "mode" "XF")
4450 (set_attr "fp_int_src" "true")])
4451
4452 ;; %%% Kill these when reload knows how to do it.
4453 (define_split
4454 [(set (match_operand 0 "register_operand" "")
4455 (float (match_operand 1 "register_operand" "")))]
4456 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4457 [(const_int 0)]
4458 "
4459 {
4460 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4461 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4462 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4463 ix86_free_from_memory (GET_MODE (operands[1]));
4464 DONE;
4465 }")
4466 \f
4467 ;; Add instructions
4468
4469 ;; %%% define_expand from the very first?
4470 ;; %%% splits for addsidi3
4471 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4472 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4473 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4474
4475 (define_insn "adddi3"
4476 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4477 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4478 (match_operand:DI 2 "general_operand" "roiF,riF")))
4479 (clobber (reg:CC 17))]
4480 ""
4481 "#")
4482
4483 (define_split
4484 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4485 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4486 (match_operand:DI 2 "general_operand" "")))
4487 (clobber (reg:CC 17))]
4488 "reload_completed"
4489 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
4490 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4491 (parallel [(set (match_dup 3)
4492 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4493 (match_dup 4))
4494 (match_dup 5)))
4495 (clobber (reg:CC 17))])]
4496 "split_di (operands+0, 1, operands+0, operands+3);
4497 split_di (operands+1, 1, operands+1, operands+4);
4498 split_di (operands+2, 1, operands+2, operands+5);")
4499
4500 (define_insn "*addsi3_carry"
4501 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4502 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4503 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4504 (match_operand:SI 2 "general_operand" "ri,rm")))
4505 (clobber (reg:CC 17))]
4506 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4507 "adc{l}\\t{%2, %0|%0, %2}"
4508 [(set_attr "type" "alu")
4509 (set_attr "pent_pair" "pu")
4510 (set_attr "mode" "SI")
4511 (set_attr "ppro_uops" "few")])
4512
4513 (define_insn "*addsi3_cc"
4514 [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4515 (match_operand:SI 2 "general_operand" "ri,rm")] 12))
4516 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4517 (plus:SI (match_dup 1) (match_dup 2)))]
4518 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4519 "add{l}\\t{%2, %0|%0, %2}"
4520 [(set_attr "type" "alu")
4521 (set_attr "mode" "SI")])
4522
4523 (define_insn "addqi3_cc"
4524 [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4525 (match_operand:QI 2 "general_operand" "qi,qm")] 12))
4526 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4527 (plus:QI (match_dup 1) (match_dup 2)))]
4528 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4529 "add{b}\\t{%2, %0|%0, %2}"
4530 [(set_attr "type" "alu")
4531 (set_attr "mode" "QI")])
4532
4533 (define_expand "addsi3"
4534 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4535 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4536 (match_operand:SI 2 "general_operand" "")))
4537 (clobber (reg:CC 17))])]
4538 ""
4539 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4540
4541 (define_insn "*lea_0"
4542 [(set (match_operand:SI 0 "register_operand" "=r")
4543 (match_operand:SI 1 "address_operand" "p"))]
4544 ""
4545 "lea{l}\\t{%a1, %0|%0, %a1}"
4546 [(set_attr "type" "lea")
4547 (set_attr "mode" "SI")])
4548
4549 ;; The lea patterns for non-Pmodes needs to be matched by several
4550 ;; insns converted to real lea by splitters.
4551
4552 (define_insn_and_split "*lea_general_1"
4553 [(set (match_operand 0 "register_operand" "=r")
4554 (plus (plus (match_operand 1 "register_operand" "r")
4555 (match_operand 2 "register_operand" "r"))
4556 (match_operand 3 "immediate_operand" "i")))]
4557 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4558 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4559 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4560 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4561 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4562 || GET_MODE (operands[3]) == VOIDmode)"
4563 "#"
4564 "&& reload_completed"
4565 [(const_int 0)]
4566 "
4567 {
4568 rtx pat;
4569 operands[0] = gen_lowpart (SImode, operands[0]);
4570 operands[1] = gen_lowpart (Pmode, operands[1]);
4571 operands[2] = gen_lowpart (Pmode, operands[2]);
4572 operands[3] = gen_lowpart (Pmode, operands[3]);
4573 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4574 operands[3]);
4575 if (Pmode != SImode)
4576 pat = gen_rtx_SUBREG (SImode, pat, 0);
4577 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4578 DONE;
4579 }"
4580 [(set_attr "type" "lea")
4581 (set_attr "mode" "SI")])
4582
4583 (define_insn_and_split "*lea_general_2"
4584 [(set (match_operand 0 "register_operand" "=r")
4585 (plus (mult (match_operand 1 "register_operand" "r")
4586 (match_operand 2 "const248_operand" "i"))
4587 (match_operand 3 "nonmemory_operand" "ri")))]
4588 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4589 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4590 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4591 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4592 || GET_MODE (operands[3]) == VOIDmode)"
4593 "#"
4594 "&& reload_completed"
4595 [(const_int 0)]
4596 "
4597 {
4598 rtx pat;
4599 operands[0] = gen_lowpart (SImode, operands[0]);
4600 operands[1] = gen_lowpart (Pmode, operands[1]);
4601 operands[3] = gen_lowpart (Pmode, operands[3]);
4602 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4603 operands[3]);
4604 if (Pmode != SImode)
4605 pat = gen_rtx_SUBREG (SImode, pat, 0);
4606 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4607 DONE;
4608 }"
4609 [(set_attr "type" "lea")
4610 (set_attr "mode" "SI")])
4611
4612 (define_insn_and_split "*lea_general_3"
4613 [(set (match_operand 0 "register_operand" "=r")
4614 (plus (plus (mult (match_operand 1 "register_operand" "r")
4615 (match_operand 2 "const248_operand" "i"))
4616 (match_operand 3 "register_operand" "r"))
4617 (match_operand 4 "immediate_operand" "i")))]
4618 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
4619 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4620 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4621 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4622 "#"
4623 "&& reload_completed"
4624 [(const_int 0)]
4625 "
4626 {
4627 rtx pat;
4628 operands[0] = gen_lowpart (SImode, operands[0]);
4629 operands[1] = gen_lowpart (Pmode, operands[1]);
4630 operands[3] = gen_lowpart (Pmode, operands[3]);
4631 operands[4] = gen_lowpart (Pmode, operands[4]);
4632 pat = gen_rtx_PLUS (Pmode,
4633 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4634 operands[2]),
4635 operands[3]),
4636 operands[4]);
4637 if (Pmode != SImode)
4638 pat = gen_rtx_SUBREG (SImode, pat, 0);
4639 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4640 DONE;
4641 }"
4642 [(set_attr "type" "lea")
4643 (set_attr "mode" "SI")])
4644
4645 (define_insn "*addsi_1"
4646 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
4647 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
4648 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
4649 (clobber (reg:CC 17))]
4650 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4651 "*
4652 {
4653 switch (get_attr_type (insn))
4654 {
4655 case TYPE_LEA:
4656 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
4657 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
4658
4659 case TYPE_INCDEC:
4660 if (! rtx_equal_p (operands[0], operands[1]))
4661 abort ();
4662 if (operands[2] == const1_rtx)
4663 return \"inc{l}\\t%0\";
4664 else if (operands[2] == constm1_rtx)
4665 return \"dec{l}\\t%0\";
4666 else
4667 abort();
4668
4669 default:
4670 if (! rtx_equal_p (operands[0], operands[1]))
4671 abort ();
4672
4673 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4674 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4675 if (GET_CODE (operands[2]) == CONST_INT
4676 && (INTVAL (operands[2]) == 128
4677 || (INTVAL (operands[2]) < 0
4678 && INTVAL (operands[2]) != -128)))
4679 {
4680 operands[2] = GEN_INT (-INTVAL (operands[2]));
4681 return \"sub{l}\\t{%2, %0|%0, %2}\";
4682 }
4683 return \"add{l}\\t{%2, %0|%0, %2}\";
4684 }
4685 }"
4686 [(set (attr "type")
4687 (cond [(eq_attr "alternative" "2")
4688 (const_string "lea")
4689 ; Current assemblers are broken and do not allow @GOTOFF in
4690 ; ought but a memory context.
4691 (match_operand:SI 2 "pic_symbolic_operand" "")
4692 (const_string "lea")
4693 (match_operand:SI 2 "incdec_operand" "")
4694 (const_string "incdec")
4695 ]
4696 (const_string "alu")))
4697 (set_attr "mode" "SI")])
4698
4699 ;; Convert lea to the lea pattern to avoid flags dependency.
4700 (define_split
4701 [(set (match_operand 0 "register_operand" "")
4702 (plus (match_operand 1 "register_operand" "")
4703 (match_operand 2 "nonmemory_operand" "")))
4704 (clobber (reg:CC 17))]
4705 "reload_completed
4706 && true_regnum (operands[0]) != true_regnum (operands[1])"
4707 [(const_int 0)]
4708 "
4709 {
4710 rtx pat;
4711 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
4712 may confuse gen_lowpart. */
4713 if (GET_MODE (operands[0]) != Pmode)
4714 {
4715 operands[1] = gen_lowpart (Pmode, operands[1]);
4716 operands[2] = gen_lowpart (Pmode, operands[2]);
4717 }
4718 operands[0] = gen_lowpart (SImode, operands[0]);
4719 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
4720 if (Pmode != SImode)
4721 pat = gen_rtx_SUBREG (SImode, pat, 0);
4722 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4723 DONE;
4724 }")
4725
4726 (define_insn "*addsi_2"
4727 [(set (reg 17)
4728 (compare
4729 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
4730 (match_operand:SI 2 "general_operand" "rmni,rni"))
4731 (const_int 0)))
4732 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
4733 (plus:SI (match_dup 1) (match_dup 2)))]
4734 "ix86_match_ccmode (insn, CCGOCmode)
4735 && ix86_binary_operator_ok (PLUS, SImode, operands)
4736 /* Current assemblers are broken and do not allow @GOTOFF in
4737 ought but a memory context. */
4738 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4739 "*
4740 {
4741 switch (get_attr_type (insn))
4742 {
4743 case TYPE_INCDEC:
4744 if (! rtx_equal_p (operands[0], operands[1]))
4745 abort ();
4746 if (operands[2] == const1_rtx)
4747 return \"inc{l}\\t%0\";
4748 else if (operands[2] == constm1_rtx)
4749 return \"dec{l}\\t%0\";
4750 else
4751 abort();
4752
4753 default:
4754 if (! rtx_equal_p (operands[0], operands[1]))
4755 abort ();
4756 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4757 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4758 if (GET_CODE (operands[2]) == CONST_INT
4759 && (INTVAL (operands[2]) == 128
4760 || (INTVAL (operands[2]) < 0
4761 && INTVAL (operands[2]) != -128)))
4762 {
4763 operands[2] = GEN_INT (-INTVAL (operands[2]));
4764 return \"sub{l}\\t{%2, %0|%0, %2}\";
4765 }
4766 return \"add{l}\\t{%2, %0|%0, %2}\";
4767 }
4768 }"
4769 [(set (attr "type")
4770 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4771 (const_string "incdec")
4772 (const_string "alu")))
4773 (set_attr "mode" "SI")])
4774
4775 (define_insn "*addsi_3"
4776 [(set (reg 17)
4777 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
4778 (match_operand:SI 1 "nonimmediate_operand" "%0")))
4779 (clobber (match_scratch:SI 0 "=r"))]
4780 "ix86_match_ccmode (insn, CCZmode)
4781 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4782 /* Current assemblers are broken and do not allow @GOTOFF in
4783 ought but a memory context. */
4784 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4785 "*
4786 {
4787 switch (get_attr_type (insn))
4788 {
4789 case TYPE_INCDEC:
4790 if (! rtx_equal_p (operands[0], operands[1]))
4791 abort ();
4792 if (operands[2] == const1_rtx)
4793 return \"inc{l}\\t%0\";
4794 else if (operands[2] == constm1_rtx)
4795 return \"dec{l}\\t%0\";
4796 else
4797 abort();
4798
4799 default:
4800 if (! rtx_equal_p (operands[0], operands[1]))
4801 abort ();
4802 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4803 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4804 if (GET_CODE (operands[2]) == CONST_INT
4805 && (INTVAL (operands[2]) == 128
4806 || (INTVAL (operands[2]) < 0
4807 && INTVAL (operands[2]) != -128)))
4808 {
4809 operands[2] = GEN_INT (-INTVAL (operands[2]));
4810 return \"sub{l}\\t{%2, %0|%0, %2}\";
4811 }
4812 return \"add{l}\\t{%2, %0|%0, %2}\";
4813 }
4814 }"
4815 [(set (attr "type")
4816 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4817 (const_string "incdec")
4818 (const_string "alu")))
4819 (set_attr "mode" "SI")])
4820
4821 ; For comparisons agains 1, -1 and 128, we may generate better code
4822 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
4823 ; is matched then. We can't accept general immediate, because for
4824 ; case of overflows, the result is messed up.
4825 ; This pattern also don't hold of 0x80000000, since the value overflows
4826 ; when negated.
4827 ; Also carry flag is reversed compared to cmp, so this converison is valid
4828 ; only for comparisons not depending on it.
4829 (define_insn "*addsi_4"
4830 [(set (reg 17)
4831 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
4832 (match_operand:SI 2 "const_int_operand" "n")))
4833 (clobber (match_scratch:SI 0 "=rm"))]
4834 "ix86_match_ccmode (insn, CCGCmode)
4835 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
4836 "*
4837 {
4838 switch (get_attr_type (insn))
4839 {
4840 case TYPE_INCDEC:
4841 if (operands[2] == constm1_rtx)
4842 return \"inc{l}\\t%0\";
4843 else if (operands[2] == const1_rtx)
4844 return \"dec{l}\\t%0\";
4845 else
4846 abort();
4847
4848 default:
4849 if (! rtx_equal_p (operands[0], operands[1]))
4850 abort ();
4851 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4852 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4853 if ((INTVAL (operands[2]) == -128
4854 || (INTVAL (operands[2]) > 0
4855 && INTVAL (operands[2]) != 128)))
4856 return \"sub{l}\\t{%2, %0|%0, %2}\";
4857 operands[2] = GEN_INT (-INTVAL (operands[2]));
4858 return \"add{l}\\t{%2, %0|%0, %2}\";
4859 }
4860 }"
4861 [(set (attr "type")
4862 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4863 (const_string "incdec")
4864 (const_string "alu")))
4865 (set_attr "mode" "SI")])
4866
4867 (define_insn "*addsi_5"
4868 [(set (reg 17)
4869 (compare
4870 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
4871 (match_operand:SI 2 "general_operand" "rmni"))
4872 (const_int 0)))
4873 (clobber (match_scratch:SI 0 "=r"))]
4874 "ix86_match_ccmode (insn, CCGOCmode)
4875 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
4876 /* Current assemblers are broken and do not allow @GOTOFF in
4877 ought but a memory context. */
4878 && ! pic_symbolic_operand (operands[2], VOIDmode)"
4879 "*
4880 {
4881 switch (get_attr_type (insn))
4882 {
4883 case TYPE_INCDEC:
4884 if (! rtx_equal_p (operands[0], operands[1]))
4885 abort ();
4886 if (operands[2] == const1_rtx)
4887 return \"inc{l}\\t%0\";
4888 else if (operands[2] == constm1_rtx)
4889 return \"dec{l}\\t%0\";
4890 else
4891 abort();
4892
4893 default:
4894 if (! rtx_equal_p (operands[0], operands[1]))
4895 abort ();
4896 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4897 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4898 if (GET_CODE (operands[2]) == CONST_INT
4899 && (INTVAL (operands[2]) == 128
4900 || (INTVAL (operands[2]) < 0
4901 && INTVAL (operands[2]) != -128)))
4902 {
4903 operands[2] = GEN_INT (-INTVAL (operands[2]));
4904 return \"sub{l}\\t{%2, %0|%0, %2}\";
4905 }
4906 return \"add{l}\\t{%2, %0|%0, %2}\";
4907 }
4908 }"
4909 [(set (attr "type")
4910 (if_then_else (match_operand:SI 2 "incdec_operand" "")
4911 (const_string "incdec")
4912 (const_string "alu")))
4913 (set_attr "mode" "SI")])
4914
4915 (define_expand "addhi3"
4916 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4917 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
4918 (match_operand:HI 2 "general_operand" "")))
4919 (clobber (reg:CC 17))])]
4920 "TARGET_HIMODE_MATH"
4921 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
4922
4923 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
4924 ;; type optimizations enabled by define-splits. This is not important
4925 ;; for PII, and in fact harmful because of partial register stalls.
4926
4927 (define_insn "*addhi_1_lea"
4928 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
4929 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
4930 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
4931 (clobber (reg:CC 17))]
4932 "!TARGET_PARTIAL_REG_STALL
4933 && ix86_binary_operator_ok (PLUS, HImode, operands)"
4934 "*
4935 {
4936 switch (get_attr_type (insn))
4937 {
4938 case TYPE_LEA:
4939 return \"#\";
4940 case TYPE_INCDEC:
4941 if (operands[2] == const1_rtx)
4942 return \"inc{w}\\t%0\";
4943 else if (operands[2] == constm1_rtx
4944 || (GET_CODE (operands[2]) == CONST_INT
4945 && INTVAL (operands[2]) == 65535))
4946 return \"dec{w}\\t%0\";
4947 abort();
4948
4949 default:
4950 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4951 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4952 if (GET_CODE (operands[2]) == CONST_INT
4953 && (INTVAL (operands[2]) == 128
4954 || (INTVAL (operands[2]) < 0
4955 && INTVAL (operands[2]) != -128)))
4956 {
4957 operands[2] = GEN_INT (-INTVAL (operands[2]));
4958 return \"sub{w}\\t{%2, %0|%0, %2}\";
4959 }
4960 return \"add{w}\\t{%2, %0|%0, %2}\";
4961 }
4962 }"
4963 [(set (attr "type")
4964 (if_then_else (eq_attr "alternative" "2")
4965 (const_string "lea")
4966 (if_then_else (match_operand:HI 2 "incdec_operand" "")
4967 (const_string "incdec")
4968 (const_string "alu"))))
4969 (set_attr "mode" "HI,HI,SI")])
4970
4971 (define_insn "*addhi_1"
4972 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4973 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
4974 (match_operand:HI 2 "general_operand" "ri,rm")))
4975 (clobber (reg:CC 17))]
4976 "TARGET_PARTIAL_REG_STALL
4977 && ix86_binary_operator_ok (PLUS, HImode, operands)"
4978 "*
4979 {
4980 switch (get_attr_type (insn))
4981 {
4982 case TYPE_INCDEC:
4983 if (operands[2] == const1_rtx)
4984 return \"inc{w}\\t%0\";
4985 else if (operands[2] == constm1_rtx
4986 || (GET_CODE (operands[2]) == CONST_INT
4987 && INTVAL (operands[2]) == 65535))
4988 return \"dec{w}\\t%0\";
4989 abort();
4990
4991 default:
4992 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
4993 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
4994 if (GET_CODE (operands[2]) == CONST_INT
4995 && (INTVAL (operands[2]) == 128
4996 || (INTVAL (operands[2]) < 0
4997 && INTVAL (operands[2]) != -128)))
4998 {
4999 operands[2] = GEN_INT (-INTVAL (operands[2]));
5000 return \"sub{w}\\t{%2, %0|%0, %2}\";
5001 }
5002 return \"add{w}\\t{%2, %0|%0, %2}\";
5003 }
5004 }"
5005 [(set (attr "type")
5006 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5007 (const_string "incdec")
5008 (const_string "alu")))
5009 (set_attr "mode" "HI")])
5010
5011 (define_insn "*addhi_2"
5012 [(set (reg 17)
5013 (compare
5014 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5015 (match_operand:HI 2 "general_operand" "rmni,rni"))
5016 (const_int 0)))
5017 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5018 (plus:HI (match_dup 1) (match_dup 2)))]
5019 "ix86_match_ccmode (insn, CCGOCmode)
5020 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5021 "*
5022 {
5023 switch (get_attr_type (insn))
5024 {
5025 case TYPE_INCDEC:
5026 if (operands[2] == const1_rtx)
5027 return \"inc{w}\\t%0\";
5028 else if (operands[2] == constm1_rtx
5029 || (GET_CODE (operands[2]) == CONST_INT
5030 && INTVAL (operands[2]) == 65535))
5031 return \"dec{w}\\t%0\";
5032 abort();
5033
5034 default:
5035 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5036 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5037 if (GET_CODE (operands[2]) == CONST_INT
5038 && (INTVAL (operands[2]) == 128
5039 || (INTVAL (operands[2]) < 0
5040 && INTVAL (operands[2]) != -128)))
5041 {
5042 operands[2] = GEN_INT (-INTVAL (operands[2]));
5043 return \"sub{w}\\t{%2, %0|%0, %2}\";
5044 }
5045 return \"add{w}\\t{%2, %0|%0, %2}\";
5046 }
5047 }"
5048 [(set (attr "type")
5049 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5050 (const_string "incdec")
5051 (const_string "alu")))
5052 (set_attr "mode" "HI")])
5053
5054 (define_insn "*addhi_3"
5055 [(set (reg 17)
5056 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5057 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5058 (clobber (match_scratch:HI 0 "=r"))]
5059 "ix86_match_ccmode (insn, CCZmode)
5060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5061 "*
5062 {
5063 switch (get_attr_type (insn))
5064 {
5065 case TYPE_INCDEC:
5066 if (operands[2] == const1_rtx)
5067 return \"inc{w}\\t%0\";
5068 else if (operands[2] == constm1_rtx
5069 || (GET_CODE (operands[2]) == CONST_INT
5070 && INTVAL (operands[2]) == 65535))
5071 return \"dec{w}\\t%0\";
5072 abort();
5073
5074 default:
5075 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5076 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5077 if (GET_CODE (operands[2]) == CONST_INT
5078 && (INTVAL (operands[2]) == 128
5079 || (INTVAL (operands[2]) < 0
5080 && INTVAL (operands[2]) != -128)))
5081 {
5082 operands[2] = GEN_INT (-INTVAL (operands[2]));
5083 return \"sub{w}\\t{%2, %0|%0, %2}\";
5084 }
5085 return \"add{w}\\t{%2, %0|%0, %2}\";
5086 }
5087 }"
5088 [(set (attr "type")
5089 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5090 (const_string "incdec")
5091 (const_string "alu")))
5092 (set_attr "mode" "HI")])
5093
5094 ; See comments above addsi_3_imm for details.
5095 (define_insn "*addhi_4"
5096 [(set (reg 17)
5097 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5098 (match_operand:HI 2 "const_int_operand" "n")))
5099 (clobber (match_scratch:HI 0 "=rm"))]
5100 "ix86_match_ccmode (insn, CCGCmode)
5101 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5102 "*
5103 {
5104 switch (get_attr_type (insn))
5105 {
5106 case TYPE_INCDEC:
5107 if (operands[2] == constm1_rtx
5108 || (GET_CODE (operands[2]) == CONST_INT
5109 && INTVAL (operands[2]) == 65535))
5110 return \"inc{w}\\t%0\";
5111 else if (operands[2] == const1_rtx)
5112 return \"dec{w}\\t%0\";
5113 else
5114 abort();
5115
5116 default:
5117 if (! rtx_equal_p (operands[0], operands[1]))
5118 abort ();
5119 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5120 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5121 if ((INTVAL (operands[2]) == -128
5122 || (INTVAL (operands[2]) > 0
5123 && INTVAL (operands[2]) != 128)))
5124 return \"sub{w}\\t{%2, %0|%0, %2}\";
5125 operands[2] = GEN_INT (-INTVAL (operands[2]));
5126 return \"add{w}\\t{%2, %0|%0, %2}\";
5127 }
5128 }"
5129 [(set (attr "type")
5130 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5131 (const_string "incdec")
5132 (const_string "alu")))
5133 (set_attr "mode" "SI")])
5134
5135
5136 (define_insn "*addhi_5"
5137 [(set (reg 17)
5138 (compare
5139 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5140 (match_operand:HI 2 "general_operand" "rmni"))
5141 (const_int 0)))
5142 (clobber (match_scratch:HI 0 "=r"))]
5143 "ix86_match_ccmode (insn, CCGOCmode)
5144 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5145 "*
5146 {
5147 switch (get_attr_type (insn))
5148 {
5149 case TYPE_INCDEC:
5150 if (operands[2] == const1_rtx)
5151 return \"inc{w}\\t%0\";
5152 else if (operands[2] == constm1_rtx
5153 || (GET_CODE (operands[2]) == CONST_INT
5154 && INTVAL (operands[2]) == 65535))
5155 return \"dec{w}\\t%0\";
5156 abort();
5157
5158 default:
5159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5161 if (GET_CODE (operands[2]) == CONST_INT
5162 && (INTVAL (operands[2]) == 128
5163 || (INTVAL (operands[2]) < 0
5164 && INTVAL (operands[2]) != -128)))
5165 {
5166 operands[2] = GEN_INT (-INTVAL (operands[2]));
5167 return \"sub{w}\\t{%2, %0|%0, %2}\";
5168 }
5169 return \"add{w}\\t{%2, %0|%0, %2}\";
5170 }
5171 }"
5172 [(set (attr "type")
5173 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5174 (const_string "incdec")
5175 (const_string "alu")))
5176 (set_attr "mode" "HI")])
5177
5178 (define_expand "addqi3"
5179 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5180 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5181 (match_operand:QI 2 "general_operand" "")))
5182 (clobber (reg:CC 17))])]
5183 "TARGET_QIMODE_MATH"
5184 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5185
5186 ;; %%% Potential partial reg stall on alternative 2. What to do?
5187 (define_insn "*addqi_1_lea"
5188 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5189 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5190 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
5191 (clobber (reg:CC 17))]
5192 "!TARGET_PARTIAL_REG_STALL
5193 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5194 "*
5195 {
5196 int widen = (which_alternative == 2);
5197 switch (get_attr_type (insn))
5198 {
5199 case TYPE_LEA:
5200 return \"#\";
5201 case TYPE_INCDEC:
5202 if (operands[2] == const1_rtx)
5203 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5204 else if (operands[2] == constm1_rtx
5205 || (GET_CODE (operands[2]) == CONST_INT
5206 && INTVAL (operands[2]) == 255))
5207 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5208 abort();
5209
5210 default:
5211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5213 if (GET_CODE (operands[2]) == CONST_INT
5214 && (INTVAL (operands[2]) == 128
5215 || (INTVAL (operands[2]) < 0
5216 && INTVAL (operands[2]) != -128)))
5217 {
5218 operands[2] = GEN_INT (-INTVAL (operands[2]));
5219 if (widen)
5220 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5221 else
5222 return \"sub{b}\\t{%2, %0|%0, %2}\";
5223 }
5224 if (widen)
5225 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5226 else
5227 return \"add{b}\\t{%2, %0|%0, %2}\";
5228 }
5229 }"
5230 [(set (attr "type")
5231 (if_then_else (eq_attr "alternative" "3")
5232 (const_string "lea")
5233 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5234 (const_string "incdec")
5235 (const_string "alu"))))
5236 (set_attr "mode" "QI,QI,SI,SI")])
5237
5238 (define_insn "*addqi_1"
5239 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5240 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5241 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5242 (clobber (reg:CC 17))]
5243 "TARGET_PARTIAL_REG_STALL
5244 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5245 "*
5246 {
5247 int widen = (which_alternative == 2);
5248 switch (get_attr_type (insn))
5249 {
5250 case TYPE_INCDEC:
5251 if (operands[2] == const1_rtx)
5252 return widen ? \"inc{l}\\t%k0\" : \"inc{b}\\t%0\";
5253 else if (operands[2] == constm1_rtx
5254 || (GET_CODE (operands[2]) == CONST_INT
5255 && INTVAL (operands[2]) == 255))
5256 return widen ? \"dec{l}\\t%k0\" : \"dec{b}\\t%0\";
5257 abort();
5258
5259 default:
5260 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5261 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5262 if (GET_CODE (operands[2]) == CONST_INT
5263 && (INTVAL (operands[2]) == 128
5264 || (INTVAL (operands[2]) < 0
5265 && INTVAL (operands[2]) != -128)))
5266 {
5267 operands[2] = GEN_INT (-INTVAL (operands[2]));
5268 if (widen)
5269 return \"sub{l}\\t{%2, %k0|%k0, %2}\";
5270 else
5271 return \"sub{b}\\t{%2, %0|%0, %2}\";
5272 }
5273 if (widen)
5274 return \"add{l}\\t{%k2, %k0|%k0, %k2}\";
5275 else
5276 return \"add{b}\\t{%2, %0|%0, %2}\";
5277 }
5278 }"
5279 [(set (attr "type")
5280 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5281 (const_string "incdec")
5282 (const_string "alu")))
5283 (set_attr "mode" "QI,QI,SI")])
5284
5285 (define_insn "*addqi_2"
5286 [(set (reg 17)
5287 (compare
5288 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
5289 (match_operand:QI 2 "general_operand" "qmni,qni"))
5290 (const_int 0)))
5291 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
5292 (plus:QI (match_dup 1) (match_dup 2)))]
5293 "ix86_match_ccmode (insn, CCGOCmode)
5294 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5295 "*
5296 {
5297 switch (get_attr_type (insn))
5298 {
5299 case TYPE_INCDEC:
5300 if (operands[2] == const1_rtx)
5301 return \"inc{b}\\t%0\";
5302 else if (operands[2] == constm1_rtx
5303 || (GET_CODE (operands[2]) == CONST_INT
5304 && INTVAL (operands[2]) == 255))
5305 return \"dec{b}\\t%0\";
5306 abort();
5307
5308 default:
5309 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5310 if (GET_CODE (operands[2]) == CONST_INT
5311 && INTVAL (operands[2]) < 0)
5312 {
5313 operands[2] = GEN_INT (-INTVAL (operands[2]));
5314 return \"sub{b}\\t{%2, %0|%0, %2}\";
5315 }
5316 return \"add{b}\\t{%2, %0|%0, %2}\";
5317 }
5318 }"
5319 [(set (attr "type")
5320 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5321 (const_string "incdec")
5322 (const_string "alu")))
5323 (set_attr "mode" "QI")])
5324
5325 (define_insn "*addqi_3"
5326 [(set (reg 17)
5327 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
5328 (match_operand:QI 1 "nonimmediate_operand" "%0")))
5329 (clobber (match_scratch:QI 0 "=q"))]
5330 "ix86_match_ccmode (insn, CCZmode)
5331 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5332 "*
5333 {
5334 switch (get_attr_type (insn))
5335 {
5336 case TYPE_INCDEC:
5337 if (operands[2] == const1_rtx)
5338 return \"inc{b}\\t%0\";
5339 else if (operands[2] == constm1_rtx
5340 || (GET_CODE (operands[2]) == CONST_INT
5341 && INTVAL (operands[2]) == 255))
5342 return \"dec{b}\\t%0\";
5343 abort();
5344
5345 default:
5346 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5347 if (GET_CODE (operands[2]) == CONST_INT
5348 && INTVAL (operands[2]) < 0)
5349 {
5350 operands[2] = GEN_INT (-INTVAL (operands[2]));
5351 return \"sub{b}\\t{%2, %0|%0, %2}\";
5352 }
5353 return \"add{b}\\t{%2, %0|%0, %2}\";
5354 }
5355 }"
5356 [(set (attr "type")
5357 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5358 (const_string "incdec")
5359 (const_string "alu")))
5360 (set_attr "mode" "QI")])
5361
5362 ; See comments above addsi_3_imm for details.
5363 (define_insn "*addqi_4"
5364 [(set (reg 17)
5365 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
5366 (match_operand:QI 2 "const_int_operand" "n")))
5367 (clobber (match_scratch:QI 0 "=qm"))]
5368 "ix86_match_ccmode (insn, CCGCmode)
5369 && (INTVAL (operands[2]) & 0xff) != 0x80"
5370 "*
5371 {
5372 switch (get_attr_type (insn))
5373 {
5374 case TYPE_INCDEC:
5375 if (operands[2] == constm1_rtx
5376 || (GET_CODE (operands[2]) == CONST_INT
5377 && INTVAL (operands[2]) == 255))
5378 return \"inc{b}\\t%0\";
5379 else if (operands[2] == const1_rtx)
5380 return \"dec{b}\\t%0\";
5381 else
5382 abort();
5383
5384 default:
5385 if (! rtx_equal_p (operands[0], operands[1]))
5386 abort ();
5387 if (INTVAL (operands[2]) < 0)
5388 {
5389 operands[2] = GEN_INT (-INTVAL (operands[2]));
5390 return \"add{b}\\t{%2, %0|%0, %2}\";
5391 }
5392 return \"sub{b}\\t{%2, %0|%0, %2}\";
5393 }
5394 }"
5395 [(set (attr "type")
5396 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5397 (const_string "incdec")
5398 (const_string "alu")))
5399 (set_attr "mode" "QI")])
5400
5401
5402 (define_insn "*addqi_5"
5403 [(set (reg 17)
5404 (compare
5405 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
5406 (match_operand:QI 2 "general_operand" "qmni"))
5407 (const_int 0)))
5408 (clobber (match_scratch:QI 0 "=q"))]
5409 "ix86_match_ccmode (insn, CCGOCmode)
5410 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5411 "*
5412 {
5413 switch (get_attr_type (insn))
5414 {
5415 case TYPE_INCDEC:
5416 if (operands[2] == const1_rtx)
5417 return \"inc{b}\\t%0\";
5418 else if (operands[2] == constm1_rtx
5419 || (GET_CODE (operands[2]) == CONST_INT
5420 && INTVAL (operands[2]) == 255))
5421 return \"dec{b}\\t%0\";
5422 abort();
5423
5424 default:
5425 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
5426 if (GET_CODE (operands[2]) == CONST_INT
5427 && INTVAL (operands[2]) < 0)
5428 {
5429 operands[2] = GEN_INT (-INTVAL (operands[2]));
5430 return \"sub{b}\\t{%2, %0|%0, %2}\";
5431 }
5432 return \"add{b}\\t{%2, %0|%0, %2}\";
5433 }
5434 }"
5435 [(set (attr "type")
5436 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5437 (const_string "incdec")
5438 (const_string "alu")))
5439 (set_attr "mode" "QI")])
5440
5441
5442 (define_insn "addqi_ext_1"
5443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5444 (const_int 8)
5445 (const_int 8))
5446 (plus:SI
5447 (zero_extract:SI
5448 (match_operand 1 "ext_register_operand" "0")
5449 (const_int 8)
5450 (const_int 8))
5451 (match_operand:QI 2 "general_operand" "qmn")))
5452 (clobber (reg:CC 17))]
5453 ""
5454 "*
5455 {
5456 switch (get_attr_type (insn))
5457 {
5458 case TYPE_INCDEC:
5459 if (operands[2] == const1_rtx)
5460 return \"inc{b}\\t%h0\";
5461 else if (operands[2] == constm1_rtx
5462 || (GET_CODE (operands[2]) == CONST_INT
5463 && INTVAL (operands[2]) == 255))
5464 return \"dec{b}\\t%h0\";
5465 abort();
5466
5467 default:
5468 return \"add{b}\\t{%2, %h0|%h0, %2}\";
5469 }
5470 }"
5471 [(set (attr "type")
5472 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5473 (const_string "incdec")
5474 (const_string "alu")))
5475 (set_attr "mode" "QI")])
5476
5477 (define_insn "*addqi_ext_2"
5478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
5479 (const_int 8)
5480 (const_int 8))
5481 (plus:SI
5482 (zero_extract:SI
5483 (match_operand 1 "ext_register_operand" "%0")
5484 (const_int 8)
5485 (const_int 8))
5486 (zero_extract:SI
5487 (match_operand 2 "ext_register_operand" "q")
5488 (const_int 8)
5489 (const_int 8))))
5490 (clobber (reg:CC 17))]
5491 ""
5492 "add{b}\\t{%h2, %h0|%h0, %h2}"
5493 [(set_attr "type" "alu")
5494 (set_attr "mode" "QI")])
5495
5496 ;; The patterns that match these are at the end of this file.
5497
5498 (define_expand "addxf3"
5499 [(set (match_operand:XF 0 "register_operand" "")
5500 (plus:XF (match_operand:XF 1 "register_operand" "")
5501 (match_operand:XF 2 "register_operand" "")))]
5502 "TARGET_80387"
5503 "")
5504
5505 (define_expand "addtf3"
5506 [(set (match_operand:TF 0 "register_operand" "")
5507 (plus:TF (match_operand:TF 1 "register_operand" "")
5508 (match_operand:TF 2 "register_operand" "")))]
5509 "TARGET_80387"
5510 "")
5511
5512 (define_expand "adddf3"
5513 [(set (match_operand:DF 0 "register_operand" "")
5514 (plus:DF (match_operand:DF 1 "register_operand" "")
5515 (match_operand:DF 2 "nonimmediate_operand" "")))]
5516 "TARGET_80387 || TARGET_SSE2"
5517 "")
5518
5519 (define_expand "addsf3"
5520 [(set (match_operand:SF 0 "register_operand" "")
5521 (plus:SF (match_operand:SF 1 "register_operand" "")
5522 (match_operand:SF 2 "nonimmediate_operand" "")))]
5523 "TARGET_80387 || TARGET_SSE"
5524 "")
5525 \f
5526 ;; Subtract instructions
5527
5528 ;; %%% define_expand from the very first?
5529 ;; %%% splits for subsidi3
5530
5531 (define_insn "subdi3"
5532 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5533 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
5534 (match_operand:DI 2 "general_operand" "roiF,riF")))
5535 (clobber (reg:CC 17))]
5536 ""
5537 "#")
5538
5539 (define_split
5540 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5541 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5542 (match_operand:DI 2 "general_operand" "")))
5543 (clobber (reg:CC 17))]
5544 "reload_completed"
5545 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
5546 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
5547 (parallel [(set (match_dup 3)
5548 (minus:SI (match_dup 4)
5549 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5550 (match_dup 5))))
5551 (clobber (reg:CC 17))])]
5552 "split_di (operands+0, 1, operands+0, operands+3);
5553 split_di (operands+1, 1, operands+1, operands+4);
5554 split_di (operands+2, 1, operands+2, operands+5);")
5555
5556 (define_insn "subsi3_carry"
5557 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5558 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5559 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5560 (match_operand:SI 2 "general_operand" "ri,rm"))))
5561 (clobber (reg:CC 17))]
5562 "ix86_binary_operator_ok (MINUS, SImode, operands)"
5563 "sbb{l}\\t{%2, %0|%0, %2}"
5564 [(set_attr "type" "alu")
5565 (set_attr "pent_pair" "pu")
5566 (set_attr "ppro_uops" "few")
5567 (set_attr "mode" "SI")])
5568
5569 (define_expand "subsi3"
5570 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5571 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5572 (match_operand:SI 2 "general_operand" "")))
5573 (clobber (reg:CC 17))])]
5574 ""
5575 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
5576
5577 (define_insn "*subsi_1"
5578 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5579 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5580 (match_operand:SI 2 "general_operand" "ri,rm")))
5581 (clobber (reg:CC 17))]
5582 "ix86_binary_operator_ok (MINUS, SImode, operands)"
5583 "sub{l}\\t{%2, %0|%0, %2}"
5584 [(set_attr "type" "alu")
5585 (set_attr "mode" "SI")])
5586
5587 (define_insn "*subsi_2"
5588 [(set (reg 17)
5589 (compare
5590 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5591 (match_operand:SI 2 "general_operand" "ri,rm"))
5592 (const_int 0)))
5593 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5594 (minus:SI (match_dup 1) (match_dup 2)))]
5595 "ix86_match_ccmode (insn, CCGOCmode)
5596 && ix86_binary_operator_ok (MINUS, SImode, operands)"
5597 "sub{l}\\t{%2, %0|%0, %2}"
5598 [(set_attr "type" "alu")
5599 (set_attr "mode" "SI")])
5600
5601 (define_insn "*subsi_3"
5602 [(set (reg 17)
5603 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
5604 (match_operand:SI 2 "general_operand" "ri,rm")))
5605 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5606 (minus:SI (match_dup 1) (match_dup 2)))]
5607 "ix86_match_ccmode (insn, CCmode)
5608 && ix86_binary_operator_ok (MINUS, SImode, operands)"
5609 "sub{l}\\t{%2, %0|%0, %2}"
5610 [(set_attr "type" "alu")
5611 (set_attr "mode" "SI")])
5612
5613 (define_expand "subhi3"
5614 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5615 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5616 (match_operand:HI 2 "general_operand" "")))
5617 (clobber (reg:CC 17))])]
5618 "TARGET_HIMODE_MATH"
5619 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
5620
5621 (define_insn "*subhi_1"
5622 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5623 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5624 (match_operand:HI 2 "general_operand" "ri,rm")))
5625 (clobber (reg:CC 17))]
5626 "ix86_binary_operator_ok (MINUS, HImode, operands)"
5627 "sub{w}\\t{%2, %0|%0, %2}"
5628 [(set_attr "type" "alu")
5629 (set_attr "mode" "HI")])
5630
5631 (define_insn "*subhi_2"
5632 [(set (reg 17)
5633 (compare
5634 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
5635 (match_operand:HI 2 "general_operand" "ri,rm"))
5636 (const_int 0)))
5637 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5638 (minus:HI (match_dup 1) (match_dup 2)))]
5639 "ix86_match_ccmode (insn, CCGOCmode)
5640 && ix86_binary_operator_ok (MINUS, HImode, operands)"
5641 "sub{w}\\t{%2, %0|%0, %2}"
5642 [(set_attr "type" "alu")
5643 (set_attr "mode" "HI")])
5644
5645 (define_insn "*subhi_3"
5646 [(set (reg 17)
5647 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
5648 (match_operand:HI 2 "general_operand" "ri,rm")))
5649 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5650 (minus:HI (match_dup 1) (match_dup 2)))]
5651 "ix86_match_ccmode (insn, CCmode)
5652 && ix86_binary_operator_ok (MINUS, HImode, operands)"
5653 "sub{w}\\t{%2, %0|%0, %2}"
5654 [(set_attr "type" "alu")
5655 (set_attr "mode" "HI")])
5656
5657 (define_expand "subqi3"
5658 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5659 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5660 (match_operand:QI 2 "general_operand" "")))
5661 (clobber (reg:CC 17))])]
5662 "TARGET_QIMODE_MATH"
5663 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
5664
5665 (define_insn "*subqi_1"
5666 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5667 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5668 (match_operand:QI 2 "general_operand" "qn,qmn")))
5669 (clobber (reg:CC 17))]
5670 "ix86_binary_operator_ok (MINUS, QImode, operands)"
5671 "sub{b}\\t{%2, %0|%0, %2}"
5672 [(set_attr "type" "alu")
5673 (set_attr "mode" "QI")])
5674
5675 (define_insn "*subqi_2"
5676 [(set (reg 17)
5677 (compare
5678 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
5679 (match_operand:QI 2 "general_operand" "qi,qm"))
5680 (const_int 0)))
5681 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5682 (minus:HI (match_dup 1) (match_dup 2)))]
5683 "ix86_match_ccmode (insn, CCGOCmode)
5684 && ix86_binary_operator_ok (MINUS, QImode, operands)"
5685 "sub{b}\\t{%2, %0|%0, %2}"
5686 [(set_attr "type" "alu")
5687 (set_attr "mode" "QI")])
5688
5689 (define_insn "*subqi_3"
5690 [(set (reg 17)
5691 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
5692 (match_operand:QI 2 "general_operand" "qi,qm")))
5693 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
5694 (minus:HI (match_dup 1) (match_dup 2)))]
5695 "ix86_match_ccmode (insn, CCmode)
5696 && ix86_binary_operator_ok (MINUS, QImode, operands)"
5697 "sub{b}\\t{%2, %0|%0, %2}"
5698 [(set_attr "type" "alu")
5699 (set_attr "mode" "QI")])
5700
5701 ;; The patterns that match these are at the end of this file.
5702
5703 (define_expand "subxf3"
5704 [(set (match_operand:XF 0 "register_operand" "")
5705 (minus:XF (match_operand:XF 1 "register_operand" "")
5706 (match_operand:XF 2 "register_operand" "")))]
5707 "TARGET_80387"
5708 "")
5709
5710 (define_expand "subtf3"
5711 [(set (match_operand:TF 0 "register_operand" "")
5712 (minus:TF (match_operand:TF 1 "register_operand" "")
5713 (match_operand:TF 2 "register_operand" "")))]
5714 "TARGET_80387"
5715 "")
5716
5717 (define_expand "subdf3"
5718 [(set (match_operand:DF 0 "register_operand" "")
5719 (minus:DF (match_operand:DF 1 "register_operand" "")
5720 (match_operand:DF 2 "nonimmediate_operand" "")))]
5721 "TARGET_80387 || TARGET_SSE2"
5722 "")
5723
5724 (define_expand "subsf3"
5725 [(set (match_operand:SF 0 "register_operand" "")
5726 (minus:SF (match_operand:SF 1 "register_operand" "")
5727 (match_operand:SF 2 "nonimmediate_operand" "")))]
5728 "TARGET_80387 || TARGET_SSE"
5729 "")
5730 \f
5731 ;; Multiply instructions
5732
5733 (define_expand "mulsi3"
5734 [(parallel [(set (match_operand:SI 0 "register_operand" "")
5735 (mult:SI (match_operand:SI 1 "register_operand" "")
5736 (match_operand:SI 2 "general_operand" "")))
5737 (clobber (reg:CC 17))])]
5738 ""
5739 "")
5740
5741 (define_insn "*mulsi3_1"
5742 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5743 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
5744 (match_operand:SI 2 "general_operand" "K,i,mr")))
5745 (clobber (reg:CC 17))]
5746 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
5747 ; For the {r,0,i} alternative (i.e., register <- register * immediate),
5748 ; there are two ways of writing the exact same machine instruction
5749 ; in assembly language. One, for example, is:
5750 ;
5751 ; imul $12, %eax
5752 ;
5753 ; while the other is:
5754 ;
5755 ; imul $12, %eax, %eax
5756 ;
5757 ; The first is simply short-hand for the latter. But, some assemblers,
5758 ; like the SCO OSR5 COFF assembler, don't handle the first form.
5759 "@
5760 imul{l}\\t{%2, %1, %0|%0, %1, %2}
5761 imul{l}\\t{%2, %1, %0|%0, %1, %2}
5762 imul{l}\\t{%2, %0|%0, %2}"
5763 [(set_attr "type" "imul")
5764 (set_attr "prefix_0f" "0,0,1")
5765 (set_attr "mode" "SI")])
5766
5767 (define_expand "mulhi3"
5768 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5769 (mult:HI (match_operand:HI 1 "register_operand" "")
5770 (match_operand:HI 2 "general_operand" "")))
5771 (clobber (reg:CC 17))])]
5772 "TARGET_HIMODE_MATH"
5773 "")
5774
5775 (define_insn "*mulhi3_1"
5776 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
5777 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
5778 (match_operand:HI 2 "general_operand" "K,i,mr")))
5779 (clobber (reg:CC 17))]
5780 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
5781 ; %%% There was a note about "Assembler has weird restrictions",
5782 ; concerning alternative 1 when op1 == op0. True?
5783 "@
5784 imul{w}\\t{%2, %1, %0|%0, %1, %2}
5785 imul{w}\\t{%2, %1, %0|%0, %1, %2}
5786 imul{w}\\t{%2, %0|%0, %2}"
5787 [(set_attr "type" "imul")
5788 (set_attr "prefix_0f" "0,0,1")
5789 (set_attr "mode" "HI")])
5790
5791 (define_insn "mulqi3"
5792 [(set (match_operand:QI 0 "register_operand" "=a")
5793 (mult:QI (match_operand:QI 1 "register_operand" "%0")
5794 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5795 (clobber (reg:CC 17))]
5796 "TARGET_QIMODE_MATH"
5797 "mul{b}\\t%2"
5798 [(set_attr "type" "imul")
5799 (set_attr "length_immediate" "0")
5800 (set_attr "mode" "QI")])
5801
5802 (define_insn "umulqihi3"
5803 [(set (match_operand:HI 0 "register_operand" "=a")
5804 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
5805 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5806 (clobber (reg:CC 17))]
5807 "TARGET_QIMODE_MATH"
5808 "mul{b}\\t%2"
5809 [(set_attr "type" "imul")
5810 (set_attr "length_immediate" "0")
5811 (set_attr "mode" "QI")])
5812
5813 (define_insn "mulqihi3"
5814 [(set (match_operand:HI 0 "register_operand" "=a")
5815 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
5816 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
5817 (clobber (reg:CC 17))]
5818 "TARGET_QIMODE_MATH"
5819 "imul{b}\\t%2"
5820 [(set_attr "type" "imul")
5821 (set_attr "length_immediate" "0")
5822 (set_attr "mode" "QI")])
5823
5824 (define_insn "umulsidi3"
5825 [(set (match_operand:DI 0 "register_operand" "=A")
5826 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
5827 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5828 (clobber (reg:CC 17))]
5829 ""
5830 "mul{l}\\t%2"
5831 [(set_attr "type" "imul")
5832 (set_attr "ppro_uops" "few")
5833 (set_attr "length_immediate" "0")
5834 (set_attr "mode" "SI")])
5835
5836 (define_insn "mulsidi3"
5837 [(set (match_operand:DI 0 "register_operand" "=A")
5838 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
5839 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
5840 (clobber (reg:CC 17))]
5841 ""
5842 "imul{l}\\t%2"
5843 [(set_attr "type" "imul")
5844 (set_attr "length_immediate" "0")
5845 (set_attr "mode" "SI")])
5846
5847 (define_insn "umulsi3_highpart"
5848 [(set (match_operand:SI 0 "register_operand" "=d")
5849 (truncate:SI
5850 (lshiftrt:DI
5851 (mult:DI (zero_extend:DI
5852 (match_operand:SI 1 "register_operand" "%a"))
5853 (zero_extend:DI
5854 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5855 (const_int 32))))
5856 (clobber (match_scratch:SI 3 "=a"))
5857 (clobber (reg:CC 17))]
5858 ""
5859 "mul{l}\\t%2"
5860 [(set_attr "type" "imul")
5861 (set_attr "ppro_uops" "few")
5862 (set_attr "length_immediate" "0")
5863 (set_attr "mode" "SI")])
5864
5865 (define_insn "smulsi3_highpart"
5866 [(set (match_operand:SI 0 "register_operand" "=d")
5867 (truncate:SI
5868 (lshiftrt:DI
5869 (mult:DI (sign_extend:DI
5870 (match_operand:SI 1 "register_operand" "%a"))
5871 (sign_extend:DI
5872 (match_operand:SI 2 "nonimmediate_operand" "rm")))
5873 (const_int 32))))
5874 (clobber (match_scratch:SI 3 "=a"))
5875 (clobber (reg:CC 17))]
5876 ""
5877 "imul{l}\\t%2"
5878 [(set_attr "type" "imul")
5879 (set_attr "ppro_uops" "few")
5880 (set_attr "mode" "SI")])
5881
5882 ;; The patterns that match these are at the end of this file.
5883
5884 (define_expand "mulxf3"
5885 [(set (match_operand:XF 0 "register_operand" "")
5886 (mult:XF (match_operand:XF 1 "register_operand" "")
5887 (match_operand:XF 2 "register_operand" "")))]
5888 "TARGET_80387"
5889 "")
5890
5891 (define_expand "multf3"
5892 [(set (match_operand:TF 0 "register_operand" "")
5893 (mult:TF (match_operand:TF 1 "register_operand" "")
5894 (match_operand:TF 2 "register_operand" "")))]
5895 "TARGET_80387"
5896 "")
5897
5898 (define_expand "muldf3"
5899 [(set (match_operand:DF 0 "register_operand" "")
5900 (mult:DF (match_operand:DF 1 "register_operand" "")
5901 (match_operand:DF 2 "nonimmediate_operand" "")))]
5902 "TARGET_80387 || TARGET_SSE2"
5903 "")
5904
5905 (define_expand "mulsf3"
5906 [(set (match_operand:SF 0 "register_operand" "")
5907 (mult:SF (match_operand:SF 1 "register_operand" "")
5908 (match_operand:SF 2 "nonimmediate_operand" "")))]
5909 "TARGET_80387 || TARGET_SSE"
5910 "")
5911 \f
5912 ;; Divide instructions
5913
5914 (define_insn "divqi3"
5915 [(set (match_operand:QI 0 "register_operand" "=a")
5916 (div:QI (match_operand:HI 1 "register_operand" "0")
5917 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5918 (clobber (reg:CC 17))]
5919 "TARGET_QIMODE_MATH"
5920 "idiv{b}\\t%2"
5921 [(set_attr "type" "idiv")
5922 (set_attr "mode" "QI")
5923 (set_attr "ppro_uops" "few")])
5924
5925 (define_insn "udivqi3"
5926 [(set (match_operand:QI 0 "register_operand" "=a")
5927 (udiv:QI (match_operand:HI 1 "register_operand" "0")
5928 (match_operand:QI 2 "nonimmediate_operand" "qm")))
5929 (clobber (reg:CC 17))]
5930 "TARGET_QIMODE_MATH"
5931 "div{b}\\t%2"
5932 [(set_attr "type" "idiv")
5933 (set_attr "mode" "QI")
5934 (set_attr "ppro_uops" "few")])
5935
5936 ;; The patterns that match these are at the end of this file.
5937
5938 (define_expand "divxf3"
5939 [(set (match_operand:XF 0 "register_operand" "")
5940 (div:XF (match_operand:XF 1 "register_operand" "")
5941 (match_operand:XF 2 "register_operand" "")))]
5942 "TARGET_80387"
5943 "")
5944
5945 (define_expand "divtf3"
5946 [(set (match_operand:TF 0 "register_operand" "")
5947 (div:TF (match_operand:TF 1 "register_operand" "")
5948 (match_operand:TF 2 "register_operand" "")))]
5949 "TARGET_80387"
5950 "")
5951
5952 (define_expand "divdf3"
5953 [(set (match_operand:DF 0 "register_operand" "")
5954 (div:DF (match_operand:DF 1 "register_operand" "")
5955 (match_operand:DF 2 "nonimmediate_operand" "")))]
5956 "TARGET_80387 || TARGET_SSE2"
5957 "")
5958
5959 (define_expand "divsf3"
5960 [(set (match_operand:SF 0 "register_operand" "")
5961 (div:SF (match_operand:SF 1 "register_operand" "")
5962 (match_operand:SF 2 "nonimmediate_operand" "")))]
5963 "TARGET_80387 || TARGET_SSE"
5964 "")
5965 \f
5966 ;; Remainder instructions.
5967 (define_expand "divmodsi4"
5968 [(parallel [(set (match_operand:SI 0 "register_operand" "")
5969 (div:SI (match_operand:SI 1 "register_operand" "")
5970 (match_operand:SI 2 "nonimmediate_operand" "")))
5971 (set (match_operand:SI 3 "register_operand" "")
5972 (mod:SI (match_dup 1) (match_dup 2)))
5973 (clobber (reg:CC 17))])]
5974 ""
5975 "")
5976
5977 ;; Allow to come the parameter in eax or edx to avoid extra moves.
5978 ;; Penalize eax case sligthly because it results in worse scheduling
5979 ;; of code.
5980 (define_insn "*divmodsi4_nocltd"
5981 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
5982 (div:SI (match_operand:SI 2 "register_operand" "1,0")
5983 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
5984 (set (match_operand:SI 1 "register_operand" "=&d,&d")
5985 (mod:SI (match_dup 2) (match_dup 3)))
5986 (clobber (reg:CC 17))]
5987 "!optimize_size && !TARGET_USE_CLTD"
5988 "#"
5989 [(set_attr "type" "multi")])
5990
5991 (define_insn "*divmodsi4_cltd"
5992 [(set (match_operand:SI 0 "register_operand" "=a")
5993 (div:SI (match_operand:SI 2 "register_operand" "a")
5994 (match_operand:SI 3 "nonimmediate_operand" "rm")))
5995 (set (match_operand:SI 1 "register_operand" "=&d")
5996 (mod:SI (match_dup 2) (match_dup 3)))
5997 (clobber (reg:CC 17))]
5998 "optimize_size || TARGET_USE_CLTD"
5999 "#"
6000 [(set_attr "type" "multi")])
6001
6002 (define_insn "*divmodsi_noext"
6003 [(set (match_operand:SI 0 "register_operand" "=a")
6004 (div:SI (match_operand:SI 1 "register_operand" "0")
6005 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6006 (set (match_operand:SI 3 "register_operand" "=d")
6007 (mod:SI (match_dup 1) (match_dup 2)))
6008 (use (match_operand:SI 4 "register_operand" "3"))
6009 (clobber (reg:CC 17))]
6010 ""
6011 "idiv{l}\\t%2"
6012 [(set_attr "type" "idiv")
6013 (set_attr "mode" "SI")
6014 (set_attr "ppro_uops" "few")])
6015
6016 (define_split
6017 [(set (match_operand:SI 0 "register_operand" "")
6018 (div:SI (match_operand:SI 1 "register_operand" "")
6019 (match_operand:SI 2 "nonimmediate_operand" "")))
6020 (set (match_operand:SI 3 "register_operand" "")
6021 (mod:SI (match_dup 1) (match_dup 2)))
6022 (clobber (reg:CC 17))]
6023 "reload_completed"
6024 [(parallel [(set (match_dup 3)
6025 (ashiftrt:SI (match_dup 4) (const_int 31)))
6026 (clobber (reg:CC 17))])
6027 (parallel [(set (match_dup 0)
6028 (div:SI (reg:SI 0) (match_dup 2)))
6029 (set (match_dup 3)
6030 (mod:SI (reg:SI 0) (match_dup 2)))
6031 (use (match_dup 3))
6032 (clobber (reg:CC 17))])]
6033 "
6034 {
6035 /* Avoid use of cltd in favour of a mov+shift. */
6036 if (!TARGET_USE_CLTD && !optimize_size)
6037 {
6038 if (true_regnum (operands[1]))
6039 emit_move_insn (operands[0], operands[1]);
6040 else
6041 emit_move_insn (operands[3], operands[1]);
6042 operands[4] = operands[3];
6043 }
6044 else
6045 {
6046 if (true_regnum (operands[1]))
6047 abort();
6048 operands[4] = operands[1];
6049 }
6050 }")
6051 ;; %%% Split me.
6052 (define_insn "divmodhi4"
6053 [(set (match_operand:HI 0 "register_operand" "=a")
6054 (div:HI (match_operand:HI 1 "register_operand" "0")
6055 (match_operand:HI 2 "nonimmediate_operand" "rm")))
6056 (set (match_operand:HI 3 "register_operand" "=&d")
6057 (mod:HI (match_dup 1) (match_dup 2)))
6058 (clobber (reg:CC 17))]
6059 "TARGET_HIMODE_MATH"
6060 "cwtd\;idiv{w}\\t%2"
6061 [(set_attr "type" "multi")
6062 (set_attr "length_immediate" "0")
6063 (set_attr "mode" "SI")])
6064
6065 (define_insn "udivmodsi4"
6066 [(set (match_operand:SI 0 "register_operand" "=a")
6067 (udiv:SI (match_operand:SI 1 "register_operand" "0")
6068 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6069 (set (match_operand:SI 3 "register_operand" "=&d")
6070 (umod:SI (match_dup 1) (match_dup 2)))
6071 (clobber (reg:CC 17))]
6072 ""
6073 "xor{l}\\t%3, %3\;div{l}\\t%2"
6074 [(set_attr "type" "multi")
6075 (set_attr "length_immediate" "0")
6076 (set_attr "mode" "SI")])
6077
6078 (define_insn "*udivmodsi4_noext"
6079 [(set (match_operand:SI 0 "register_operand" "=a")
6080 (udiv:SI (match_operand:SI 1 "register_operand" "0")
6081 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6082 (set (match_operand:SI 3 "register_operand" "=d")
6083 (umod:SI (match_dup 1) (match_dup 2)))
6084 (use (match_dup 3))
6085 (clobber (reg:CC 17))]
6086 ""
6087 "div{l}\\t%2"
6088 [(set_attr "type" "idiv")
6089 (set_attr "ppro_uops" "few")
6090 (set_attr "mode" "SI")])
6091
6092 (define_split
6093 [(set (match_operand:SI 0 "register_operand" "")
6094 (udiv:SI (match_operand:SI 1 "register_operand" "")
6095 (match_operand:SI 2 "nonimmediate_operand" "")))
6096 (set (match_operand:SI 3 "register_operand" "")
6097 (umod:SI (match_dup 1) (match_dup 2)))
6098 (clobber (reg:CC 17))]
6099 "reload_completed"
6100 [(set (match_dup 3) (const_int 0))
6101 (parallel [(set (match_dup 0)
6102 (udiv:SI (match_dup 1) (match_dup 2)))
6103 (set (match_dup 3)
6104 (umod:SI (match_dup 1) (match_dup 2)))
6105 (use (match_dup 3))
6106 (clobber (reg:CC 17))])]
6107 "")
6108
6109 (define_expand "udivmodhi4"
6110 [(set (match_dup 4) (const_int 0))
6111 (parallel [(set (match_operand:HI 0 "register_operand" "")
6112 (udiv:HI (match_operand:HI 1 "register_operand" "")
6113 (match_operand:HI 2 "nonimmediate_operand" "")))
6114 (set (match_operand:HI 3 "register_operand" "")
6115 (umod:HI (match_dup 1) (match_dup 2)))
6116 (use (match_dup 4))
6117 (clobber (reg:CC 17))])]
6118 "TARGET_HIMODE_MATH"
6119 "operands[4] = gen_reg_rtx (HImode);")
6120
6121 (define_insn "*udivmodhi_noext"
6122 [(set (match_operand:HI 0 "register_operand" "=a")
6123 (udiv:HI (match_operand:HI 1 "register_operand" "0")
6124 (match_operand:HI 2 "nonimmediate_operand" "rm")))
6125 (set (match_operand:HI 3 "register_operand" "=d")
6126 (umod:HI (match_dup 1) (match_dup 2)))
6127 (use (match_operand:HI 4 "register_operand" "3"))
6128 (clobber (reg:CC 17))]
6129 ""
6130 "div{w}\\t%2"
6131 [(set_attr "type" "idiv")
6132 (set_attr "mode" "HI")
6133 (set_attr "ppro_uops" "few")])
6134
6135 ;; We can not use div/idiv for double division, because it causes
6136 ;; "division by zero" on the overflow and that's not what we expect
6137 ;; from truncate. Because true (non truncating) double division is
6138 ;; never generated, we can't create this insn anyway.
6139 ;
6140 ;(define_insn ""
6141 ; [(set (match_operand:SI 0 "register_operand" "=a")
6142 ; (truncate:SI
6143 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
6144 ; (zero_extend:DI
6145 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
6146 ; (set (match_operand:SI 3 "register_operand" "=d")
6147 ; (truncate:SI
6148 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
6149 ; (clobber (reg:CC 17))]
6150 ; ""
6151 ; "div{l}\\t{%2, %0|%0, %2}"
6152 ; [(set_attr "type" "idiv")
6153 ; (set_attr "ppro_uops" "few")])
6154 \f
6155 ;;- Logical AND instructions
6156
6157 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
6158 ;; Note that this excludes ah.
6159
6160
6161 (define_insn "testsi_1"
6162 [(set (reg 17)
6163 (compare
6164 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
6165 (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
6166 (const_int 0)))]
6167 "ix86_match_ccmode (insn, CCNOmode)"
6168 "test{l}\\t{%1, %0|%0, %1}"
6169 [(set_attr "type" "test")
6170 (set_attr "modrm" "0,1,1")
6171 (set_attr "mode" "SI")
6172 (set_attr "pent_pair" "uv,np,uv")])
6173
6174 (define_expand "testsi_ccno_1"
6175 [(set (reg:CCNO 17)
6176 (compare:CCNO
6177 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
6178 (match_operand:SI 1 "nonmemory_operand" ""))
6179 (const_int 0)))]
6180 ""
6181 "")
6182
6183 (define_insn "*testhi_1"
6184 [(set (reg 17)
6185 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
6186 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
6187 (const_int 0)))]
6188 "ix86_match_ccmode (insn, CCNOmode)"
6189 "test{w}\\t{%1, %0|%0, %1}"
6190 [(set_attr "type" "test")
6191 (set_attr "modrm" "0,1,1")
6192 (set_attr "mode" "HI")
6193 (set_attr "pent_pair" "uv,np,uv")])
6194
6195 (define_expand "testqi_ccz_1"
6196 [(set (reg:CCZ 17)
6197 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
6198 (match_operand:QI 1 "nonmemory_operand" ""))
6199 (const_int 0)))]
6200 ""
6201 "")
6202
6203 (define_insn "*testqi_1"
6204 [(set (reg 17)
6205 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
6206 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
6207 (const_int 0)))]
6208 "ix86_match_ccmode (insn, CCNOmode)"
6209 "*
6210 {
6211 if (which_alternative == 3)
6212 {
6213 if (GET_CODE (operands[1]) == CONST_INT
6214 && (INTVAL (operands[1]) & 0xffffff00))
6215 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
6216 return \"test{l}\\t{%1, %k0|%k0, %1}\";
6217 }
6218 return \"test{b}\\t{%1, %0|%0, %1}\";
6219 }"
6220 [(set_attr "type" "test")
6221 (set_attr "modrm" "0,1,1,1")
6222 (set_attr "mode" "QI,QI,QI,SI")
6223 (set_attr "pent_pair" "uv,np,uv,np")])
6224
6225 (define_expand "testqi_ext_ccno_0"
6226 [(set (reg:CCNO 17)
6227 (compare:CCNO
6228 (and:SI
6229 (zero_extract:SI
6230 (match_operand 0 "ext_register_operand" "")
6231 (const_int 8)
6232 (const_int 8))
6233 (match_operand 1 "const_int_operand" ""))
6234 (const_int 0)))]
6235 ""
6236 "")
6237
6238 (define_insn "*testqi_ext_0"
6239 [(set (reg 17)
6240 (compare
6241 (and:SI
6242 (zero_extract:SI
6243 (match_operand 0 "ext_register_operand" "q")
6244 (const_int 8)
6245 (const_int 8))
6246 (match_operand 1 "const_int_operand" "n"))
6247 (const_int 0)))]
6248 "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
6249 && ix86_match_ccmode (insn, CCNOmode)"
6250 "test{b}\\t{%1, %h0|%h0, %1}"
6251 [(set_attr "type" "test")
6252 (set_attr "mode" "QI")
6253 (set_attr "length_immediate" "1")
6254 (set_attr "pent_pair" "np")])
6255
6256 (define_insn "*testqi_ext_1"
6257 [(set (reg 17)
6258 (compare
6259 (and:SI
6260 (zero_extract:SI
6261 (match_operand 0 "ext_register_operand" "q")
6262 (const_int 8)
6263 (const_int 8))
6264 (zero_extend:SI
6265 (match_operand:QI 1 "nonimmediate_operand" "qm")))
6266 (const_int 0)))]
6267 "ix86_match_ccmode (insn, CCNOmode)"
6268 "test{b}\\t{%1, %h0|%h0, %1}"
6269 [(set_attr "type" "test")
6270 (set_attr "mode" "QI")])
6271
6272 (define_insn "*testqi_ext_2"
6273 [(set (reg 17)
6274 (compare
6275 (and:SI
6276 (zero_extract:SI
6277 (match_operand 0 "ext_register_operand" "q")
6278 (const_int 8)
6279 (const_int 8))
6280 (zero_extract:SI
6281 (match_operand 1 "ext_register_operand" "q")
6282 (const_int 8)
6283 (const_int 8)))
6284 (const_int 0)))]
6285 "ix86_match_ccmode (insn, CCNOmode)"
6286 "test{b}\\t{%h1, %h0|%h0, %h1}"
6287 [(set_attr "type" "test")
6288 (set_attr "mode" "QI")])
6289
6290 ;; Combine likes to form bit extractions for some tests. Humor it.
6291 (define_insn "*testqi_ext_3"
6292 [(set (reg 17)
6293 (compare (zero_extract:SI
6294 (match_operand 0 "nonimmediate_operand" "rm")
6295 (match_operand:SI 1 "const_int_operand" "")
6296 (match_operand:SI 2 "const_int_operand" ""))
6297 (const_int 0)))]
6298 "ix86_match_ccmode (insn, CCNOmode)
6299 && (GET_MODE (operands[0]) == SImode
6300 || GET_MODE (operands[0]) == HImode
6301 || GET_MODE (operands[0]) == QImode)"
6302 "#")
6303
6304 (define_split
6305 [(set (reg 17)
6306 (compare (zero_extract:SI
6307 (match_operand 0 "nonimmediate_operand" "rm")
6308 (match_operand:SI 1 "const_int_operand" "")
6309 (match_operand:SI 2 "const_int_operand" ""))
6310 (const_int 0)))]
6311 "ix86_match_ccmode (insn, CCNOmode)"
6312 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
6313 "
6314 {
6315 HOST_WIDE_INT len = INTVAL (operands[1]);
6316 HOST_WIDE_INT pos = INTVAL (operands[2]);
6317 HOST_WIDE_INT mask;
6318 enum machine_mode mode;
6319
6320 mode = GET_MODE (operands[0]);
6321 if (GET_CODE (operands[0]) == MEM)
6322 {
6323 /* ??? Combine likes to put non-volatile mem extractions in QImode
6324 no matter the size of the test. So find a mode that works. */
6325 if (! MEM_VOLATILE_P (operands[0]))
6326 {
6327 mode = smallest_mode_for_size (pos + len, MODE_INT);
6328 operands[0] = change_address (operands[0], mode, NULL_RTX);
6329 }
6330 }
6331 else if (mode == HImode && pos + len <= 8)
6332 {
6333 /* Small HImode tests can be converted to QImode. */
6334 mode = QImode;
6335 operands[0] = gen_lowpart (QImode, operands[0]);
6336 }
6337
6338 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
6339 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
6340
6341 operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
6342 }")
6343
6344 ;; %%% This used to optimize known byte-wide and operations to memory,
6345 ;; and sometimes to QImode registers. If this is considered useful,
6346 ;; it should be done with splitters.
6347
6348 (define_expand "andsi3"
6349 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6350 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
6351 (match_operand:SI 2 "general_operand" "")))
6352 (clobber (reg:CC 17))]
6353 ""
6354 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
6355
6356 (define_insn "*andsi_1"
6357 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
6358 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
6359 (match_operand:SI 2 "general_operand" "ri,rm,L")))
6360 (clobber (reg:CC 17))]
6361 "ix86_binary_operator_ok (AND, SImode, operands)"
6362 "*
6363 {
6364 switch (get_attr_type (insn))
6365 {
6366 case TYPE_IMOVX:
6367 {
6368 enum machine_mode mode;
6369
6370 if (GET_CODE (operands[2]) != CONST_INT)
6371 abort ();
6372 if (INTVAL (operands[2]) == 0xff)
6373 mode = QImode;
6374 else if (INTVAL (operands[2]) == 0xffff)
6375 mode = HImode;
6376 else
6377 abort ();
6378
6379 operands[1] = gen_lowpart (mode, operands[1]);
6380 if (mode == QImode)
6381 return \"movz{bl|x}\\t{%1,%0|%0, %1}\";
6382 else
6383 return \"movz{wl|x}\\t{%1,%0|%0, %1}\";
6384 }
6385
6386 default:
6387 if (! rtx_equal_p (operands[0], operands[1]))
6388 abort ();
6389 return \"and{l}\\t{%2, %0|%0, %2}\";
6390 }
6391 }"
6392 [(set_attr "type" "alu,alu,imovx")
6393 (set_attr "length_immediate" "*,*,0")
6394 (set_attr "mode" "SI")])
6395
6396 (define_split
6397 [(set (match_operand:SI 0 "register_operand" "")
6398 (and:SI (match_dup 0)
6399 (const_int -65536)))
6400 (clobber (reg:CC 17))]
6401 "optimize_size"
6402 [(set (strict_low_part (match_dup 1)) (const_int 0))]
6403 "operands[1] = gen_lowpart (HImode, operands[0]);")
6404
6405 (define_split
6406 [(set (match_operand 0 "q_regs_operand" "")
6407 (and (match_dup 0)
6408 (const_int -256)))
6409 (clobber (reg:CC 17))]
6410 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6411 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6412 [(set (strict_low_part (match_dup 1)) (const_int 0))]
6413 "operands[1] = gen_lowpart (QImode, operands[0]);")
6414
6415 (define_split
6416 [(set (match_operand 0 "q_regs_operand" "")
6417 (and (match_dup 0)
6418 (const_int -65281)))
6419 (clobber (reg:CC 17))]
6420 "(optimize_size || !TARGET_PARTIAL_REG_STALL)
6421 && (GET_MODE (operands[0]) == SImode || GET_MODE (operands[0]) == HImode)"
6422 [(parallel [(set (zero_extract:SI (match_dup 0)
6423 (const_int 8)
6424 (const_int 8))
6425 (xor:SI
6426 (zero_extract:SI (match_dup 0)
6427 (const_int 8)
6428 (const_int 8))
6429 (zero_extract:SI (match_dup 0)
6430 (const_int 8)
6431 (const_int 8))))
6432 (clobber (reg:CC 17))])]
6433 "operands[0] = gen_lowpart (SImode, operands[0]);")
6434
6435 (define_insn "*andsi_2"
6436 [(set (reg 17)
6437 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6438 (match_operand:SI 2 "general_operand" "rim,ri"))
6439 (const_int 0)))
6440 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6441 (and:SI (match_dup 1) (match_dup 2)))]
6442 "ix86_match_ccmode (insn, CCNOmode)
6443 && ix86_binary_operator_ok (AND, SImode, operands)"
6444 "and{l}\\t{%2, %0|%0, %2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "SI")])
6447
6448 (define_expand "andhi3"
6449 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6450 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
6451 (match_operand:HI 2 "general_operand" "")))
6452 (clobber (reg:CC 17))]
6453 "TARGET_HIMODE_MATH"
6454 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
6455
6456 (define_insn "*andhi_1"
6457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6458 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
6459 (match_operand:HI 2 "general_operand" "ri,rm,L")))
6460 (clobber (reg:CC 17))]
6461 "ix86_binary_operator_ok (AND, HImode, operands)"
6462 "*
6463 {
6464 switch (get_attr_type (insn))
6465 {
6466 case TYPE_IMOVX:
6467 if (GET_CODE (operands[2]) != CONST_INT)
6468 abort ();
6469 if (INTVAL (operands[2]) == 0xff)
6470 return \"movz{bl|x}\\t{%b1, %k0|%k0, %b1}\";
6471 abort ();
6472
6473 default:
6474 if (! rtx_equal_p (operands[0], operands[1]))
6475 abort ();
6476
6477 return \"and{w}\\t{%2, %0|%0, %2}\";
6478 }
6479 }"
6480 [(set_attr "type" "alu,alu,imovx")
6481 (set_attr "length_immediate" "*,*,0")
6482 (set_attr "mode" "HI,HI,SI")])
6483
6484 (define_insn "*andhi_2"
6485 [(set (reg 17)
6486 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6487 (match_operand:HI 2 "general_operand" "rim,ri"))
6488 (const_int 0)))
6489 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6490 (and:HI (match_dup 1) (match_dup 2)))]
6491 "ix86_match_ccmode (insn, CCNOmode)
6492 && ix86_binary_operator_ok (AND, HImode, operands)"
6493 "and{w}\\t{%2, %0|%0, %2}"
6494 [(set_attr "type" "alu")
6495 (set_attr "mode" "HI")])
6496
6497 (define_expand "andqi3"
6498 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6499 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
6500 (match_operand:QI 2 "general_operand" "")))
6501 (clobber (reg:CC 17))]
6502 "TARGET_QIMODE_MATH"
6503 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
6504
6505 ;; %%% Potential partial reg stall on alternative 2. What to do?
6506 (define_insn "*andqi_1"
6507 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6508 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6509 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
6510 (clobber (reg:CC 17))]
6511 "ix86_binary_operator_ok (AND, QImode, operands)"
6512 "@
6513 and{b}\\t{%2, %0|%0, %2}
6514 and{b}\\t{%2, %0|%0, %2}
6515 and{l}\\t{%k2, %k0|%k0, %k2}"
6516 [(set_attr "type" "alu")
6517 (set_attr "mode" "QI,QI,SI")])
6518
6519 (define_insn "*andqi_1_slp"
6520 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6521 (and:QI (match_dup 0)
6522 (match_operand:QI 1 "general_operand" "qi,qmi")))
6523 (clobber (reg:CC 17))]
6524 ""
6525 "and{b}\\t{%1, %0|%0, %1}"
6526 [(set_attr "type" "alu1")
6527 (set_attr "mode" "QI")])
6528
6529 (define_insn "*andqi_2"
6530 [(set (reg 17)
6531 (compare (and:QI
6532 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6533 (match_operand:QI 2 "general_operand" "qim,qi,i"))
6534 (const_int 0)))
6535 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
6536 (and:QI (match_dup 1) (match_dup 2)))]
6537 "ix86_match_ccmode (insn, CCNOmode)
6538 && ix86_binary_operator_ok (AND, QImode, operands)"
6539 "*
6540 {
6541 if (which_alternative == 2)
6542 {
6543 if (GET_CODE (operands[2]) == CONST_INT
6544 && (INTVAL (operands[2]) & 0xffffff00))
6545 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
6546 return \"and{l}\\t{%2, %k0|%k0, %2}\";
6547 }
6548 return \"and{b}\\t{%2, %0|%0, %2}\";
6549 }"
6550 [(set_attr "type" "alu")
6551 (set_attr "mode" "QI,QI,SI")])
6552
6553 (define_insn "*andqi_2_slp"
6554 [(set (reg 17)
6555 (compare (and:QI
6556 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6557 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
6558 (const_int 0)))
6559 (set (strict_low_part (match_dup 0))
6560 (and:QI (match_dup 0) (match_dup 1)))]
6561 "ix86_match_ccmode (insn, CCNOmode)"
6562 "and{b}\\t{%1, %0|%0, %1}"
6563 [(set_attr "type" "alu1")
6564 (set_attr "mode" "QI")])
6565
6566 ;; ??? A bug in recog prevents it from recognizing a const_int as an
6567 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
6568 ;; for a QImode operand, which of course failed.
6569
6570 (define_insn "andqi_ext_0"
6571 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6572 (const_int 8)
6573 (const_int 8))
6574 (and:SI
6575 (zero_extract:SI
6576 (match_operand 1 "ext_register_operand" "0")
6577 (const_int 8)
6578 (const_int 8))
6579 (match_operand 2 "const_int_operand" "n")))
6580 (clobber (reg:CC 17))]
6581 "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6582 "and{b}\\t{%2, %h0|%h0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "length_immediate" "1")
6585 (set_attr "mode" "QI")])
6586
6587 ;; Generated by peephole translating test to and. This shows up
6588 ;; often in fp comparisons.
6589
6590 (define_insn "*andqi_ext_0_cc"
6591 [(set (reg 17)
6592 (compare
6593 (and:SI
6594 (zero_extract:SI
6595 (match_operand 1 "ext_register_operand" "0")
6596 (const_int 8)
6597 (const_int 8))
6598 (match_operand 2 "const_int_operand" "n"))
6599 (const_int 0)))
6600 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6601 (const_int 8)
6602 (const_int 8))
6603 (and:SI
6604 (zero_extract:SI
6605 (match_dup 1)
6606 (const_int 8)
6607 (const_int 8))
6608 (match_dup 2)))]
6609 "ix86_match_ccmode (insn, CCNOmode)
6610 && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
6611 "and{b}\\t{%2, %h0|%h0, %2}"
6612 [(set_attr "type" "alu")
6613 (set_attr "length_immediate" "1")
6614 (set_attr "mode" "QI")])
6615
6616 (define_insn "*andqi_ext_1"
6617 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6618 (const_int 8)
6619 (const_int 8))
6620 (and:SI
6621 (zero_extract:SI
6622 (match_operand 1 "ext_register_operand" "0")
6623 (const_int 8)
6624 (const_int 8))
6625 (zero_extend:SI
6626 (match_operand:QI 2 "general_operand" "qm"))))
6627 (clobber (reg:CC 17))]
6628 ""
6629 "and{b}\\t{%2, %h0|%h0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "length_immediate" "0")
6632 (set_attr "mode" "QI")])
6633
6634 (define_insn "*andqi_ext_2"
6635 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6636 (const_int 8)
6637 (const_int 8))
6638 (and:SI
6639 (zero_extract:SI
6640 (match_operand 1 "ext_register_operand" "%0")
6641 (const_int 8)
6642 (const_int 8))
6643 (zero_extract:SI
6644 (match_operand 2 "ext_register_operand" "q")
6645 (const_int 8)
6646 (const_int 8))))
6647 (clobber (reg:CC 17))]
6648 ""
6649 "and{b}\\t{%h2, %h0|%h0, %h2}"
6650 [(set_attr "type" "alu")
6651 (set_attr "length_immediate" "0")
6652 (set_attr "mode" "QI")])
6653 \f
6654 ;; Logical inclusive OR instructions
6655
6656 ;; %%% This used to optimize known byte-wide and operations to memory.
6657 ;; If this is considered useful, it should be done with splitters.
6658
6659 (define_expand "iorsi3"
6660 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6661 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
6662 (match_operand:SI 2 "general_operand" "")))
6663 (clobber (reg:CC 17))]
6664 ""
6665 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
6666
6667 (define_insn "*iorsi_1"
6668 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6670 (match_operand:SI 2 "general_operand" "ri,rmi")))
6671 (clobber (reg:CC 17))]
6672 "ix86_binary_operator_ok (IOR, SImode, operands)"
6673 "or{l}\\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "mode" "SI")])
6676
6677 (define_insn "*iorsi_2"
6678 [(set (reg 17)
6679 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6680 (match_operand:SI 2 "general_operand" "rim,ri"))
6681 (const_int 0)))
6682 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6683 (ior:SI (match_dup 1) (match_dup 2)))]
6684 "ix86_match_ccmode (insn, CCNOmode)
6685 && ix86_binary_operator_ok (IOR, SImode, operands)"
6686 "or{l}\\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "SI")])
6689
6690 (define_insn "*iorsi_3"
6691 [(set (reg 17)
6692 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6693 (match_operand:SI 2 "general_operand" "rim"))
6694 (const_int 0)))
6695 (clobber (match_scratch:SI 0 "=r"))]
6696 "ix86_match_ccmode (insn, CCNOmode)
6697 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6698 "or{l}\\t{%2, %0|%0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "SI")])
6701
6702 (define_expand "iorhi3"
6703 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6704 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
6705 (match_operand:HI 2 "general_operand" "")))
6706 (clobber (reg:CC 17))]
6707 "TARGET_HIMODE_MATH"
6708 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
6709
6710 (define_insn "*iorhi_1"
6711 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6712 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6713 (match_operand:HI 2 "general_operand" "rmi,ri")))
6714 (clobber (reg:CC 17))]
6715 "ix86_binary_operator_ok (IOR, HImode, operands)"
6716 "or{w}\\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "HI")])
6719
6720 (define_insn "*iorhi_2"
6721 [(set (reg 17)
6722 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6723 (match_operand:HI 2 "general_operand" "rim,ri"))
6724 (const_int 0)))
6725 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6726 (ior:HI (match_dup 1) (match_dup 2)))]
6727 "ix86_match_ccmode (insn, CCNOmode)
6728 && ix86_binary_operator_ok (IOR, HImode, operands)"
6729 "or{w}\\t{%2, %0|%0, %2}"
6730 [(set_attr "type" "alu")
6731 (set_attr "mode" "HI")])
6732
6733 (define_insn "*iorhi_3"
6734 [(set (reg 17)
6735 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6736 (match_operand:HI 2 "general_operand" "rim"))
6737 (const_int 0)))
6738 (clobber (match_scratch:HI 0 "=r"))]
6739 "ix86_match_ccmode (insn, CCNOmode)
6740 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6741 "or{w}\\t{%2, %0|%0, %2}"
6742 [(set_attr "type" "alu")
6743 (set_attr "mode" "HI")])
6744
6745 (define_expand "iorqi3"
6746 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6747 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
6748 (match_operand:QI 2 "general_operand" "")))
6749 (clobber (reg:CC 17))]
6750 "TARGET_QIMODE_MATH"
6751 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
6752
6753 ;; %%% Potential partial reg stall on alternative 2. What to do?
6754 (define_insn "*iorqi_1"
6755 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
6756 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6757 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
6758 (clobber (reg:CC 17))]
6759 "ix86_binary_operator_ok (IOR, QImode, operands)"
6760 "@
6761 or{b}\\t{%2, %0|%0, %2}
6762 or{b}\\t{%2, %0|%0, %2}
6763 or{l}\\t{%k2, %k0|%k0, %k2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "QI,QI,SI")])
6766
6767 (define_insn "*iorqi_1_slp"
6768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
6769 (ior:QI (match_dup 0)
6770 (match_operand:QI 1 "general_operand" "qmi,qi")))
6771 (clobber (reg:CC 17))]
6772 ""
6773 "or{b}\\t{%1, %0|%0, %1}"
6774 [(set_attr "type" "alu1")
6775 (set_attr "mode" "QI")])
6776
6777 (define_insn "*iorqi_2"
6778 [(set (reg 17)
6779 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6780 (match_operand:QI 2 "general_operand" "qim,qi"))
6781 (const_int 0)))
6782 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6783 (ior:QI (match_dup 1) (match_dup 2)))]
6784 "ix86_match_ccmode (insn, CCNOmode)
6785 && ix86_binary_operator_ok (IOR, QImode, operands)"
6786 "or{b}\\t{%2, %0|%0, %2}"
6787 [(set_attr "type" "alu")
6788 (set_attr "mode" "QI")])
6789
6790 (define_insn "*iorqi_2_slp"
6791 [(set (reg 17)
6792 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
6793 (match_operand:QI 1 "general_operand" "qim,qi"))
6794 (const_int 0)))
6795 (set (strict_low_part (match_dup 0))
6796 (ior:QI (match_dup 0) (match_dup 1)))]
6797 "ix86_match_ccmode (insn, CCNOmode)"
6798 "or{b}\\t{%1, %0|%0, %1}"
6799 [(set_attr "type" "alu1")
6800 (set_attr "mode" "QI")])
6801
6802 (define_insn "*iorqi_3"
6803 [(set (reg 17)
6804 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6805 (match_operand:QI 2 "general_operand" "qim"))
6806 (const_int 0)))
6807 (clobber (match_scratch:QI 0 "=q"))]
6808 "ix86_match_ccmode (insn, CCNOmode)
6809 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6810 "or{b}\\t{%2, %0|%0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "QI")])
6813
6814 \f
6815 ;; Logical XOR instructions
6816
6817 ;; %%% This used to optimize known byte-wide and operations to memory.
6818 ;; If this is considered useful, it should be done with splitters.
6819
6820 (define_expand "xorsi3"
6821 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6822 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
6823 (match_operand:SI 2 "general_operand" "")))
6824 (clobber (reg:CC 17))]
6825 ""
6826 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
6827
6828 (define_insn "*xorsi_1"
6829 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6830 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6831 (match_operand:SI 2 "general_operand" "ri,rm")))
6832 (clobber (reg:CC 17))]
6833 "ix86_binary_operator_ok (XOR, SImode, operands)"
6834 "xor{l}\\t{%2, %0|%0, %2}"
6835 [(set_attr "type" "alu")
6836 (set_attr "mode" "SI")])
6837
6838 (define_insn "*xorsi_2"
6839 [(set (reg 17)
6840 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6841 (match_operand:SI 2 "general_operand" "rim,ri"))
6842 (const_int 0)))
6843 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6844 (xor:SI (match_dup 1) (match_dup 2)))]
6845 "ix86_match_ccmode (insn, CCNOmode)
6846 && ix86_binary_operator_ok (XOR, SImode, operands)"
6847 "xor{l}\\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "SI")])
6850
6851 (define_insn "*xorsi_3"
6852 [(set (reg 17)
6853 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6854 (match_operand:SI 2 "general_operand" "rim"))
6855 (const_int 0)))
6856 (clobber (match_scratch:SI 0 "=r"))]
6857 "ix86_match_ccmode (insn, CCNOmode)
6858 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6859 "xor{l}\\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "alu")
6861 (set_attr "mode" "SI")])
6862
6863 (define_expand "xorhi3"
6864 [(set (match_operand:HI 0 "nonimmediate_operand" "")
6865 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
6866 (match_operand:HI 2 "general_operand" "")))
6867 (clobber (reg:CC 17))]
6868 "TARGET_HIMODE_MATH"
6869 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
6870
6871 (define_insn "*xorhi_1"
6872 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
6873 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6874 (match_operand:HI 2 "general_operand" "rmi,ri")))
6875 (clobber (reg:CC 17))]
6876 "ix86_binary_operator_ok (XOR, HImode, operands)"
6877 "xor{w}\\t{%2, %0|%0, %2}"
6878 [(set_attr "type" "alu")
6879 (set_attr "mode" "HI")])
6880
6881 (define_insn "*xorhi_2"
6882 [(set (reg 17)
6883 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6884 (match_operand:HI 2 "general_operand" "rim,ri"))
6885 (const_int 0)))
6886 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6887 (xor:HI (match_dup 1) (match_dup 2)))]
6888 "ix86_match_ccmode (insn, CCNOmode)
6889 && ix86_binary_operator_ok (XOR, HImode, operands)"
6890 "xor{w}\\t{%2, %0|%0, %2}"
6891 [(set_attr "type" "alu")
6892 (set_attr "mode" "HI")])
6893
6894 (define_insn "*xorhi_3"
6895 [(set (reg 17)
6896 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6897 (match_operand:HI 2 "general_operand" "rim"))
6898 (const_int 0)))
6899 (clobber (match_scratch:HI 0 "=r"))]
6900 "ix86_match_ccmode (insn, CCNOmode)
6901 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6902 "xor{w}\\t{%2, %0|%0, %2}"
6903 [(set_attr "type" "alu")
6904 (set_attr "mode" "HI")])
6905
6906 (define_expand "xorqi3"
6907 [(set (match_operand:QI 0 "nonimmediate_operand" "")
6908 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
6909 (match_operand:QI 2 "general_operand" "")))
6910 (clobber (reg:CC 17))]
6911 "TARGET_QIMODE_MATH"
6912 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
6913
6914 ;; %%% Potential partial reg stall on alternative 2. What to do?
6915 (define_insn "*xorqi_1"
6916 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
6917 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6918 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
6919 (clobber (reg:CC 17))]
6920 "ix86_binary_operator_ok (XOR, QImode, operands)"
6921 "@
6922 xor{b}\\t{%2, %0|%0, %2}
6923 xor{b}\\t{%2, %0|%0, %2}
6924 xor{l}\\t{%k2, %k0|%k0, %k2}"
6925 [(set_attr "type" "alu")
6926 (set_attr "mode" "QI,QI,SI")])
6927
6928 (define_insn "*xorqi_ext_1"
6929 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6930 (const_int 8)
6931 (const_int 8))
6932 (xor:SI
6933 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
6934 (const_int 8)
6935 (const_int 8))
6936 (zero_extract:SI (match_operand 2 "ext_register_operand" "q")
6937 (const_int 8)
6938 (const_int 8))))
6939 (clobber (reg:CC 17))]
6940 ""
6941 "xor{b}\\t{%h2, %h0|%h0, %h2}"
6942 [(set_attr "type" "alu")
6943 (set_attr "length_immediate" "0")
6944 (set_attr "mode" "QI")])
6945
6946 (define_insn "*xorqi_cc_1"
6947 [(set (reg 17)
6948 (compare
6949 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6950 (match_operand:QI 2 "general_operand" "qim,qi"))
6951 (const_int 0)))
6952 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6953 (xor:QI (match_dup 1) (match_dup 2)))]
6954 "ix86_match_ccmode (insn, CCNOmode)
6955 && ix86_binary_operator_ok (XOR, QImode, operands)"
6956 "xor{b}\\t{%2, %0|%0, %2}"
6957 [(set_attr "type" "alu")
6958 (set_attr "mode" "QI")])
6959
6960 (define_insn "*xorqi_cc_2"
6961 [(set (reg 17)
6962 (compare
6963 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6964 (match_operand:QI 2 "general_operand" "qim"))
6965 (const_int 0)))
6966 (clobber (match_scratch:QI 0 "=q"))]
6967 "ix86_match_ccmode (insn, CCNOmode)
6968 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6969 "xor{b}\\t{%2, %0|%0, %2}"
6970 [(set_attr "type" "alu")
6971 (set_attr "mode" "QI")])
6972
6973 (define_insn "*xorqi_cc_ext_1"
6974 [(set (reg 17)
6975 (compare
6976 (xor:SI
6977 (zero_extract:SI
6978 (match_operand 1 "ext_register_operand" "0")
6979 (const_int 8)
6980 (const_int 8))
6981 (match_operand:QI 2 "general_operand" "qmn"))
6982 (const_int 0)))
6983 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
6984 (const_int 8)
6985 (const_int 8))
6986 (xor:SI
6987 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
6988 (match_dup 2)))]
6989 "ix86_match_ccmode (insn, CCNOmode)"
6990 "xor{b}\\t{%2, %h0|%h0, %2}"
6991 [(set_attr "type" "alu")
6992 (set_attr "mode" "QI")])
6993
6994 (define_expand "xorqi_cc_ext_1"
6995 [(parallel [
6996 (set (reg:CCNO 17)
6997 (compare:CCNO
6998 (xor:SI
6999 (zero_extract:SI
7000 (match_operand 1 "ext_register_operand" "")
7001 (const_int 8)
7002 (const_int 8))
7003 (match_operand:QI 2 "general_operand" ""))
7004 (const_int 0)))
7005 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
7006 (const_int 8)
7007 (const_int 8))
7008 (xor:SI
7009 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
7010 (match_dup 2)))])]
7011 ""
7012 "")
7013 \f
7014 ;; Negation instructions
7015
7016 ;; %%% define_expand from the very first?
7017
7018 (define_expand "negdi2"
7019 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7020 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
7021 (clobber (reg:CC 17))])]
7022 ""
7023 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
7024
7025 (define_insn "*negdi2_1"
7026 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
7027 (neg:DI (match_operand:DI 1 "general_operand" "0")))
7028 (clobber (reg:CC 17))]
7029 "ix86_unary_operator_ok (NEG, DImode, operands)"
7030 "#")
7031
7032 (define_split
7033 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7034 (neg:DI (match_operand:DI 1 "general_operand" "")))
7035 (clobber (reg:CC 17))]
7036 "reload_completed"
7037 [(parallel
7038 [(set (reg:CCZ 17)
7039 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
7040 (set (match_dup 0) (neg:SI (match_dup 2)))])
7041 (parallel
7042 [(set (match_dup 1)
7043 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
7044 (match_dup 3))
7045 (const_int 0)))
7046 (clobber (reg:CC 17))])
7047 (parallel
7048 [(set (match_dup 1)
7049 (neg:SI (match_dup 1)))
7050 (clobber (reg:CC 17))])]
7051 "split_di (operands+1, 1, operands+2, operands+3);
7052 split_di (operands+0, 1, operands+0, operands+1);")
7053
7054 (define_expand "negsi2"
7055 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7056 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
7057 (clobber (reg:CC 17))])]
7058 ""
7059 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
7060
7061 (define_insn "*negsi2_1"
7062 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7063 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
7064 (clobber (reg:CC 17))]
7065 "ix86_unary_operator_ok (NEG, SImode, operands)"
7066 "neg{l}\\t%0"
7067 [(set_attr "type" "negnot")
7068 (set_attr "mode" "SI")])
7069
7070 ;; The problem with neg is that it does not perform (compare x 0),
7071 ;; it really performs (compare 0 x), which leaves us with the zero
7072 ;; flag being the only useful item.
7073
7074 (define_insn "*negsi2_cmpz"
7075 [(set (reg:CCZ 17)
7076 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7077 (const_int 0)))
7078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7079 (neg:SI (match_dup 1)))]
7080 "ix86_unary_operator_ok (NEG, SImode, operands)"
7081 "neg{l}\\t%0"
7082 [(set_attr "type" "negnot")
7083 (set_attr "mode" "SI")])
7084
7085 (define_expand "neghi2"
7086 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7087 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
7088 (clobber (reg:CC 17))])]
7089 "TARGET_HIMODE_MATH"
7090 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
7091
7092 (define_insn "*neghi2_1"
7093 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7094 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
7095 (clobber (reg:CC 17))]
7096 "ix86_unary_operator_ok (NEG, HImode, operands)"
7097 "neg{w}\\t%0"
7098 [(set_attr "type" "negnot")
7099 (set_attr "mode" "HI")])
7100
7101 (define_insn "*neghi2_cmpz"
7102 [(set (reg:CCZ 17)
7103 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7104 (const_int 0)))
7105 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7106 (neg:HI (match_dup 1)))]
7107 "ix86_unary_operator_ok (NEG, HImode, operands)"
7108 "neg{w}\\t%0"
7109 [(set_attr "type" "negnot")
7110 (set_attr "mode" "HI")])
7111
7112 (define_expand "negqi2"
7113 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7114 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
7115 (clobber (reg:CC 17))])]
7116 "TARGET_QIMODE_MATH"
7117 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
7118
7119 (define_insn "*negqi2_1"
7120 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7121 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
7122 (clobber (reg:CC 17))]
7123 "ix86_unary_operator_ok (NEG, QImode, operands)"
7124 "neg{b}\\t%0"
7125 [(set_attr "type" "negnot")
7126 (set_attr "mode" "QI")])
7127
7128 (define_insn "*negqi2_cmpz"
7129 [(set (reg:CCZ 17)
7130 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
7131 (const_int 0)))
7132 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7133 (neg:QI (match_dup 1)))]
7134 "ix86_unary_operator_ok (NEG, QImode, operands)"
7135 "neg{b}\\t%0"
7136 [(set_attr "type" "negnot")
7137 (set_attr "mode" "QI")])
7138
7139 ;; Changing of sign for FP values is doable using integer unit too.
7140
7141 (define_expand "negsf2"
7142 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
7143 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
7144 (clobber (reg:CC 17))])]
7145 "TARGET_80387"
7146 "ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
7147
7148 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7149 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7150 ;; to itself.
7151 (define_insn "*negsf2_if"
7152 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7153 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
7154 (clobber (reg:CC 17))]
7155 "TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
7156 "#")
7157
7158 (define_split
7159 [(set (match_operand:SF 0 "register_operand" "")
7160 (neg:SF (match_operand:SF 1 "register_operand" "")))
7161 (clobber (reg:CC 17))]
7162 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7163 [(set (match_dup 0)
7164 (neg:SF (match_dup 1)))]
7165 "")
7166
7167 (define_split
7168 [(set (match_operand:SF 0 "register_operand" "")
7169 (neg:SF (match_operand:SF 1 "register_operand" "")))
7170 (clobber (reg:CC 17))]
7171 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7172 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7173 (clobber (reg:CC 17))])]
7174 "operands[1] = GEN_INT (0x80000000);
7175 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7176
7177 (define_split
7178 [(set (match_operand 0 "memory_operand" "")
7179 (neg (match_operand 1 "memory_operand" "")))
7180 (clobber (reg:CC 17))]
7181 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7182 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7183 (clobber (reg:CC 17))])]
7184 "
7185 {
7186 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7187
7188 /* XFmode's size is 12, but only 10 bytes are used. */
7189 if (size == 12)
7190 size = 10;
7191 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7192 operands[0] = adj_offsettable_operand (operands[0], size - 1);
7193 operands[1] = GEN_INT (0x80);
7194 }")
7195
7196 (define_expand "negdf2"
7197 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
7198 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
7199 (clobber (reg:CC 17))])]
7200 "TARGET_80387"
7201 "ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
7202
7203 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7204 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7205 ;; to itself.
7206 (define_insn "*negdf2_if"
7207 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7208 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
7209 (clobber (reg:CC 17))]
7210 "TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
7211 "#")
7212
7213 (define_split
7214 [(set (match_operand:DF 0 "register_operand" "")
7215 (neg:DF (match_operand:DF 1 "register_operand" "")))
7216 (clobber (reg:CC 17))]
7217 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7218 [(set (match_dup 0)
7219 (neg:DF (match_dup 1)))]
7220 "")
7221
7222 (define_split
7223 [(set (match_operand:DF 0 "register_operand" "")
7224 (neg:DF (match_operand:DF 1 "register_operand" "")))
7225 (clobber (reg:CC 17))]
7226 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7227 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
7228 (clobber (reg:CC 17))])]
7229 "operands[4] = GEN_INT (0x80000000);
7230 split_di (operands+0, 1, operands+2, operands+3);")
7231
7232 (define_expand "negxf2"
7233 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
7234 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
7235 (clobber (reg:CC 17))])]
7236 "TARGET_80387"
7237 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
7238
7239 (define_expand "negtf2"
7240 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7241 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7242 (clobber (reg:CC 17))])]
7243 "TARGET_80387"
7244 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
7245
7246 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7247 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7248 ;; to itself.
7249 (define_insn "*negxf2_if"
7250 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7251 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
7252 (clobber (reg:CC 17))]
7253 "TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
7254 "#")
7255
7256 (define_split
7257 [(set (match_operand:XF 0 "register_operand" "")
7258 (neg:XF (match_operand:XF 1 "register_operand" "")))
7259 (clobber (reg:CC 17))]
7260 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7261 [(set (match_dup 0)
7262 (neg:XF (match_dup 1)))]
7263 "")
7264
7265 (define_split
7266 [(set (match_operand:XF 0 "register_operand" "")
7267 (neg:XF (match_operand:XF 1 "register_operand" "")))
7268 (clobber (reg:CC 17))]
7269 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7270 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7271 (clobber (reg:CC 17))])]
7272 "operands[1] = GEN_INT (0x8000);
7273 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7274
7275 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7276 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7277 ;; to itself.
7278 (define_insn "*negtf2_if"
7279 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7280 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7281 (clobber (reg:CC 17))]
7282 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
7283 "#")
7284
7285 (define_split
7286 [(set (match_operand:TF 0 "register_operand" "")
7287 (neg:TF (match_operand:TF 1 "register_operand" "")))
7288 (clobber (reg:CC 17))]
7289 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7290 [(set (match_dup 0)
7291 (neg:TF (match_dup 1)))]
7292 "")
7293
7294 (define_split
7295 [(set (match_operand:TF 0 "register_operand" "")
7296 (neg:TF (match_operand:TF 1 "register_operand" "")))
7297 (clobber (reg:CC 17))]
7298 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7299 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
7300 (clobber (reg:CC 17))])]
7301 "operands[1] = GEN_INT (0x8000);
7302 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7303
7304 ;; Conditionize these after reload. If they matches before reload, we
7305 ;; lose the clobber and ability to use integer instructions.
7306
7307 (define_insn "*negsf2_1"
7308 [(set (match_operand:SF 0 "register_operand" "=f")
7309 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
7310 "TARGET_80387 && reload_completed"
7311 "fchs"
7312 [(set_attr "type" "fsgn")
7313 (set_attr "mode" "SF")
7314 (set_attr "ppro_uops" "few")])
7315
7316 (define_insn "*negdf2_1"
7317 [(set (match_operand:DF 0 "register_operand" "=f")
7318 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
7319 "TARGET_80387 && reload_completed"
7320 "fchs"
7321 [(set_attr "type" "fsgn")
7322 (set_attr "mode" "DF")
7323 (set_attr "ppro_uops" "few")])
7324
7325 (define_insn "*negextendsfdf2"
7326 [(set (match_operand:DF 0 "register_operand" "=f")
7327 (neg:DF (float_extend:DF
7328 (match_operand:SF 1 "register_operand" "0"))))]
7329 "TARGET_80387"
7330 "fchs"
7331 [(set_attr "type" "fsgn")
7332 (set_attr "mode" "DF")
7333 (set_attr "ppro_uops" "few")])
7334
7335 (define_insn "*negxf2_1"
7336 [(set (match_operand:XF 0 "register_operand" "=f")
7337 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
7338 "TARGET_80387 && reload_completed"
7339 "fchs"
7340 [(set_attr "type" "fsgn")
7341 (set_attr "mode" "XF")
7342 (set_attr "ppro_uops" "few")])
7343
7344 (define_insn "*negextenddfxf2"
7345 [(set (match_operand:XF 0 "register_operand" "=f")
7346 (neg:XF (float_extend:XF
7347 (match_operand:DF 1 "register_operand" "0"))))]
7348 "TARGET_80387"
7349 "fchs"
7350 [(set_attr "type" "fsgn")
7351 (set_attr "mode" "XF")
7352 (set_attr "ppro_uops" "few")])
7353
7354 (define_insn "*negextendsfxf2"
7355 [(set (match_operand:XF 0 "register_operand" "=f")
7356 (neg:XF (float_extend:XF
7357 (match_operand:SF 1 "register_operand" "0"))))]
7358 "TARGET_80387"
7359 "fchs"
7360 [(set_attr "type" "fsgn")
7361 (set_attr "mode" "XF")
7362 (set_attr "ppro_uops" "few")])
7363
7364 (define_insn "*negtf2_1"
7365 [(set (match_operand:TF 0 "register_operand" "=f")
7366 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
7367 "TARGET_80387 && reload_completed"
7368 "fchs"
7369 [(set_attr "type" "fsgn")
7370 (set_attr "mode" "XF")
7371 (set_attr "ppro_uops" "few")])
7372
7373 (define_insn "*negextenddftf2"
7374 [(set (match_operand:TF 0 "register_operand" "=f")
7375 (neg:TF (float_extend:TF
7376 (match_operand:DF 1 "register_operand" "0"))))]
7377 "TARGET_80387"
7378 "fchs"
7379 [(set_attr "type" "fsgn")
7380 (set_attr "mode" "XF")
7381 (set_attr "ppro_uops" "few")])
7382
7383 (define_insn "*negextendsftf2"
7384 [(set (match_operand:TF 0 "register_operand" "=f")
7385 (neg:TF (float_extend:TF
7386 (match_operand:SF 1 "register_operand" "0"))))]
7387 "TARGET_80387"
7388 "fchs"
7389 [(set_attr "type" "fsgn")
7390 (set_attr "mode" "XF")
7391 (set_attr "ppro_uops" "few")])
7392 \f
7393 ;; Absolute value instructions
7394
7395 (define_expand "abssf2"
7396 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
7397 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
7398 (clobber (reg:CC 17))])]
7399 "TARGET_80387"
7400 "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
7401
7402 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7403 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7404 ;; to itself.
7405 (define_insn "*abssf2_if"
7406 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
7407 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
7408 (clobber (reg:CC 17))]
7409 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
7410 "#")
7411
7412 (define_split
7413 [(set (match_operand:SF 0 "register_operand" "")
7414 (abs:SF (match_operand:SF 1 "register_operand" "")))
7415 (clobber (reg:CC 17))]
7416 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
7417 [(set (match_dup 0)
7418 (abs:SF (match_dup 1)))]
7419 "")
7420
7421 (define_split
7422 [(set (match_operand:SF 0 "register_operand" "")
7423 (abs:SF (match_operand:SF 1 "register_operand" "")))
7424 (clobber (reg:CC 17))]
7425 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7426 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7427 (clobber (reg:CC 17))])]
7428 "operands[1] = GEN_INT (~0x80000000);
7429 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
7430
7431 (define_split
7432 [(set (match_operand 0 "memory_operand" "")
7433 (abs (match_operand 1 "memory_operand" "")))
7434 (clobber (reg:CC 17))]
7435 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
7436 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7437 (clobber (reg:CC 17))])]
7438 "
7439 {
7440 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
7441
7442 /* XFmode's size is 12, but only 10 bytes are used. */
7443 if (size == 12)
7444 size = 10;
7445 operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
7446 operands[0] = adj_offsettable_operand (operands[0], size - 1);
7447 operands[1] = GEN_INT (~0x80);
7448 }")
7449
7450 (define_expand "absdf2"
7451 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
7452 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
7453 (clobber (reg:CC 17))])]
7454 "TARGET_80387"
7455 "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
7456
7457 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7458 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7459 ;; to itself.
7460 (define_insn "*absdf2_if"
7461 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
7462 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
7463 (clobber (reg:CC 17))]
7464 "TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
7465 "#")
7466
7467 (define_split
7468 [(set (match_operand:DF 0 "register_operand" "")
7469 (abs:DF (match_operand:DF 1 "register_operand" "")))
7470 (clobber (reg:CC 17))]
7471 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7472 [(set (match_dup 0)
7473 (abs:DF (match_dup 1)))]
7474 "")
7475
7476 (define_split
7477 [(set (match_operand:DF 0 "register_operand" "")
7478 (abs:DF (match_operand:DF 1 "register_operand" "")))
7479 (clobber (reg:CC 17))]
7480 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7481 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
7482 (clobber (reg:CC 17))])]
7483 "operands[4] = GEN_INT (~0x80000000);
7484 split_di (operands+0, 1, operands+2, operands+3);")
7485
7486 (define_expand "absxf2"
7487 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
7488 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
7489 (clobber (reg:CC 17))])]
7490 "TARGET_80387"
7491 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
7492
7493 (define_expand "abstf2"
7494 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
7495 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
7496 (clobber (reg:CC 17))])]
7497 "TARGET_80387"
7498 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
7499
7500 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
7501 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
7502 ;; to itself.
7503 (define_insn "*absxf2_if"
7504 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
7505 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
7506 (clobber (reg:CC 17))]
7507 "TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
7508 "#")
7509
7510 (define_split
7511 [(set (match_operand:XF 0 "register_operand" "")
7512 (abs:XF (match_operand:XF 1 "register_operand" "")))
7513 (clobber (reg:CC 17))]
7514 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7515 [(set (match_dup 0)
7516 (abs:XF (match_dup 1)))]
7517 "")
7518
7519 (define_split
7520 [(set (match_operand:XF 0 "register_operand" "")
7521 (abs:XF (match_operand:XF 1 "register_operand" "")))
7522 (clobber (reg:CC 17))]
7523 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7524 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7525 (clobber (reg:CC 17))])]
7526 "operands[1] = GEN_INT (~0x8000);
7527 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7528
7529 (define_insn "*abstf2_if"
7530 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
7531 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
7532 (clobber (reg:CC 17))]
7533 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
7534 "#")
7535
7536 (define_split
7537 [(set (match_operand:TF 0 "register_operand" "")
7538 (abs:TF (match_operand:TF 1 "register_operand" "")))
7539 (clobber (reg:CC 17))]
7540 "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
7541 [(set (match_dup 0)
7542 (abs:TF (match_dup 1)))]
7543 "")
7544
7545 (define_split
7546 [(set (match_operand:TF 0 "register_operand" "")
7547 (abs:TF (match_operand:TF 1 "register_operand" "")))
7548 (clobber (reg:CC 17))]
7549 "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
7550 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
7551 (clobber (reg:CC 17))])]
7552 "operands[1] = GEN_INT (~0x8000);
7553 operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
7554
7555 (define_insn "*abssf2_1"
7556 [(set (match_operand:SF 0 "register_operand" "=f")
7557 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
7558 "TARGET_80387 && reload_completed"
7559 "fabs"
7560 [(set_attr "type" "fsgn")
7561 (set_attr "mode" "SF")])
7562
7563 (define_insn "*absdf2_1"
7564 [(set (match_operand:DF 0 "register_operand" "=f")
7565 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
7566 "TARGET_80387 && reload_completed"
7567 "fabs"
7568 [(set_attr "type" "fsgn")
7569 (set_attr "mode" "DF")])
7570
7571 (define_insn "*absextendsfdf2"
7572 [(set (match_operand:DF 0 "register_operand" "=f")
7573 (abs:DF (float_extend:DF
7574 (match_operand:SF 1 "register_operand" "0"))))]
7575 "TARGET_80387"
7576 "fabs"
7577 [(set_attr "type" "fsgn")
7578 (set_attr "mode" "DF")])
7579
7580 (define_insn "*absxf2_1"
7581 [(set (match_operand:XF 0 "register_operand" "=f")
7582 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
7583 "TARGET_80387 && reload_completed"
7584 "fabs"
7585 [(set_attr "type" "fsgn")
7586 (set_attr "mode" "DF")])
7587
7588 (define_insn "*absextenddfxf2"
7589 [(set (match_operand:XF 0 "register_operand" "=f")
7590 (abs:XF (float_extend:XF
7591 (match_operand:DF 1 "register_operand" "0"))))]
7592 "TARGET_80387"
7593 "fabs"
7594 [(set_attr "type" "fsgn")
7595 (set_attr "mode" "XF")])
7596
7597 (define_insn "*absextendsfxf2"
7598 [(set (match_operand:XF 0 "register_operand" "=f")
7599 (abs:XF (float_extend:XF
7600 (match_operand:SF 1 "register_operand" "0"))))]
7601 "TARGET_80387"
7602 "fabs"
7603 [(set_attr "type" "fsgn")
7604 (set_attr "mode" "XF")])
7605
7606 (define_insn "*abstf2_1"
7607 [(set (match_operand:TF 0 "register_operand" "=f")
7608 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
7609 "TARGET_80387 && reload_completed"
7610 "fabs"
7611 [(set_attr "type" "fsgn")
7612 (set_attr "mode" "DF")])
7613
7614 (define_insn "*absextenddftf2"
7615 [(set (match_operand:TF 0 "register_operand" "=f")
7616 (abs:TF (float_extend:TF
7617 (match_operand:DF 1 "register_operand" "0"))))]
7618 "TARGET_80387"
7619 "fabs"
7620 [(set_attr "type" "fsgn")
7621 (set_attr "mode" "XF")])
7622
7623 (define_insn "*absextendsftf2"
7624 [(set (match_operand:TF 0 "register_operand" "=f")
7625 (abs:TF (float_extend:TF
7626 (match_operand:SF 1 "register_operand" "0"))))]
7627 "TARGET_80387"
7628 "fabs"
7629 [(set_attr "type" "fsgn")
7630 (set_attr "mode" "XF")])
7631 \f
7632 ;; One complement instructions
7633
7634 (define_expand "one_cmplsi2"
7635 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7636 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
7637 ""
7638 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
7639
7640 (define_insn "*one_cmplsi2_1"
7641 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7642 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
7643 "ix86_unary_operator_ok (NOT, SImode, operands)"
7644 "not{l}\\t%0"
7645 [(set_attr "type" "negnot")
7646 (set_attr "mode" "SI")])
7647
7648 (define_insn "*one_cmplsi2_2"
7649 [(set (reg 17)
7650 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
7651 (const_int 0)))
7652 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7653 (not:SI (match_dup 1)))]
7654 "ix86_match_ccmode (insn, CCNOmode)
7655 && ix86_unary_operator_ok (NOT, SImode, operands)"
7656 "#"
7657 [(set_attr "type" "alu1")
7658 (set_attr "mode" "SI")])
7659
7660 (define_split
7661 [(set (reg 17)
7662 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
7663 (const_int 0)))
7664 (set (match_operand:SI 0 "nonimmediate_operand" "")
7665 (not:SI (match_dup 1)))]
7666 "ix86_match_ccmode (insn, CCNOmode)"
7667 [(parallel [(set (reg:CCNO 17)
7668 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
7669 (const_int 0)))
7670 (set (match_dup 0)
7671 (xor:SI (match_dup 1) (const_int -1)))])]
7672 "")
7673
7674 (define_expand "one_cmplhi2"
7675 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7676 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
7677 "TARGET_HIMODE_MATH"
7678 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
7679
7680 (define_insn "*one_cmplhi2_1"
7681 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7682 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
7683 "ix86_unary_operator_ok (NOT, HImode, operands)"
7684 "not{w}\\t%0"
7685 [(set_attr "type" "negnot")
7686 (set_attr "mode" "HI")])
7687
7688 (define_insn "*one_cmplhi2_2"
7689 [(set (reg 17)
7690 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
7691 (const_int 0)))
7692 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7693 (not:HI (match_dup 1)))]
7694 "ix86_match_ccmode (insn, CCNOmode)
7695 && ix86_unary_operator_ok (NEG, HImode, operands)"
7696 "#"
7697 [(set_attr "type" "alu1")
7698 (set_attr "mode" "HI")])
7699
7700 (define_split
7701 [(set (reg 17)
7702 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
7703 (const_int 0)))
7704 (set (match_operand:HI 0 "nonimmediate_operand" "")
7705 (not:HI (match_dup 1)))]
7706 "ix86_match_ccmode (insn, CCNOmode)"
7707 [(parallel [(set (reg:CCNO 17)
7708 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
7709 (const_int 0)))
7710 (set (match_dup 0)
7711 (xor:HI (match_dup 1) (const_int -1)))])]
7712 "")
7713
7714 ;; %%% Potential partial reg stall on alternative 1. What to do?
7715 (define_expand "one_cmplqi2"
7716 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7717 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
7718 "TARGET_QIMODE_MATH"
7719 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
7720
7721 (define_insn "*one_cmplqi2_1"
7722 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
7723 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
7724 "ix86_unary_operator_ok (NOT, QImode, operands)"
7725 "@
7726 not{b}\\t%0
7727 not{l}\\t%k0"
7728 [(set_attr "type" "negnot")
7729 (set_attr "mode" "QI,SI")])
7730
7731 (define_insn "*one_cmplqi2_2"
7732 [(set (reg 17)
7733 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
7734 (const_int 0)))
7735 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
7736 (not:QI (match_dup 1)))]
7737 "ix86_match_ccmode (insn, CCNOmode)
7738 && ix86_unary_operator_ok (NOT, QImode, operands)"
7739 "#"
7740 [(set_attr "type" "alu1")
7741 (set_attr "mode" "QI")])
7742
7743 (define_split
7744 [(set (reg 17)
7745 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
7746 (const_int 0)))
7747 (set (match_operand:QI 0 "nonimmediate_operand" "")
7748 (not:QI (match_dup 1)))]
7749 "ix86_match_ccmode (insn, CCNOmode)"
7750 [(parallel [(set (reg:CCNO 17)
7751 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
7752 (const_int 0)))
7753 (set (match_dup 0)
7754 (xor:QI (match_dup 1) (const_int -1)))])]
7755 "")
7756 \f
7757 ;; Arithmetic shift instructions
7758
7759 ;; DImode shifts are implemented using the i386 "shift double" opcode,
7760 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
7761 ;; is variable, then the count is in %cl and the "imm" operand is dropped
7762 ;; from the assembler input.
7763 ;;
7764 ;; This instruction shifts the target reg/mem as usual, but instead of
7765 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
7766 ;; is a left shift double, bits are taken from the high order bits of
7767 ;; reg, else if the insn is a shift right double, bits are taken from the
7768 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
7769 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
7770 ;;
7771 ;; Since sh[lr]d does not change the `reg' operand, that is done
7772 ;; separately, making all shifts emit pairs of shift double and normal
7773 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
7774 ;; support a 63 bit shift, each shift where the count is in a reg expands
7775 ;; to a pair of shifts, a branch, a shift by 32 and a label.
7776 ;;
7777 ;; If the shift count is a constant, we need never emit more than one
7778 ;; shift pair, instead using moves and sign extension for counts greater
7779 ;; than 31.
7780
7781 (define_expand "ashldi3"
7782 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
7783 (ashift:DI (match_operand:DI 1 "register_operand" "0")
7784 (match_operand:QI 2 "nonmemory_operand" "Jc")))
7785 (clobber (reg:CC 17))])]
7786 ""
7787 "
7788 {
7789 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
7790 {
7791 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
7792 DONE;
7793 }
7794 }")
7795
7796 (define_insn "ashldi3_1"
7797 [(set (match_operand:DI 0 "register_operand" "=r")
7798 (ashift:DI (match_operand:DI 1 "register_operand" "0")
7799 (match_operand:QI 2 "nonmemory_operand" "Jc")))
7800 (clobber (match_scratch:SI 3 "=&r"))
7801 (clobber (reg:CC 17))]
7802 "TARGET_CMOVE"
7803 "#"
7804 [(set_attr "type" "multi")])
7805
7806 (define_insn "*ashldi3_2"
7807 [(set (match_operand:DI 0 "register_operand" "=r")
7808 (ashift:DI (match_operand:DI 1 "register_operand" "0")
7809 (match_operand:QI 2 "nonmemory_operand" "Jc")))
7810 (clobber (reg:CC 17))]
7811 ""
7812 "#"
7813 [(set_attr "type" "multi")])
7814
7815 (define_split
7816 [(set (match_operand:DI 0 "register_operand" "")
7817 (ashift:DI (match_operand:DI 1 "register_operand" "")
7818 (match_operand:QI 2 "nonmemory_operand" "")))
7819 (clobber (match_scratch:SI 3 ""))
7820 (clobber (reg:CC 17))]
7821 "TARGET_CMOVE && reload_completed"
7822 [(const_int 0)]
7823 "ix86_split_ashldi (operands, operands[3]); DONE;")
7824
7825 (define_split
7826 [(set (match_operand:DI 0 "register_operand" "")
7827 (ashift:DI (match_operand:DI 1 "register_operand" "")
7828 (match_operand:QI 2 "nonmemory_operand" "")))
7829 (clobber (reg:CC 17))]
7830 "reload_completed"
7831 [(const_int 0)]
7832 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
7833
7834 (define_insn "x86_shld_1"
7835 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
7836 (ior:SI (ashift:SI (match_dup 0)
7837 (match_operand:QI 2 "nonmemory_operand" "I,c"))
7838 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
7839 (minus:QI (const_int 32) (match_dup 2)))))
7840 (clobber (reg:CC 17))]
7841 ""
7842 "@
7843 shld{l}\\t{%2, %1, %0|%0, %1, %2}
7844 shld{l}\\t{%s2%1, %0|%0, %1, %2}"
7845 [(set_attr "type" "ishift")
7846 (set_attr "prefix_0f" "1")
7847 (set_attr "mode" "SI")
7848 (set_attr "pent_pair" "np")
7849 (set_attr "athlon_decode" "vector")
7850 (set_attr "ppro_uops" "few")])
7851
7852 (define_expand "x86_shift_adj_1"
7853 [(set (reg:CCZ 17)
7854 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
7855 (const_int 32))
7856 (const_int 0)))
7857 (set (match_operand:SI 0 "register_operand" "")
7858 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
7859 (match_operand:SI 1 "register_operand" "")
7860 (match_dup 0)))
7861 (set (match_dup 1)
7862 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
7863 (match_operand:SI 3 "register_operand" "r")
7864 (match_dup 1)))]
7865 "TARGET_CMOVE"
7866 "")
7867
7868 (define_expand "x86_shift_adj_2"
7869 [(use (match_operand:SI 0 "register_operand" ""))
7870 (use (match_operand:SI 1 "register_operand" ""))
7871 (use (match_operand:QI 2 "register_operand" ""))]
7872 ""
7873 "
7874 {
7875 rtx label = gen_label_rtx ();
7876 rtx tmp;
7877
7878 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
7879
7880 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
7881 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7882 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
7883 gen_rtx_LABEL_REF (VOIDmode, label),
7884 pc_rtx);
7885 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
7886 JUMP_LABEL (tmp) = label;
7887
7888 emit_move_insn (operands[0], operands[1]);
7889 emit_move_insn (operands[1], const0_rtx);
7890
7891 emit_label (label);
7892 LABEL_NUSES (label) = 1;
7893
7894 DONE;
7895 }")
7896
7897 (define_expand "ashlsi3"
7898 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7899 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
7900 (match_operand:QI 2 "nonmemory_operand" "")))
7901 (clobber (reg:CC 17))]
7902 ""
7903 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
7904
7905 (define_insn "*ashlsi3_1"
7906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7907 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
7908 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
7909 (clobber (reg:CC 17))]
7910 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
7911 "*
7912 {
7913 switch (get_attr_type (insn))
7914 {
7915 case TYPE_ALU:
7916 if (operands[2] != const1_rtx)
7917 abort ();
7918 if (!rtx_equal_p (operands[0], operands[1]))
7919 abort ();
7920 return \"add{l}\\t{%0, %0|%0, %0}\";
7921
7922 case TYPE_LEA:
7923 if (GET_CODE (operands[2]) != CONST_INT
7924 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
7925 abort ();
7926 operands[1] = gen_rtx_MULT (SImode, operands[1],
7927 GEN_INT (1 << INTVAL (operands[2])));
7928 return \"lea{l}\\t{%a1, %0|%0, %a1}\";
7929
7930 default:
7931 if (REG_P (operands[2]))
7932 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
7933 else if (GET_CODE (operands[2]) == CONST_INT
7934 && INTVAL (operands[2]) == 1
7935 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
7936 return \"sal{l}\\t%0\";
7937 else
7938 return \"sal{l}\\t{%2, %0|%0, %2}\";
7939 }
7940 }"
7941 [(set (attr "type")
7942 (cond [(eq_attr "alternative" "1")
7943 (const_string "lea")
7944 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
7945 (const_int 0))
7946 (match_operand 0 "register_operand" ""))
7947 (match_operand 2 "const1_operand" ""))
7948 (const_string "alu")
7949 ]
7950 (const_string "ishift")))
7951 (set_attr "mode" "SI")])
7952
7953 ;; Convert lea to the lea pattern to avoid flags dependency.
7954 (define_split
7955 [(set (match_operand 0 "register_operand" "")
7956 (ashift (match_operand 1 "register_operand" "")
7957 (match_operand:QI 2 "const_int_operand" "")))
7958 (clobber (reg:CC 17))]
7959 "reload_completed
7960 && true_regnum (operands[0]) != true_regnum (operands[1])"
7961 [(const_int 0)]
7962 "
7963 {
7964 rtx pat;
7965 operands[0] = gen_lowpart (SImode, operands[0]);
7966 operands[1] = gen_lowpart (Pmode, operands[1]);
7967 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7968 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
7969 if (Pmode != SImode)
7970 pat = gen_rtx_SUBREG (SImode, pat, 0);
7971 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7972 DONE;
7973 }")
7974
7975 ;; This pattern can't accept a variable shift count, since shifts by
7976 ;; zero don't affect the flags. We assume that shifts by constant
7977 ;; zero are optimized away.
7978 (define_insn "*ashlsi3_cmp"
7979 [(set (reg 17)
7980 (compare
7981 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
7982 (match_operand:QI 2 "immediate_operand" "I"))
7983 (const_int 0)))
7984 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7985 (ashift:SI (match_dup 1) (match_dup 2)))]
7986 "ix86_match_ccmode (insn, CCGOCmode)
7987 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
7988 "*
7989 {
7990 switch (get_attr_type (insn))
7991 {
7992 case TYPE_ALU:
7993 if (operands[2] != const1_rtx)
7994 abort ();
7995 return \"add{l}\\t{%0, %0|%0, %0}\";
7996
7997 default:
7998 if (REG_P (operands[2]))
7999 return \"sal{l}\\t{%b2, %0|%0, %b2}\";
8000 else if (GET_CODE (operands[2]) == CONST_INT
8001 && INTVAL (operands[2]) == 1
8002 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8003 return \"sal{l}\\t%0\";
8004 else
8005 return \"sal{l}\\t{%2, %0|%0, %2}\";
8006 }
8007 }"
8008 [(set (attr "type")
8009 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8010 (const_int 0))
8011 (match_operand 0 "register_operand" ""))
8012 (match_operand 2 "const1_operand" ""))
8013 (const_string "alu")
8014 ]
8015 (const_string "ishift")))
8016 (set_attr "mode" "SI")])
8017
8018 (define_expand "ashlhi3"
8019 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8020 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
8021 (match_operand:QI 2 "nonmemory_operand" "")))
8022 (clobber (reg:CC 17))]
8023 "TARGET_HIMODE_MATH"
8024 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
8025
8026 (define_insn "*ashlhi3_1_lea"
8027 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8028 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
8029 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8030 (clobber (reg:CC 17))]
8031 "!TARGET_PARTIAL_REG_STALL
8032 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8033 "*
8034 {
8035 switch (get_attr_type (insn))
8036 {
8037 case TYPE_LEA:
8038 return \"#\";
8039 case TYPE_ALU:
8040 if (operands[2] != const1_rtx)
8041 abort ();
8042 return \"add{w}\\t{%0, %0|%0, %0}\";
8043
8044 default:
8045 if (REG_P (operands[2]))
8046 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8047 else if (GET_CODE (operands[2]) == CONST_INT
8048 && INTVAL (operands[2]) == 1
8049 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8050 return \"sal{w}\\t%0\";
8051 else
8052 return \"sal{w}\\t{%2, %0|%0, %2}\";
8053 }
8054 }"
8055 [(set (attr "type")
8056 (cond [(eq_attr "alternative" "1")
8057 (const_string "lea")
8058 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8059 (const_int 0))
8060 (match_operand 0 "register_operand" ""))
8061 (match_operand 2 "const1_operand" ""))
8062 (const_string "alu")
8063 ]
8064 (const_string "ishift")))
8065 (set_attr "mode" "HI,SI")])
8066
8067 (define_insn "*ashlhi3_1"
8068 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8069 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8070 (match_operand:QI 2 "nonmemory_operand" "cI")))
8071 (clobber (reg:CC 17))]
8072 "TARGET_PARTIAL_REG_STALL
8073 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8074 "*
8075 {
8076 switch (get_attr_type (insn))
8077 {
8078 case TYPE_ALU:
8079 if (operands[2] != const1_rtx)
8080 abort ();
8081 return \"add{w}\\t{%0, %0|%0, %0}\";
8082
8083 default:
8084 if (REG_P (operands[2]))
8085 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8086 else if (GET_CODE (operands[2]) == CONST_INT
8087 && INTVAL (operands[2]) == 1
8088 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8089 return \"sal{w}\\t%0\";
8090 else
8091 return \"sal{w}\\t{%2, %0|%0, %2}\";
8092 }
8093 }"
8094 [(set (attr "type")
8095 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8096 (const_int 0))
8097 (match_operand 0 "register_operand" ""))
8098 (match_operand 2 "const1_operand" ""))
8099 (const_string "alu")
8100 ]
8101 (const_string "ishift")))
8102 (set_attr "mode" "HI")])
8103
8104 ;; This pattern can't accept a variable shift count, since shifts by
8105 ;; zero don't affect the flags. We assume that shifts by constant
8106 ;; zero are optimized away.
8107 (define_insn "*ashlhi3_cmp"
8108 [(set (reg 17)
8109 (compare
8110 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8111 (match_operand:QI 2 "immediate_operand" "I"))
8112 (const_int 0)))
8113 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8114 (ashift:HI (match_dup 1) (match_dup 2)))]
8115 "ix86_match_ccmode (insn, CCGOCmode)
8116 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8117 "*
8118 {
8119 switch (get_attr_type (insn))
8120 {
8121 case TYPE_ALU:
8122 if (operands[2] != const1_rtx)
8123 abort ();
8124 return \"add{w}\\t{%0, %0|%0, %0}\";
8125
8126 default:
8127 if (REG_P (operands[2]))
8128 return \"sal{w}\\t{%b2, %0|%0, %b2}\";
8129 else if (GET_CODE (operands[2]) == CONST_INT
8130 && INTVAL (operands[2]) == 1
8131 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8132 return \"sal{w}\\t%0\";
8133 else
8134 return \"sal{w}\\t{%2, %0|%0, %2}\";
8135 }
8136 }"
8137 [(set (attr "type")
8138 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8139 (const_int 0))
8140 (match_operand 0 "register_operand" ""))
8141 (match_operand 2 "const1_operand" ""))
8142 (const_string "alu")
8143 ]
8144 (const_string "ishift")))
8145 (set_attr "mode" "HI")])
8146
8147 (define_expand "ashlqi3"
8148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8149 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
8150 (match_operand:QI 2 "nonmemory_operand" "")))
8151 (clobber (reg:CC 17))]
8152 "TARGET_QIMODE_MATH"
8153 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
8154
8155 ;; %%% Potential partial reg stall on alternative 2. What to do?
8156
8157 (define_insn "*ashlqi3_1_lea"
8158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
8159 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
8160 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8161 (clobber (reg:CC 17))]
8162 "!TARGET_PARTIAL_REG_STALL
8163 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8164 "*
8165 {
8166 switch (get_attr_type (insn))
8167 {
8168 case TYPE_LEA:
8169 return \"#\";
8170 case TYPE_ALU:
8171 if (operands[2] != const1_rtx)
8172 abort ();
8173 if (NON_QI_REG_P (operands[1]))
8174 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
8175 else
8176 return \"add{b}\\t{%0, %0|%0, %0}\";
8177
8178 default:
8179 if (REG_P (operands[2]))
8180 {
8181 if (get_attr_mode (insn) == MODE_SI)
8182 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
8183 else
8184 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8185 }
8186 else if (GET_CODE (operands[2]) == CONST_INT
8187 && INTVAL (operands[2]) == 1
8188 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8189 {
8190 if (get_attr_mode (insn) == MODE_SI)
8191 return \"sal{l}\\t%0\";
8192 else
8193 return \"sal{b}\\t%0\";
8194 }
8195 else
8196 {
8197 if (get_attr_mode (insn) == MODE_SI)
8198 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
8199 else
8200 return \"sal{b}\\t{%2, %0|%0, %2}\";
8201 }
8202 }
8203 }"
8204 [(set (attr "type")
8205 (cond [(eq_attr "alternative" "2")
8206 (const_string "lea")
8207 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8208 (const_int 0))
8209 (match_operand 0 "register_operand" ""))
8210 (match_operand 2 "const1_operand" ""))
8211 (const_string "alu")
8212 ]
8213 (const_string "ishift")))
8214 (set_attr "mode" "QI,SI,SI")])
8215
8216 (define_insn "*ashlqi3_1"
8217 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8218 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8219 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
8220 (clobber (reg:CC 17))]
8221 "TARGET_PARTIAL_REG_STALL
8222 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8223 "*
8224 {
8225 switch (get_attr_type (insn))
8226 {
8227 case TYPE_ALU:
8228 if (operands[2] != const1_rtx)
8229 abort ();
8230 if (NON_QI_REG_P (operands[1]))
8231 return \"add{l}\\t{%k0, %k0|%k0, %k0}\";
8232 else
8233 return \"add{b}\\t{%0, %0|%0, %0}\";
8234
8235 default:
8236 if (REG_P (operands[2]))
8237 {
8238 if (NON_QI_REG_P (operands[1]))
8239 return \"sal{l}\\t{%b2, %k0|%k0, %b2}\";
8240 else
8241 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8242 }
8243 else if (GET_CODE (operands[2]) == CONST_INT
8244 && INTVAL (operands[2]) == 1
8245 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8246 {
8247 if (NON_QI_REG_P (operands[1]))
8248 return \"sal{l}\\t%0\";
8249 else
8250 return \"sal{b}\\t%0\";
8251 }
8252 else
8253 {
8254 if (NON_QI_REG_P (operands[1]))
8255 return \"sal{l}\\t{%2, %k0|%k0, %2}\";
8256 else
8257 return \"sal{b}\\t{%2, %0|%0, %2}\";
8258 }
8259 }
8260 }"
8261 [(set (attr "type")
8262 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8263 (const_int 0))
8264 (match_operand 0 "register_operand" ""))
8265 (match_operand 2 "const1_operand" ""))
8266 (const_string "alu")
8267 ]
8268 (const_string "ishift")))
8269 (set_attr "mode" "QI,SI")])
8270
8271 ;; This pattern can't accept a variable shift count, since shifts by
8272 ;; zero don't affect the flags. We assume that shifts by constant
8273 ;; zero are optimized away.
8274 (define_insn "*ashlqi3_cmp"
8275 [(set (reg 17)
8276 (compare
8277 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8278 (match_operand:QI 2 "immediate_operand" "I"))
8279 (const_int 0)))
8280 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8281 (ashift:QI (match_dup 1) (match_dup 2)))]
8282 "ix86_match_ccmode (insn, CCGOCmode)
8283 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8284 "*
8285 {
8286 switch (get_attr_type (insn))
8287 {
8288 case TYPE_ALU:
8289 if (operands[2] != const1_rtx)
8290 abort ();
8291 return \"add{b}\\t{%0, %0|%0, %0}\";
8292
8293 default:
8294 if (REG_P (operands[2]))
8295 return \"sal{b}\\t{%b2, %0|%0, %b2}\";
8296 else if (GET_CODE (operands[2]) == CONST_INT
8297 && INTVAL (operands[2]) == 1
8298 && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
8299 return \"sal{b}\\t%0\";
8300 else
8301 return \"sal{b}\\t{%2, %0|%0, %2}\";
8302 }
8303 }"
8304 [(set (attr "type")
8305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
8306 (const_int 0))
8307 (match_operand 0 "register_operand" ""))
8308 (match_operand 2 "const1_operand" ""))
8309 (const_string "alu")
8310 ]
8311 (const_string "ishift")))
8312 (set_attr "mode" "QI")])
8313
8314 ;; See comment above `ashldi3' about how this works.
8315
8316 (define_expand "ashrdi3"
8317 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8318 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8319 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8320 (clobber (reg:CC 17))])]
8321 ""
8322 "
8323 {
8324 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
8325 {
8326 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
8327 DONE;
8328 }
8329 }")
8330
8331 (define_insn "ashrdi3_1"
8332 [(set (match_operand:DI 0 "register_operand" "=r")
8333 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8334 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8335 (clobber (match_scratch:SI 3 "=&r"))
8336 (clobber (reg:CC 17))]
8337 "TARGET_CMOVE"
8338 "#"
8339 [(set_attr "type" "multi")])
8340
8341 (define_insn "*ashrdi3_2"
8342 [(set (match_operand:DI 0 "register_operand" "=r")
8343 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8344 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8345 (clobber (reg:CC 17))]
8346 ""
8347 "#"
8348 [(set_attr "type" "multi")])
8349
8350 (define_split
8351 [(set (match_operand:DI 0 "register_operand" "")
8352 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8353 (match_operand:QI 2 "nonmemory_operand" "")))
8354 (clobber (match_scratch:SI 3 ""))
8355 (clobber (reg:CC 17))]
8356 "TARGET_CMOVE && reload_completed"
8357 [(const_int 0)]
8358 "ix86_split_ashrdi (operands, operands[3]); DONE;")
8359
8360 (define_split
8361 [(set (match_operand:DI 0 "register_operand" "")
8362 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
8363 (match_operand:QI 2 "nonmemory_operand" "")))
8364 (clobber (reg:CC 17))]
8365 "reload_completed"
8366 [(const_int 0)]
8367 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
8368
8369 (define_insn "x86_shrd_1"
8370 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
8371 (ior:SI (ashiftrt:SI (match_dup 0)
8372 (match_operand:QI 2 "nonmemory_operand" "I,c"))
8373 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
8374 (minus:QI (const_int 32) (match_dup 2)))))
8375 (clobber (reg:CC 17))]
8376 ""
8377 "@
8378 shrd{l}\\t{%2, %1, %0|%0, %1, %2}
8379 shrd{l}\\t{%s2%1, %0|%0, %1, %2}"
8380 [(set_attr "type" "ishift")
8381 (set_attr "prefix_0f" "1")
8382 (set_attr "pent_pair" "np")
8383 (set_attr "ppro_uops" "few")
8384 (set_attr "mode" "SI")])
8385
8386 (define_expand "x86_shift_adj_3"
8387 [(use (match_operand:SI 0 "register_operand" ""))
8388 (use (match_operand:SI 1 "register_operand" ""))
8389 (use (match_operand:QI 2 "register_operand" ""))]
8390 ""
8391 "
8392 {
8393 rtx label = gen_label_rtx ();
8394 rtx tmp;
8395
8396 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
8397
8398 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8399 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8400 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8401 gen_rtx_LABEL_REF (VOIDmode, label),
8402 pc_rtx);
8403 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8404 JUMP_LABEL (tmp) = label;
8405
8406 emit_move_insn (operands[0], operands[1]);
8407 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
8408
8409 emit_label (label);
8410 LABEL_NUSES (label) = 1;
8411
8412 DONE;
8413 }")
8414
8415 (define_insn "ashrsi3_31"
8416 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
8417 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
8418 (match_operand:SI 2 "const_int_operand" "i,i")))
8419 (clobber (reg:CC 17))]
8420 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
8421 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8422 "@
8423 {cltd|cdq}
8424 sar{l}\\t{%2, %0|%0, %2}"
8425 [(set_attr "type" "imovx,ishift")
8426 (set_attr "prefix_0f" "0,*")
8427 (set_attr "length_immediate" "0,*")
8428 (set_attr "modrm" "0,1")
8429 (set_attr "mode" "SI")])
8430
8431 (define_expand "ashrsi3"
8432 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8433 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
8434 (match_operand:QI 2 "nonmemory_operand" "")))
8435 (clobber (reg:CC 17))]
8436 ""
8437 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
8438
8439 (define_insn "*ashrsi3_1_one_bit"
8440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8441 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8442 (match_operand:QI 2 "const_int_1_operand" "")))
8443 (clobber (reg:CC 17))]
8444 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
8445 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8446 "sar{l}\\t%0"
8447 [(set_attr "type" "ishift")
8448 (set (attr "length")
8449 (if_then_else (match_operand:SI 0 "register_operand" "")
8450 (const_string "2")
8451 (const_string "*")))])
8452
8453 (define_insn "*ashrsi3_1"
8454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8455 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8456 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8457 (clobber (reg:CC 17))]
8458 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8459 "@
8460 sar{l}\\t{%2, %0|%0, %2}
8461 sar{l}\\t{%b2, %0|%0, %b2}"
8462 [(set_attr "type" "ishift")
8463 (set_attr "mode" "SI")])
8464
8465 ;; This pattern can't accept a variable shift count, since shifts by
8466 ;; zero don't affect the flags. We assume that shifts by constant
8467 ;; zero are optimized away.
8468 (define_insn "*ashrsi3_one_bit_cmp"
8469 [(set (reg 17)
8470 (compare
8471 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8472 (match_operand:QI 2 "const_int_1_operand" ""))
8473 (const_int 0)))
8474 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8475 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
8476 "ix86_match_ccmode (insn, CCGOCmode)
8477 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8478 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8479 "sar{l}\\t%0"
8480 [(set_attr "type" "ishift")
8481 (set (attr "length")
8482 (if_then_else (match_operand:SI 0 "register_operand" "")
8483 (const_string "2")
8484 (const_string "*")))])
8485
8486 ;; This pattern can't accept a variable shift count, since shifts by
8487 ;; zero don't affect the flags. We assume that shifts by constant
8488 ;; zero are optimized away.
8489 (define_insn "*ashrsi3_cmp"
8490 [(set (reg 17)
8491 (compare
8492 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8493 (match_operand:QI 2 "immediate_operand" "I"))
8494 (const_int 0)))
8495 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8496 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
8497 "ix86_match_ccmode (insn, CCGOCmode)
8498 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
8499 "sar{l}\\t{%2, %0|%0, %2}"
8500 [(set_attr "type" "ishift")
8501 (set_attr "mode" "SI")])
8502
8503 (define_expand "ashrhi3"
8504 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8505 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
8506 (match_operand:QI 2 "nonmemory_operand" "")))
8507 (clobber (reg:CC 17))]
8508 "TARGET_HIMODE_MATH"
8509 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
8510
8511 (define_insn "*ashrhi3_1_one_bit"
8512 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8513 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8514 (match_operand:QI 2 "const_int_1_operand" "")))
8515 (clobber (reg:CC 17))]
8516 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
8517 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8518 "sar{w}\\t%0"
8519 [(set_attr "type" "ishift")
8520 (set (attr "length")
8521 (if_then_else (match_operand:SI 0 "register_operand" "")
8522 (const_string "2")
8523 (const_string "*")))])
8524
8525 (define_insn "*ashrhi3_1"
8526 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8527 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8528 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8529 (clobber (reg:CC 17))]
8530 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8531 "@
8532 sar{w}\\t{%2, %0|%0, %2}
8533 sar{w}\\t{%b2, %0|%0, %b2}"
8534 [(set_attr "type" "ishift")
8535 (set_attr "mode" "HI")])
8536
8537 ;; This pattern can't accept a variable shift count, since shifts by
8538 ;; zero don't affect the flags. We assume that shifts by constant
8539 ;; zero are optimized away.
8540 (define_insn "*ashrhi3_one_bit_cmp"
8541 [(set (reg 17)
8542 (compare
8543 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8544 (match_operand:QI 2 "const_int_1_operand" ""))
8545 (const_int 0)))
8546 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8547 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
8548 "ix86_match_ccmode (insn, CCGOCmode)
8549 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8550 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8551 "sar{w}\\t%0"
8552 [(set_attr "type" "ishift")
8553 (set (attr "length")
8554 (if_then_else (match_operand:SI 0 "register_operand" "")
8555 (const_string "2")
8556 (const_string "*")))])
8557
8558 ;; This pattern can't accept a variable shift count, since shifts by
8559 ;; zero don't affect the flags. We assume that shifts by constant
8560 ;; zero are optimized away.
8561 (define_insn "*ashrhi3_cmp"
8562 [(set (reg 17)
8563 (compare
8564 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8565 (match_operand:QI 2 "immediate_operand" "I"))
8566 (const_int 0)))
8567 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8568 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
8569 "ix86_match_ccmode (insn, CCGOCmode)
8570 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
8571 "sar{w}\\t{%2, %0|%0, %2}"
8572 [(set_attr "type" "ishift")
8573 (set_attr "mode" "HI")])
8574
8575 (define_expand "ashrqi3"
8576 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8577 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
8578 (match_operand:QI 2 "nonmemory_operand" "")))
8579 (clobber (reg:CC 17))]
8580 "TARGET_QIMODE_MATH"
8581 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
8582
8583 (define_insn "*ashrqi3_1_one_bit"
8584 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8585 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8586 (match_operand:QI 2 "const_int_1_operand" "")))
8587 (clobber (reg:CC 17))]
8588 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
8589 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8590 "sar{b}\\t%0"
8591 [(set_attr "type" "ishift")
8592 (set (attr "length")
8593 (if_then_else (match_operand:SI 0 "register_operand" "")
8594 (const_string "2")
8595 (const_string "*")))])
8596
8597 (define_insn "*ashrqi3_1"
8598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8599 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8600 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8601 (clobber (reg:CC 17))]
8602 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8603 "@
8604 sar{b}\\t{%2, %0|%0, %2}
8605 sar{b}\\t{%b2, %0|%0, %b2}"
8606 [(set_attr "type" "ishift")
8607 (set_attr "mode" "QI")])
8608
8609 ;; This pattern can't accept a variable shift count, since shifts by
8610 ;; zero don't affect the flags. We assume that shifts by constant
8611 ;; zero are optimized away.
8612 (define_insn "*ashrqi3_one_bit_cmp"
8613 [(set (reg 17)
8614 (compare
8615 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8616 (match_operand:QI 2 "const_int_1_operand" "I"))
8617 (const_int 0)))
8618 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8619 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
8620 "ix86_match_ccmode (insn, CCGOCmode)
8621 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8622 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8623 "sar{b}\\t%0"
8624 [(set_attr "type" "ishift")
8625 (set (attr "length")
8626 (if_then_else (match_operand:SI 0 "register_operand" "")
8627 (const_string "2")
8628 (const_string "*")))])
8629
8630 ;; This pattern can't accept a variable shift count, since shifts by
8631 ;; zero don't affect the flags. We assume that shifts by constant
8632 ;; zero are optimized away.
8633 (define_insn "*ashrqi3_cmp"
8634 [(set (reg 17)
8635 (compare
8636 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8637 (match_operand:QI 2 "immediate_operand" "I"))
8638 (const_int 0)))
8639 (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
8640 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
8641 "ix86_match_ccmode (insn, CCGOCmode)
8642 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
8643 "sar{b}\\t{%2, %0|%0, %2}"
8644 [(set_attr "type" "ishift")
8645 (set_attr "mode" "QI")])
8646 \f
8647 ;; Logical shift instructions
8648
8649 ;; See comment above `ashldi3' about how this works.
8650
8651 (define_expand "lshrdi3"
8652 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
8653 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8654 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8655 (clobber (reg:CC 17))])]
8656 ""
8657 "
8658 {
8659 if (TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
8660 {
8661 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
8662 DONE;
8663 }
8664 }")
8665
8666 (define_insn "lshrdi3_1"
8667 [(set (match_operand:DI 0 "register_operand" "=r")
8668 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8669 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8670 (clobber (match_scratch:SI 3 "=&r"))
8671 (clobber (reg:CC 17))]
8672 "TARGET_CMOVE"
8673 "#"
8674 [(set_attr "type" "multi")])
8675
8676 (define_insn "*lshrdi3_2"
8677 [(set (match_operand:DI 0 "register_operand" "=r")
8678 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
8679 (match_operand:QI 2 "nonmemory_operand" "Jc")))
8680 (clobber (reg:CC 17))]
8681 ""
8682 "#"
8683 [(set_attr "type" "multi")])
8684
8685 (define_split
8686 [(set (match_operand:DI 0 "register_operand" "")
8687 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8688 (match_operand:QI 2 "nonmemory_operand" "")))
8689 (clobber (match_scratch:SI 3 ""))
8690 (clobber (reg:CC 17))]
8691 "TARGET_CMOVE && reload_completed"
8692 [(const_int 0)]
8693 "ix86_split_lshrdi (operands, operands[3]); DONE;")
8694
8695 (define_split
8696 [(set (match_operand:DI 0 "register_operand" "")
8697 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
8698 (match_operand:QI 2 "nonmemory_operand" "")))
8699 (clobber (reg:CC 17))]
8700 "reload_completed"
8701 [(const_int 0)]
8702 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
8703
8704 (define_expand "lshrsi3"
8705 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8706 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
8707 (match_operand:QI 2 "nonmemory_operand" "")))
8708 (clobber (reg:CC 17))]
8709 ""
8710 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
8711
8712 (define_insn "*lshrsi3_1_one_bit"
8713 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8714 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8715 (match_operand:QI 2 "const_int_1_operand" "")))
8716 (clobber (reg:CC 17))]
8717 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
8718 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8719 "shr{l}\\t%0"
8720 [(set_attr "type" "ishift")
8721 (set (attr "length")
8722 (if_then_else (match_operand:SI 0 "register_operand" "")
8723 (const_string "2")
8724 (const_string "*")))])
8725
8726 (define_insn "*lshrsi3_1"
8727 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8728 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8729 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8730 (clobber (reg:CC 17))]
8731 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8732 "@
8733 shr{l}\\t{%2, %0|%0, %2}
8734 shr{l}\\t{%b2, %0|%0, %b2}"
8735 [(set_attr "type" "ishift")
8736 (set_attr "mode" "SI")])
8737
8738 ;; This pattern can't accept a variable shift count, since shifts by
8739 ;; zero don't affect the flags. We assume that shifts by constant
8740 ;; zero are optimized away.
8741 (define_insn "*lshrsi3_one_bit_cmp"
8742 [(set (reg 17)
8743 (compare
8744 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8745 (match_operand:QI 2 "const_int_1_operand" ""))
8746 (const_int 0)))
8747 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8748 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
8749 "ix86_match_ccmode (insn, CCGOCmode)
8750 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8751 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8752 "shr{l}\\t%0"
8753 [(set_attr "type" "ishift")
8754 (set (attr "length")
8755 (if_then_else (match_operand:SI 0 "register_operand" "")
8756 (const_string "2")
8757 (const_string "*")))])
8758
8759 ;; This pattern can't accept a variable shift count, since shifts by
8760 ;; zero don't affect the flags. We assume that shifts by constant
8761 ;; zero are optimized away.
8762 (define_insn "*lshrsi3_cmp"
8763 [(set (reg 17)
8764 (compare
8765 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8766 (match_operand:QI 2 "immediate_operand" "I"))
8767 (const_int 0)))
8768 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8769 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
8770 "ix86_match_ccmode (insn, CCGOCmode)
8771 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8772 "shr{l}\\t{%2, %0|%0, %2}"
8773 [(set_attr "type" "ishift")
8774 (set_attr "mode" "SI")])
8775
8776 (define_expand "lshrhi3"
8777 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8778 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
8779 (match_operand:QI 2 "nonmemory_operand" "")))
8780 (clobber (reg:CC 17))]
8781 "TARGET_HIMODE_MATH"
8782 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
8783
8784 (define_insn "*lshrhi3_1_one_bit"
8785 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8786 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8787 (match_operand:QI 2 "const_int_1_operand" "")))
8788 (clobber (reg:CC 17))]
8789 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
8790 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8791 "shr{w}\\t%0"
8792 [(set_attr "type" "ishift")
8793 (set (attr "length")
8794 (if_then_else (match_operand:SI 0 "register_operand" "")
8795 (const_string "2")
8796 (const_string "*")))])
8797
8798 (define_insn "*lshrhi3_1"
8799 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8800 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8801 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8802 (clobber (reg:CC 17))]
8803 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8804 "@
8805 shr{w}\\t{%2, %0|%0, %2}
8806 shr{w}\\t{%b2, %0|%0, %b2}"
8807 [(set_attr "type" "ishift")
8808 (set_attr "mode" "HI")])
8809
8810 ;; This pattern can't accept a variable shift count, since shifts by
8811 ;; zero don't affect the flags. We assume that shifts by constant
8812 ;; zero are optimized away.
8813 (define_insn "*lshrhi3_one_bit_cmp"
8814 [(set (reg 17)
8815 (compare
8816 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8817 (match_operand:QI 2 "const_int_1_operand" ""))
8818 (const_int 0)))
8819 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8820 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
8821 "ix86_match_ccmode (insn, CCGOCmode)
8822 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8823 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8824 "shr{w}\\t%0"
8825 [(set_attr "type" "ishift")
8826 (set (attr "length")
8827 (if_then_else (match_operand:SI 0 "register_operand" "")
8828 (const_string "2")
8829 (const_string "*")))])
8830
8831 ;; This pattern can't accept a variable shift count, since shifts by
8832 ;; zero don't affect the flags. We assume that shifts by constant
8833 ;; zero are optimized away.
8834 (define_insn "*lshrhi3_cmp"
8835 [(set (reg 17)
8836 (compare
8837 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8838 (match_operand:QI 2 "immediate_operand" "I"))
8839 (const_int 0)))
8840 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8841 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
8842 "ix86_match_ccmode (insn, CCGOCmode)
8843 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
8844 "shr{w}\\t{%2, %0|%0, %2}"
8845 [(set_attr "type" "ishift")
8846 (set_attr "mode" "HI")])
8847
8848 (define_expand "lshrqi3"
8849 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8850 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
8851 (match_operand:QI 2 "nonmemory_operand" "")))
8852 (clobber (reg:CC 17))]
8853 "TARGET_QIMODE_MATH"
8854 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
8855
8856 (define_insn "*lshrqi3_1_one_bit"
8857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8858 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8859 (match_operand:QI 2 "const_int_1_operand" "")))
8860 (clobber (reg:CC 17))]
8861 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
8862 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8863 "shr{b}\\t%0"
8864 [(set_attr "type" "ishift")
8865 (set (attr "length")
8866 (if_then_else (match_operand:SI 0 "register_operand" "")
8867 (const_string "2")
8868 (const_string "*")))])
8869
8870 (define_insn "*lshrqi3_1"
8871 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
8872 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8873 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8874 (clobber (reg:CC 17))]
8875 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8876 "@
8877 shr{b}\\t{%2, %0|%0, %2}
8878 shr{b}\\t{%b2, %0|%0, %b2}"
8879 [(set_attr "type" "ishift")
8880 (set_attr "mode" "QI")])
8881
8882 ;; This pattern can't accept a variable shift count, since shifts by
8883 ;; zero don't affect the flags. We assume that shifts by constant
8884 ;; zero are optimized away.
8885 (define_insn "*lshrqi2_one_bit_cmp"
8886 [(set (reg 17)
8887 (compare
8888 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8889 (match_operand:QI 2 "const_int_1_operand" ""))
8890 (const_int 0)))
8891 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8892 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
8893 "ix86_match_ccmode (insn, CCGOCmode)
8894 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
8895 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8896 "shr{b}\\t%0"
8897 [(set_attr "type" "ishift")
8898 (set (attr "length")
8899 (if_then_else (match_operand:SI 0 "register_operand" "")
8900 (const_string "2")
8901 (const_string "*")))])
8902
8903 ;; This pattern can't accept a variable shift count, since shifts by
8904 ;; zero don't affect the flags. We assume that shifts by constant
8905 ;; zero are optimized away.
8906 (define_insn "*lshrqi2_cmp"
8907 [(set (reg 17)
8908 (compare
8909 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
8910 (match_operand:QI 2 "immediate_operand" "I"))
8911 (const_int 0)))
8912 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
8913 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
8914 "ix86_match_ccmode (insn, CCGOCmode)
8915 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
8916 "shr{b}\\t{%2, %0|%0, %2}"
8917 [(set_attr "type" "ishift")
8918 (set_attr "mode" "QI")])
8919 \f
8920 ;; Rotate instructions
8921
8922 (define_expand "rotlsi3"
8923 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8924 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
8925 (match_operand:QI 2 "nonmemory_operand" "")))
8926 (clobber (reg:CC 17))]
8927 ""
8928 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
8929
8930 (define_insn "*rotlsi3_1_one_bit"
8931 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8932 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
8933 (match_operand:QI 2 "const_int_1_operand" "")))
8934 (clobber (reg:CC 17))]
8935 "ix86_binary_operator_ok (ROTATE, SImode, operands)
8936 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8937 "rol{l}\\t%0"
8938 [(set_attr "type" "ishift")
8939 (set (attr "length")
8940 (if_then_else (match_operand:SI 0 "register_operand" "")
8941 (const_string "2")
8942 (const_string "*")))])
8943
8944 (define_insn "*rotlsi3_1"
8945 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8946 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8947 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8948 (clobber (reg:CC 17))]
8949 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
8950 "@
8951 rol{l}\\t{%2, %0|%0, %2}
8952 rol{l}\\t{%b2, %0|%0, %b2}"
8953 [(set_attr "type" "ishift")
8954 (set_attr "mode" "SI")])
8955
8956 (define_expand "rotlhi3"
8957 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8958 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
8959 (match_operand:QI 2 "nonmemory_operand" "")))
8960 (clobber (reg:CC 17))]
8961 "TARGET_HIMODE_MATH"
8962 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
8963
8964 (define_insn "*rotlhi3_1_one_bit"
8965 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
8966 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
8967 (match_operand:QI 2 "const_int_1_operand" "")))
8968 (clobber (reg:CC 17))]
8969 "ix86_binary_operator_ok (ROTATE, HImode, operands)
8970 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
8971 "rol{w}\\t%0"
8972 [(set_attr "type" "ishift")
8973 (set (attr "length")
8974 (if_then_else (match_operand:SI 0 "register_operand" "")
8975 (const_string "2")
8976 (const_string "*")))])
8977
8978 (define_insn "*rotlhi3_1"
8979 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
8980 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8981 (match_operand:QI 2 "nonmemory_operand" "I,c")))
8982 (clobber (reg:CC 17))]
8983 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
8984 "@
8985 rol{w}\\t{%2, %0|%0, %2}
8986 rol{w}\\t{%b2, %0|%0, %b2}"
8987 [(set_attr "type" "ishift")
8988 (set_attr "mode" "HI")])
8989
8990 (define_expand "rotlqi3"
8991 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8992 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
8993 (match_operand:QI 2 "nonmemory_operand" "")))
8994 (clobber (reg:CC 17))]
8995 "TARGET_QIMODE_MATH"
8996 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
8997
8998 (define_insn "*rotlqi3_1_one_bit"
8999 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9000 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9001 (match_operand:QI 2 "const_int_1_operand" "")))
9002 (clobber (reg:CC 17))]
9003 "ix86_binary_operator_ok (ROTATE, QImode, operands)
9004 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9005 "rol{b}\\t%0"
9006 [(set_attr "type" "ishift")
9007 (set (attr "length")
9008 (if_then_else (match_operand:SI 0 "register_operand" "")
9009 (const_string "2")
9010 (const_string "*")))])
9011
9012 (define_insn "*rotlqi3_1"
9013 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9014 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9015 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9016 (clobber (reg:CC 17))]
9017 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
9018 "@
9019 rol{b}\\t{%2, %0|%0, %2}
9020 rol{b}\\t{%b2, %0|%0, %b2}"
9021 [(set_attr "type" "ishift")
9022 (set_attr "mode" "QI")])
9023
9024 (define_expand "rotrsi3"
9025 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9026 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
9027 (match_operand:QI 2 "nonmemory_operand" "")))
9028 (clobber (reg:CC 17))]
9029 ""
9030 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
9031
9032 (define_insn "*rotrsi3_1_one_bit"
9033 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9034 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
9035 (match_operand:QI 2 "const_int_1_operand" "")))
9036 (clobber (reg:CC 17))]
9037 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
9038 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9039 "ror{l}\\t%0"
9040 [(set_attr "type" "ishift")
9041 (set (attr "length")
9042 (if_then_else (match_operand:SI 0 "register_operand" "")
9043 (const_string "2")
9044 (const_string "*")))])
9045
9046 (define_insn "*rotrsi3_1"
9047 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
9048 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
9049 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9050 (clobber (reg:CC 17))]
9051 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
9052 "@
9053 ror{l}\\t{%2, %0|%0, %2}
9054 ror{l}\\t{%b2, %0|%0, %b2}"
9055 [(set_attr "type" "ishift")
9056 (set_attr "mode" "SI")])
9057
9058 (define_expand "rotrhi3"
9059 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9060 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
9061 (match_operand:QI 2 "nonmemory_operand" "")))
9062 (clobber (reg:CC 17))]
9063 "TARGET_HIMODE_MATH"
9064 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
9065
9066 (define_insn "*rotrhi3_one_bit"
9067 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9068 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9069 (match_operand:QI 2 "const_int_1_operand" "")))
9070 (clobber (reg:CC 17))]
9071 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
9072 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9073 "ror{w}\\t%0"
9074 [(set_attr "type" "ishift")
9075 (set (attr "length")
9076 (if_then_else (match_operand:SI 0 "register_operand" "")
9077 (const_string "2")
9078 (const_string "*")))])
9079
9080 (define_insn "*rotrhi3"
9081 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
9082 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
9083 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9084 (clobber (reg:CC 17))]
9085 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
9086 "@
9087 ror{w}\\t{%2, %0|%0, %2}
9088 ror{w}\\t{%b2, %0|%0, %b2}"
9089 [(set_attr "type" "ishift")
9090 (set_attr "mode" "HI")])
9091
9092 (define_expand "rotrqi3"
9093 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9094 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
9095 (match_operand:QI 2 "nonmemory_operand" "")))
9096 (clobber (reg:CC 17))]
9097 "TARGET_QIMODE_MATH"
9098 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
9099
9100 (define_insn "*rotrqi3_1_one_bit"
9101 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9102 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
9103 (match_operand:QI 2 "const_int_1_operand" "")))
9104 (clobber (reg:CC 17))]
9105 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
9106 && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
9107 "ror{b}\\t%0"
9108 [(set_attr "type" "ishift")
9109 (set (attr "length")
9110 (if_then_else (match_operand:SI 0 "register_operand" "")
9111 (const_string "2")
9112 (const_string "*")))])
9113
9114 (define_insn "*rotrqi3_1"
9115 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
9116 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9117 (match_operand:QI 2 "nonmemory_operand" "I,c")))
9118 (clobber (reg:CC 17))]
9119 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
9120 "@
9121 ror{b}\\t{%2, %0|%0, %2}
9122 ror{b}\\t{%b2, %0|%0, %b2}"
9123 [(set_attr "type" "ishift")
9124 (set_attr "mode" "QI")])
9125 \f
9126 ;; Bit set / bit test instructions
9127
9128 (define_expand "extv"
9129 [(set (match_operand:SI 0 "register_operand" "")
9130 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
9131 (match_operand:SI 2 "immediate_operand" "")
9132 (match_operand:SI 3 "immediate_operand" "")))]
9133 ""
9134 "
9135 {
9136 /* Handle extractions from %ah et al. */
9137 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9138 FAIL;
9139
9140 /* From mips.md: extract_bit_field doesn't verify that our source
9141 matches the predicate, so check it again here. */
9142 if (! register_operand (operands[1], VOIDmode))
9143 FAIL;
9144 }")
9145
9146 (define_expand "extzv"
9147 [(set (match_operand:SI 0 "register_operand" "")
9148 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
9149 (match_operand:SI 2 "immediate_operand" "")
9150 (match_operand:SI 3 "immediate_operand" "")))]
9151 ""
9152 "
9153 {
9154 /* Handle extractions from %ah et al. */
9155 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9156 FAIL;
9157
9158 /* From mips.md: extract_bit_field doesn't verify that our source
9159 matches the predicate, so check it again here. */
9160 if (! register_operand (operands[1], VOIDmode))
9161 FAIL;
9162 }")
9163
9164 (define_expand "insv"
9165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9166 (match_operand:SI 1 "immediate_operand" "")
9167 (match_operand:SI 2 "immediate_operand" ""))
9168 (match_operand:SI 3 "register_operand" ""))]
9169 ""
9170 "
9171 {
9172 /* Handle extractions from %ah et al. */
9173 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
9174 FAIL;
9175
9176 /* From mips.md: insert_bit_field doesn't verify that our source
9177 matches the predicate, so check it again here. */
9178 if (! register_operand (operands[0], VOIDmode))
9179 FAIL;
9180 }")
9181
9182 ;; %%% bts, btr, btc, bt.
9183 \f
9184 ;; Store-flag instructions.
9185
9186 ;; For all sCOND expanders, also expand the compare or test insn that
9187 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
9188
9189 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
9190 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
9191 ;; way, which can later delete the movzx if only QImode is needed.
9192
9193 (define_expand "seq"
9194 [(set (match_operand:SI 0 "register_operand" "")
9195 (eq:SI (reg:CC 17) (const_int 0)))]
9196 ""
9197 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
9198
9199 (define_expand "sne"
9200 [(set (match_operand:SI 0 "register_operand" "")
9201 (ne:SI (reg:CC 17) (const_int 0)))]
9202 ""
9203 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
9204
9205 (define_expand "sgt"
9206 [(set (match_operand:SI 0 "register_operand" "")
9207 (gt:SI (reg:CC 17) (const_int 0)))]
9208 ""
9209 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
9210
9211 (define_expand "sgtu"
9212 [(set (match_operand:SI 0 "register_operand" "")
9213 (gtu:SI (reg:CC 17) (const_int 0)))]
9214 ""
9215 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
9216
9217 (define_expand "slt"
9218 [(set (match_operand:SI 0 "register_operand" "")
9219 (lt:SI (reg:CC 17) (const_int 0)))]
9220 ""
9221 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
9222
9223 (define_expand "sltu"
9224 [(set (match_operand:SI 0 "register_operand" "")
9225 (ltu:SI (reg:CC 17) (const_int 0)))]
9226 ""
9227 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
9228
9229 (define_expand "sge"
9230 [(set (match_operand:SI 0 "register_operand" "")
9231 (ge:SI (reg:CC 17) (const_int 0)))]
9232 ""
9233 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
9234
9235 (define_expand "sgeu"
9236 [(set (match_operand:SI 0 "register_operand" "")
9237 (geu:SI (reg:CC 17) (const_int 0)))]
9238 ""
9239 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
9240
9241 (define_expand "sle"
9242 [(set (match_operand:SI 0 "register_operand" "")
9243 (le:SI (reg:CC 17) (const_int 0)))]
9244 ""
9245 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
9246
9247 (define_expand "sleu"
9248 [(set (match_operand:SI 0 "register_operand" "")
9249 (leu:SI (reg:CC 17) (const_int 0)))]
9250 ""
9251 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
9252
9253 (define_expand "sunordered"
9254 [(set (match_operand:SI 0 "register_operand" "")
9255 (unordered:SI (reg:CC 17) (const_int 0)))]
9256 "TARGET_80387 || TARGET_SSE"
9257 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
9258
9259 (define_expand "sordered"
9260 [(set (match_operand:SI 0 "register_operand" "")
9261 (ordered:SI (reg:CC 17) (const_int 0)))]
9262 "TARGET_80387"
9263 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
9264
9265 (define_expand "suneq"
9266 [(set (match_operand:SI 0 "register_operand" "")
9267 (uneq:SI (reg:CC 17) (const_int 0)))]
9268 "TARGET_80387 || TARGET_SSE"
9269 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
9270
9271 (define_expand "sunge"
9272 [(set (match_operand:SI 0 "register_operand" "")
9273 (unge:SI (reg:CC 17) (const_int 0)))]
9274 "TARGET_80387 || TARGET_SSE"
9275 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
9276
9277 (define_expand "sungt"
9278 [(set (match_operand:SI 0 "register_operand" "")
9279 (ungt:SI (reg:CC 17) (const_int 0)))]
9280 "TARGET_80387 || TARGET_SSE"
9281 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
9282
9283 (define_expand "sunle"
9284 [(set (match_operand:SI 0 "register_operand" "")
9285 (unle:SI (reg:CC 17) (const_int 0)))]
9286 "TARGET_80387 || TARGET_SSE"
9287 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
9288
9289 (define_expand "sunlt"
9290 [(set (match_operand:SI 0 "register_operand" "")
9291 (unlt:SI (reg:CC 17) (const_int 0)))]
9292 "TARGET_80387 || TARGET_SSE"
9293 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
9294
9295 (define_expand "sltgt"
9296 [(set (match_operand:SI 0 "register_operand" "")
9297 (ltgt:SI (reg:CC 17) (const_int 0)))]
9298 "TARGET_80387 || TARGET_SSE"
9299 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
9300
9301 (define_insn "*setcc_1"
9302 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9303 (match_operator:QI 1 "ix86_comparison_operator"
9304 [(reg 17) (const_int 0)]))]
9305 ""
9306 "set%C1\\t%0"
9307 [(set_attr "type" "setcc")
9308 (set_attr "mode" "QI")])
9309
9310 (define_insn "setcc_2"
9311 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9312 (match_operator:QI 1 "ix86_comparison_operator"
9313 [(reg 17) (const_int 0)]))]
9314 ""
9315 "set%C1\\t%0"
9316 [(set_attr "type" "setcc")
9317 (set_attr "mode" "QI")])
9318
9319 \f
9320 ;; Basic conditional jump instructions.
9321 ;; We ignore the overflow flag for signed branch instructions.
9322
9323 ;; For all bCOND expanders, also expand the compare or test insn that
9324 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
9325
9326 (define_expand "beq"
9327 [(set (pc)
9328 (if_then_else (match_dup 1)
9329 (label_ref (match_operand 0 "" ""))
9330 (pc)))]
9331 ""
9332 "ix86_expand_branch (EQ, operands[0]); DONE;")
9333
9334 (define_expand "bne"
9335 [(set (pc)
9336 (if_then_else (match_dup 1)
9337 (label_ref (match_operand 0 "" ""))
9338 (pc)))]
9339 ""
9340 "ix86_expand_branch (NE, operands[0]); DONE;")
9341
9342 (define_expand "bgt"
9343 [(set (pc)
9344 (if_then_else (match_dup 1)
9345 (label_ref (match_operand 0 "" ""))
9346 (pc)))]
9347 ""
9348 "ix86_expand_branch (GT, operands[0]); DONE;")
9349
9350 (define_expand "bgtu"
9351 [(set (pc)
9352 (if_then_else (match_dup 1)
9353 (label_ref (match_operand 0 "" ""))
9354 (pc)))]
9355 ""
9356 "ix86_expand_branch (GTU, operands[0]); DONE;")
9357
9358 (define_expand "blt"
9359 [(set (pc)
9360 (if_then_else (match_dup 1)
9361 (label_ref (match_operand 0 "" ""))
9362 (pc)))]
9363 ""
9364 "ix86_expand_branch (LT, operands[0]); DONE;")
9365
9366 (define_expand "bltu"
9367 [(set (pc)
9368 (if_then_else (match_dup 1)
9369 (label_ref (match_operand 0 "" ""))
9370 (pc)))]
9371 ""
9372 "ix86_expand_branch (LTU, operands[0]); DONE;")
9373
9374 (define_expand "bge"
9375 [(set (pc)
9376 (if_then_else (match_dup 1)
9377 (label_ref (match_operand 0 "" ""))
9378 (pc)))]
9379 ""
9380 "ix86_expand_branch (GE, operands[0]); DONE;")
9381
9382 (define_expand "bgeu"
9383 [(set (pc)
9384 (if_then_else (match_dup 1)
9385 (label_ref (match_operand 0 "" ""))
9386 (pc)))]
9387 ""
9388 "ix86_expand_branch (GEU, operands[0]); DONE;")
9389
9390 (define_expand "ble"
9391 [(set (pc)
9392 (if_then_else (match_dup 1)
9393 (label_ref (match_operand 0 "" ""))
9394 (pc)))]
9395 ""
9396 "ix86_expand_branch (LE, operands[0]); DONE;")
9397
9398 (define_expand "bleu"
9399 [(set (pc)
9400 (if_then_else (match_dup 1)
9401 (label_ref (match_operand 0 "" ""))
9402 (pc)))]
9403 ""
9404 "ix86_expand_branch (LEU, operands[0]); DONE;")
9405
9406 (define_expand "bunordered"
9407 [(set (pc)
9408 (if_then_else (match_dup 1)
9409 (label_ref (match_operand 0 "" ""))
9410 (pc)))]
9411 "TARGET_80387 || TARGET_SSE"
9412 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
9413
9414 (define_expand "bordered"
9415 [(set (pc)
9416 (if_then_else (match_dup 1)
9417 (label_ref (match_operand 0 "" ""))
9418 (pc)))]
9419 "TARGET_80387 || TARGET_SSE"
9420 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
9421
9422 (define_expand "buneq"
9423 [(set (pc)
9424 (if_then_else (match_dup 1)
9425 (label_ref (match_operand 0 "" ""))
9426 (pc)))]
9427 "TARGET_80387 || TARGET_SSE"
9428 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
9429
9430 (define_expand "bunge"
9431 [(set (pc)
9432 (if_then_else (match_dup 1)
9433 (label_ref (match_operand 0 "" ""))
9434 (pc)))]
9435 "TARGET_80387 || TARGET_SSE"
9436 "ix86_expand_branch (UNGE, operands[0]); DONE;")
9437
9438 (define_expand "bungt"
9439 [(set (pc)
9440 (if_then_else (match_dup 1)
9441 (label_ref (match_operand 0 "" ""))
9442 (pc)))]
9443 "TARGET_80387 || TARGET_SSE"
9444 "ix86_expand_branch (UNGT, operands[0]); DONE;")
9445
9446 (define_expand "bunle"
9447 [(set (pc)
9448 (if_then_else (match_dup 1)
9449 (label_ref (match_operand 0 "" ""))
9450 (pc)))]
9451 "TARGET_80387 || TARGET_SSE"
9452 "ix86_expand_branch (UNLE, operands[0]); DONE;")
9453
9454 (define_expand "bunlt"
9455 [(set (pc)
9456 (if_then_else (match_dup 1)
9457 (label_ref (match_operand 0 "" ""))
9458 (pc)))]
9459 "TARGET_80387 || TARGET_SSE"
9460 "ix86_expand_branch (UNLT, operands[0]); DONE;")
9461
9462 (define_expand "bltgt"
9463 [(set (pc)
9464 (if_then_else (match_dup 1)
9465 (label_ref (match_operand 0 "" ""))
9466 (pc)))]
9467 "TARGET_80387 || TARGET_SSE"
9468 "ix86_expand_branch (LTGT, operands[0]); DONE;")
9469
9470 (define_insn "*jcc_1"
9471 [(set (pc)
9472 (if_then_else (match_operator 1 "ix86_comparison_operator"
9473 [(reg 17) (const_int 0)])
9474 (label_ref (match_operand 0 "" ""))
9475 (pc)))]
9476 ""
9477 "j%C1\\t%l0"
9478 [(set_attr "type" "ibr")
9479 (set (attr "prefix_0f")
9480 (if_then_else (and (ge (minus (match_dup 0) (pc))
9481 (const_int -128))
9482 (lt (minus (match_dup 0) (pc))
9483 (const_int 124)))
9484 (const_int 0)
9485 (const_int 1)))])
9486
9487 (define_insn "*jcc_2"
9488 [(set (pc)
9489 (if_then_else (match_operator 1 "ix86_comparison_operator"
9490 [(reg 17) (const_int 0)])
9491 (pc)
9492 (label_ref (match_operand 0 "" ""))))]
9493 ""
9494 "j%c1\\t%l0"
9495 [(set_attr "type" "ibr")
9496 (set (attr "prefix_0f")
9497 (if_then_else (and (ge (minus (match_dup 0) (pc))
9498 (const_int -128))
9499 (lt (minus (match_dup 0) (pc))
9500 (const_int 124)))
9501 (const_int 0)
9502 (const_int 1)))])
9503
9504 ;; Define combination compare-and-branch fp compare instructions to use
9505 ;; during early optimization. Splitting the operation apart early makes
9506 ;; for bad code when we want to reverse the operation.
9507
9508 (define_insn "*fp_jcc_1"
9509 [(set (pc)
9510 (if_then_else (match_operator 0 "comparison_operator"
9511 [(match_operand 1 "register_operand" "f")
9512 (match_operand 2 "register_operand" "f")])
9513 (label_ref (match_operand 3 "" ""))
9514 (pc)))
9515 (clobber (reg:CCFP 18))
9516 (clobber (reg:CCFP 17))]
9517 "TARGET_CMOVE && TARGET_80387
9518 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9519 && FLOAT_MODE_P (GET_MODE (operands[1]))
9520 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9521 "#")
9522
9523 (define_insn "*fp_jcc_1_sse"
9524 [(set (pc)
9525 (if_then_else (match_operator 0 "comparison_operator"
9526 [(match_operand 1 "register_operand" "f#x,x#f")
9527 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
9528 (label_ref (match_operand 3 "" ""))
9529 (pc)))
9530 (clobber (reg:CCFP 18))
9531 (clobber (reg:CCFP 17))]
9532 "TARGET_80387
9533 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9534 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9535 "#")
9536
9537 (define_insn "*fp_jcc_1_sse_only"
9538 [(set (pc)
9539 (if_then_else (match_operator 0 "comparison_operator"
9540 [(match_operand 1 "register_operand" "x")
9541 (match_operand 2 "nonimmediate_operand" "xm")])
9542 (label_ref (match_operand 3 "" ""))
9543 (pc)))
9544 (clobber (reg:CCFP 18))
9545 (clobber (reg:CCFP 17))]
9546 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9547 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9548 "#")
9549
9550 (define_insn "*fp_jcc_2"
9551 [(set (pc)
9552 (if_then_else (match_operator 0 "comparison_operator"
9553 [(match_operand 1 "register_operand" "f")
9554 (match_operand 2 "register_operand" "f")])
9555 (pc)
9556 (label_ref (match_operand 3 "" ""))))
9557 (clobber (reg:CCFP 18))
9558 (clobber (reg:CCFP 17))]
9559 "TARGET_CMOVE && TARGET_80387
9560 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9561 && FLOAT_MODE_P (GET_MODE (operands[1]))
9562 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9563 "#")
9564
9565 (define_insn "*fp_jcc_2_sse"
9566 [(set (pc)
9567 (if_then_else (match_operator 0 "comparison_operator"
9568 [(match_operand 1 "register_operand" "f#x,x#f")
9569 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
9570 (pc)
9571 (label_ref (match_operand 3 "" ""))))
9572 (clobber (reg:CCFP 18))
9573 (clobber (reg:CCFP 17))]
9574 "TARGET_80387
9575 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9576 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9577 "#")
9578
9579 (define_insn "*fp_jcc_2_sse_only"
9580 [(set (pc)
9581 (if_then_else (match_operator 0 "comparison_operator"
9582 [(match_operand 1 "register_operand" "x")
9583 (match_operand 2 "nonimmediate_operand" "xm")])
9584 (pc)
9585 (label_ref (match_operand 3 "" ""))))
9586 (clobber (reg:CCFP 18))
9587 (clobber (reg:CCFP 17))]
9588 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
9589 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9590 "#")
9591
9592 (define_insn "*fp_jcc_3"
9593 [(set (pc)
9594 (if_then_else (match_operator 0 "comparison_operator"
9595 [(match_operand 1 "register_operand" "f")
9596 (match_operand 2 "nonimmediate_operand" "fm")])
9597 (label_ref (match_operand 3 "" ""))
9598 (pc)))
9599 (clobber (reg:CCFP 18))
9600 (clobber (reg:CCFP 17))
9601 (clobber (match_scratch:HI 4 "=a"))]
9602 "TARGET_80387
9603 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
9604 && GET_MODE (operands[1]) == GET_MODE (operands[2])
9605 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9606 && SELECT_CC_MODE (GET_CODE (operands[0]),
9607 operands[1], operands[2]) == CCFPmode"
9608 "#")
9609
9610 (define_insn "*fp_jcc_4"
9611 [(set (pc)
9612 (if_then_else (match_operator 0 "comparison_operator"
9613 [(match_operand 1 "register_operand" "f")
9614 (match_operand 2 "nonimmediate_operand" "fm")])
9615 (pc)
9616 (label_ref (match_operand 3 "" ""))))
9617 (clobber (reg:CCFP 18))
9618 (clobber (reg:CCFP 17))
9619 (clobber (match_scratch:HI 4 "=a"))]
9620 "TARGET_80387
9621 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
9622 && GET_MODE (operands[1]) == GET_MODE (operands[2])
9623 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
9624 && SELECT_CC_MODE (GET_CODE (operands[0]),
9625 operands[1], operands[2]) == CCFPmode"
9626 "#")
9627
9628 (define_insn "*fp_jcc_5"
9629 [(set (pc)
9630 (if_then_else (match_operator 0 "comparison_operator"
9631 [(match_operand 1 "register_operand" "f")
9632 (match_operand 2 "register_operand" "f")])
9633 (label_ref (match_operand 3 "" ""))
9634 (pc)))
9635 (clobber (reg:CCFP 18))
9636 (clobber (reg:CCFP 17))
9637 (clobber (match_scratch:HI 4 "=a"))]
9638 "TARGET_80387
9639 && FLOAT_MODE_P (GET_MODE (operands[1]))
9640 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9641 "#")
9642
9643 (define_insn "*fp_jcc_6"
9644 [(set (pc)
9645 (if_then_else (match_operator 0 "comparison_operator"
9646 [(match_operand 1 "register_operand" "f")
9647 (match_operand 2 "register_operand" "f")])
9648 (pc)
9649 (label_ref (match_operand 3 "" ""))))
9650 (clobber (reg:CCFP 18))
9651 (clobber (reg:CCFP 17))
9652 (clobber (match_scratch:HI 4 "=a"))]
9653 "TARGET_80387
9654 && FLOAT_MODE_P (GET_MODE (operands[1]))
9655 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
9656 "#")
9657
9658 (define_split
9659 [(set (pc)
9660 (if_then_else (match_operator 0 "comparison_operator"
9661 [(match_operand 1 "register_operand" "")
9662 (match_operand 2 "nonimmediate_operand" "")])
9663 (match_operand 3 "" "")
9664 (match_operand 4 "" "")))
9665 (clobber (reg:CCFP 18))
9666 (clobber (reg:CCFP 17))]
9667 "reload_completed"
9668 [(const_int 0)]
9669 "
9670 {
9671 ix86_split_fp_branch (operands[0], operands[1], operands[2],
9672 operands[3], operands[4], NULL_RTX);
9673 DONE;
9674 }")
9675
9676 (define_split
9677 [(set (pc)
9678 (if_then_else (match_operator 0 "comparison_operator"
9679 [(match_operand 1 "register_operand" "")
9680 (match_operand 2 "nonimmediate_operand" "")])
9681 (match_operand 3 "" "")
9682 (match_operand 4 "" "")))
9683 (clobber (reg:CCFP 18))
9684 (clobber (reg:CCFP 17))
9685 (clobber (match_scratch:HI 5 "=a"))]
9686 "reload_completed"
9687 [(set (pc)
9688 (if_then_else (match_dup 6)
9689 (match_dup 3)
9690 (match_dup 4)))]
9691 "
9692 {
9693 ix86_split_fp_branch (operands[0], operands[1], operands[2],
9694 operands[3], operands[4], operands[5]);
9695 DONE;
9696 }")
9697 \f
9698 ;; Unconditional and other jump instructions
9699
9700 (define_insn "jump"
9701 [(set (pc)
9702 (label_ref (match_operand 0 "" "")))]
9703 ""
9704 "jmp\\t%l0"
9705 [(set_attr "type" "ibr")])
9706
9707 (define_insn "indirect_jump"
9708 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
9709 ""
9710 "jmp\\t%A0"
9711 [(set_attr "type" "ibr")
9712 (set_attr "length_immediate" "0")])
9713
9714 (define_insn "tablejump"
9715 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
9716 (use (label_ref (match_operand 1 "" "")))]
9717 "! flag_pic"
9718 "jmp\\t%A0"
9719 [(set_attr "type" "ibr")
9720 (set_attr "length_immediate" "0")])
9721
9722 ;; Implement switch statements when generating PIC code. Switches are
9723 ;; implemented by `tablejump' when not using -fpic.
9724 ;;
9725 ;; Emit code here to do the range checking and make the index zero based.
9726 ;;
9727 ;; Each entry in the "addr_diff_vec" looks like this as the result of the
9728 ;; two rules below:
9729 ;;
9730 ;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
9731 ;;
9732 ;; 1. An expression involving an external reference may only use the
9733 ;; addition operator, and only with an assembly-time constant.
9734 ;; The example above satisfies this because ".-.L2" is a constant.
9735 ;;
9736 ;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
9737 ;; given the value of "GOT - .", where GOT is the actual address of
9738 ;; the Global Offset Table. Therefore, the .long above actually
9739 ;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
9740 ;; expression "GOT - .L2" by itself would generate an error from as(1).
9741 ;;
9742 ;; The pattern below emits code that looks like this:
9743 ;;
9744 ;; movl %ebx,reg
9745 ;; subl TABLE@GOTOFF(%ebx,index,4),reg
9746 ;; jmp reg
9747 ;;
9748 ;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
9749 ;; the addr_diff_vec is known to be part of this module.
9750 ;;
9751 ;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
9752 ;; evaluates to just ".L2".
9753
9754 (define_expand "casesi"
9755 [(set (match_dup 5)
9756 (match_operand:SI 0 "general_operand" ""))
9757 (parallel [(set (match_dup 6)
9758 (minus:SI (match_dup 5)
9759 (match_operand:SI 1 "general_operand" "")))
9760 (clobber (reg:CC 17))])
9761 (set (reg:CC 17)
9762 (compare:CC (match_dup 6)
9763 (match_operand:SI 2 "general_operand" "")))
9764 (set (pc)
9765 (if_then_else (gtu (reg:CC 17)
9766 (const_int 0))
9767 (label_ref (match_operand 4 "" ""))
9768 (pc)))
9769 (parallel
9770 [(set (match_dup 7)
9771 (minus:SI (match_dup 8)
9772 (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
9773 (match_dup 8))
9774 (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
9775 (clobber (reg:CC 17))])
9776 (parallel [(set (pc) (match_dup 7))
9777 (use (label_ref (match_dup 3)))])]
9778 "flag_pic"
9779 "
9780 {
9781 operands[5] = gen_reg_rtx (SImode);
9782 operands[6] = gen_reg_rtx (SImode);
9783 operands[7] = gen_reg_rtx (SImode);
9784 operands[8] = pic_offset_table_rtx;
9785 current_function_uses_pic_offset_table = 1;
9786 }")
9787
9788 (define_insn "*tablejump_pic"
9789 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
9790 (use (label_ref (match_operand 1 "" "")))]
9791 ""
9792 "jmp\\t%A0"
9793 [(set_attr "type" "ibr")
9794 (set_attr "length_immediate" "0")])
9795 \f
9796 ;; Loop instruction
9797 ;;
9798 ;; This is all complicated by the fact that since this is a jump insn
9799 ;; we must handle our own reloads.
9800
9801 (define_expand "doloop_end"
9802 [(use (match_operand 0 "" "")) ; loop pseudo
9803 (use (match_operand 1 "" "")) ; iterations; zero if unknown
9804 (use (match_operand 2 "" "")) ; max iterations
9805 (use (match_operand 3 "" "")) ; loop level
9806 (use (match_operand 4 "" ""))] ; label
9807 "TARGET_USE_LOOP"
9808 "
9809 {
9810 /* Only use cloop on innermost loops. */
9811 if (INTVAL (operands[3]) > 1)
9812 FAIL;
9813 if (GET_MODE (operands[0]) != SImode)
9814 FAIL;
9815 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
9816 operands[0]));
9817 DONE;
9818 }")
9819
9820 (define_insn "doloop_end_internal"
9821 [(set (pc)
9822 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
9823 (const_int 1))
9824 (label_ref (match_operand 0 "" ""))
9825 (pc)))
9826 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
9827 (plus:SI (match_dup 1)
9828 (const_int -1)))
9829 (clobber (match_scratch:SI 3 "=X,X,r"))
9830 (clobber (reg:CC 17))]
9831 "TARGET_USE_LOOP"
9832 "*
9833 {
9834 if (which_alternative != 0)
9835 return \"#\";
9836 if (get_attr_length (insn) == 2)
9837 return \"loop\\t%l0\";
9838 else
9839 return \"dec{l}\\t%1\;jne\\t%l0\";
9840 }"
9841 [(set_attr "ppro_uops" "many")
9842 (set (attr "type")
9843 (if_then_else (and (eq_attr "alternative" "0")
9844 (and (ge (minus (match_dup 0) (pc))
9845 (const_int -128))
9846 (lt (minus (match_dup 0) (pc))
9847 (const_int 124))))
9848 (const_string "ibr")
9849 (const_string "multi")))])
9850
9851 (define_split
9852 [(set (pc)
9853 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
9854 (const_int 1))
9855 (match_operand 0 "" "")
9856 (pc)))
9857 (set (match_dup 1)
9858 (plus:SI (match_dup 1)
9859 (const_int -1)))
9860 (clobber (match_scratch:SI 2 ""))
9861 (clobber (reg:CC 17))]
9862 "TARGET_USE_LOOP
9863 && reload_completed
9864 && REGNO (operands[1]) != 2"
9865 [(parallel [(set (reg:CCZ 17)
9866 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
9867 (const_int 0)))
9868 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
9869 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
9870 (match_dup 0)
9871 (pc)))]
9872 "")
9873
9874 (define_split
9875 [(set (pc)
9876 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
9877 (const_int 1))
9878 (match_operand 0 "" "")
9879 (pc)))
9880 (set (match_operand:SI 2 "nonimmediate_operand" "")
9881 (plus:SI (match_dup 1)
9882 (const_int -1)))
9883 (clobber (match_scratch:SI 3 ""))
9884 (clobber (reg:CC 17))]
9885 "TARGET_USE_LOOP
9886 && reload_completed
9887 && (! REG_P (operands[2])
9888 || ! rtx_equal_p (operands[1], operands[2]))"
9889 [(set (match_dup 3) (match_dup 1))
9890 (parallel [(set (reg:CCZ 17)
9891 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
9892 (const_int 0)))
9893 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9894 (set (match_dup 2) (match_dup 3))
9895 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
9896 (match_dup 0)
9897 (pc)))]
9898 "")
9899 \f
9900 ;; Call instructions.
9901
9902 ;; The predicates normally associated with named expanders are not properly
9903 ;; checked for calls. This is a bug in the generic code, but it isn't that
9904 ;; easy to fix. Ignore it for now and be prepared to fix things up.
9905
9906 ;; Call subroutine returning no value.
9907
9908 (define_expand "call_pop"
9909 [(parallel [(call (match_operand:QI 0 "" "")
9910 (match_operand:SI 1 "" ""))
9911 (set (reg:SI 7)
9912 (plus:SI (reg:SI 7)
9913 (match_operand:SI 3 "" "")))])]
9914 ""
9915 "
9916 {
9917 if (operands[3] == const0_rtx)
9918 {
9919 emit_insn (gen_call (operands[0], operands[1]));
9920 DONE;
9921 }
9922 /* Static functions and indirect calls don't need
9923 current_function_uses_pic_offset_table. */
9924 if (flag_pic
9925 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9926 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
9927 current_function_uses_pic_offset_table = 1;
9928 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
9929 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9930 }")
9931
9932 (define_insn "*call_pop_0"
9933 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
9934 (match_operand:SI 1 "" ""))
9935 (set (reg:SI 7) (plus:SI (reg:SI 7)
9936 (match_operand:SI 2 "immediate_operand" "")))]
9937 ""
9938 "*
9939 {
9940 if (SIBLING_CALL_P (insn))
9941 return \"jmp\\t%P0\";
9942 else
9943 return \"call\\t%P0\";
9944 }"
9945 [(set_attr "type" "call")])
9946
9947 (define_insn "*call_pop_1"
9948 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
9949 (match_operand:SI 1 "" ""))
9950 (set (reg:SI 7) (plus:SI (reg:SI 7)
9951 (match_operand:SI 2 "immediate_operand" "i")))]
9952 ""
9953 "*
9954 {
9955 if (constant_call_address_operand (operands[0], Pmode))
9956 {
9957 if (SIBLING_CALL_P (insn))
9958 return \"jmp\\t%P0\";
9959 else
9960 return \"call\\t%P0\";
9961 }
9962 if (SIBLING_CALL_P (insn))
9963 return \"jmp\\t%A0\";
9964 else
9965 return \"call\\t%A0\";
9966 }"
9967 [(set_attr "type" "call")])
9968
9969 (define_expand "call"
9970 [(call (match_operand:QI 0 "" "")
9971 (match_operand:SI 1 "" ""))]
9972 ;; Operand 1 not used on the i386.
9973 ""
9974 "
9975 {
9976 /* Static functions and indirect calls don't need
9977 current_function_uses_pic_offset_table. */
9978 if (flag_pic
9979 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9980 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
9981 current_function_uses_pic_offset_table = 1;
9982 if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
9983 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9984 }")
9985
9986 (define_insn "*call_0"
9987 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
9988 (match_operand:SI 1 "" ""))]
9989 ""
9990 "*
9991 {
9992 if (SIBLING_CALL_P (insn))
9993 return \"jmp\\t%P0\";
9994 else
9995 return \"call\\t%P0\";
9996 }"
9997 [(set_attr "type" "call")])
9998
9999 (define_insn "*call_1"
10000 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
10001 (match_operand:SI 1 "" ""))]
10002 ""
10003 "*
10004 {
10005 if (constant_call_address_operand (operands[0], QImode))
10006 {
10007 if (SIBLING_CALL_P (insn))
10008 return \"jmp\\t%P0\";
10009 else
10010 return \"call\\t%P0\";
10011 }
10012 if (SIBLING_CALL_P (insn))
10013 return \"jmp\\t%A0\";
10014 else
10015 return \"call\\t%A0\";
10016 }"
10017 [(set_attr "type" "call")])
10018
10019 ;; Call subroutine, returning value in operand 0
10020 ;; (which must be a hard register).
10021
10022 (define_expand "call_value_pop"
10023 [(parallel [(set (match_operand 0 "" "")
10024 (call (match_operand:QI 1 "" "")
10025 (match_operand:SI 2 "" "")))
10026 (set (reg:SI 7)
10027 (plus:SI (reg:SI 7)
10028 (match_operand:SI 4 "" "")))])]
10029 ""
10030 "
10031 {
10032 if (operands[4] == const0_rtx)
10033 {
10034 emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
10035 DONE;
10036 }
10037 /* Static functions and indirect calls don't need
10038 current_function_uses_pic_offset_table. */
10039 if (flag_pic
10040 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10041 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
10042 current_function_uses_pic_offset_table = 1;
10043 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
10044 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
10045 }")
10046
10047 (define_expand "call_value"
10048 [(set (match_operand 0 "" "")
10049 (call (match_operand:QI 1 "" "")
10050 (match_operand:SI 2 "" "")))]
10051 ;; Operand 2 not used on the i386.
10052 ""
10053 "
10054 {
10055 /* Static functions and indirect calls don't need
10056 current_function_uses_pic_offset_table. */
10057 if (flag_pic
10058 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
10059 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
10060 current_function_uses_pic_offset_table = 1;
10061 if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
10062 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
10063 }")
10064
10065 ;; Call subroutine returning any type.
10066
10067 (define_expand "untyped_call"
10068 [(parallel [(call (match_operand 0 "" "")
10069 (const_int 0))
10070 (match_operand 1 "" "")
10071 (match_operand 2 "" "")])]
10072 ""
10073 "
10074 {
10075 int i;
10076
10077 /* In order to give reg-stack an easier job in validating two
10078 coprocessor registers as containing a possible return value,
10079 simply pretend the untyped call returns a complex long double
10080 value. */
10081
10082 emit_call_insn (TARGET_80387
10083 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
10084 operands[0], const0_rtx)
10085 : gen_call (operands[0], const0_rtx));
10086
10087 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10088 {
10089 rtx set = XVECEXP (operands[2], 0, i);
10090 emit_move_insn (SET_DEST (set), SET_SRC (set));
10091 }
10092
10093 /* The optimizer does not know that the call sets the function value
10094 registers we stored in the result block. We avoid problems by
10095 claiming that all hard registers are used and clobbered at this
10096 point. */
10097 emit_insn (gen_blockage ());
10098
10099 DONE;
10100 }")
10101 \f
10102 ;; Prologue and epilogue instructions
10103
10104 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10105 ;; all of memory. This blocks insns from being moved across this point.
10106
10107 (define_insn "blockage"
10108 [(unspec_volatile [(const_int 0)] 0)]
10109 ""
10110 ""
10111 [(set_attr "length" "0")])
10112
10113 ;; Insn emitted into the body of a function to return from a function.
10114 ;; This is only done if the function's epilogue is known to be simple.
10115 ;; See comments for ix86_can_use_return_insn_p in i386.c.
10116
10117 (define_expand "return"
10118 [(return)]
10119 "ix86_can_use_return_insn_p ()"
10120 "
10121 {
10122 if (current_function_pops_args)
10123 {
10124 rtx popc = GEN_INT (current_function_pops_args);
10125 emit_jump_insn (gen_return_pop_internal (popc));
10126 DONE;
10127 }
10128 }")
10129
10130 (define_insn "return_internal"
10131 [(return)]
10132 "reload_completed"
10133 "ret"
10134 [(set_attr "length" "1")
10135 (set_attr "length_immediate" "0")
10136 (set_attr "modrm" "0")])
10137
10138 (define_insn "return_pop_internal"
10139 [(return)
10140 (use (match_operand:SI 0 "const_int_operand" ""))]
10141 "reload_completed"
10142 "ret\\t%0"
10143 [(set_attr "length" "3")
10144 (set_attr "length_immediate" "2")
10145 (set_attr "modrm" "0")])
10146
10147 (define_insn "return_indirect_internal"
10148 [(return)
10149 (use (match_operand:SI 0 "register_operand" "r"))]
10150 "reload_completed"
10151 "jmp\\t%A0"
10152 [(set_attr "type" "ibr")
10153 (set_attr "length_immediate" "0")])
10154
10155 (define_insn "nop"
10156 [(const_int 0)]
10157 ""
10158 "nop"
10159 [(set_attr "length" "1")
10160 (set_attr "length_immediate" "0")
10161 (set_attr "modrm" "0")
10162 (set_attr "ppro_uops" "one")])
10163
10164 (define_expand "prologue"
10165 [(const_int 1)]
10166 ""
10167 "ix86_expand_prologue (); DONE;")
10168
10169 (define_insn "prologue_set_got"
10170 [(set (match_operand:SI 0 "register_operand" "=r")
10171 (unspec_volatile:SI
10172 [(plus:SI (match_dup 0)
10173 (plus:SI (match_operand:SI 1 "symbolic_operand" "")
10174 (minus:SI (pc) (match_operand 2 "" ""))))] 1))
10175 (clobber (reg:CC 17))]
10176 ""
10177 "*
10178 {
10179 if (GET_CODE (operands[2]) == LABEL_REF)
10180 operands[2] = XEXP (operands[2], 0);
10181 if (TARGET_DEEP_BRANCH_PREDICTION)
10182 return \"add{l}\\t{%1, %0|%0, %1}\";
10183 else
10184 return \"add{l}\\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}\";
10185 }"
10186 [(set_attr "type" "alu")
10187 ; Since this insn may have two constant operands, we must set the
10188 ; length manually.
10189 (set_attr "length_immediate" "4")
10190 (set_attr "mode" "SI")])
10191
10192 (define_insn "prologue_get_pc"
10193 [(set (match_operand:SI 0 "register_operand" "=r")
10194 (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
10195 ""
10196 "*
10197 {
10198 if (GET_CODE (operands[1]) == LABEL_REF)
10199 operands[1] = XEXP (operands[1], 0);
10200 output_asm_insn (\"call\\t%X1\", operands);
10201 if (! TARGET_DEEP_BRANCH_PREDICTION)
10202 {
10203 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
10204 CODE_LABEL_NUMBER (operands[1]));
10205 }
10206 RET;
10207 }"
10208 [(set_attr "type" "multi")])
10209
10210 (define_expand "epilogue"
10211 [(const_int 1)]
10212 ""
10213 "ix86_expand_epilogue (1); DONE;")
10214
10215 (define_expand "sibcall_epilogue"
10216 [(const_int 1)]
10217 ""
10218 "ix86_expand_epilogue (0); DONE;")
10219
10220 (define_insn "leave"
10221 [(set (reg:SI 7) (reg:SI 6))
10222 (set (reg:SI 6) (mem:SI (pre_dec:SI (reg:SI 7))))]
10223 ""
10224 "leave"
10225 [(set_attr "length_immediate" "0")
10226 (set_attr "length" "1")
10227 (set_attr "modrm" "0")
10228 (set_attr "modrm" "0")
10229 (set_attr "athlon_decode" "vector")
10230 (set_attr "ppro_uops" "few")])
10231 \f
10232 (define_expand "ffssi2"
10233 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10234 (ffs:SI (match_operand:SI 1 "general_operand" "")))]
10235 ""
10236 "
10237 {
10238 rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
10239 rtx in = operands[1];
10240
10241 if (TARGET_CMOVE)
10242 {
10243 emit_move_insn (tmp, constm1_rtx);
10244 emit_insn (gen_ffssi_1 (out, in));
10245 emit_insn (gen_rtx_SET (VOIDmode, out,
10246 gen_rtx_IF_THEN_ELSE (SImode,
10247 gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
10248 const0_rtx),
10249 tmp,
10250 out)));
10251 emit_insn (gen_addsi3 (out, out, const1_rtx));
10252 emit_move_insn (operands[0], out);
10253 }
10254
10255 /* Pentium bsf instruction is extremly slow. The following code is
10256 recommended by the Intel Optimizing Manual as a reasonable replacement:
10257 TEST EAX,EAX
10258 JZ SHORT BS2
10259 XOR ECX,ECX
10260 MOV DWORD PTR [TEMP+4],ECX
10261 SUB ECX,EAX
10262 AND EAX,ECX
10263 MOV DWORD PTR [TEMP],EAX
10264 FILD QWORD PTR [TEMP]
10265 FSTP QWORD PTR [TEMP]
10266 WAIT ; WAIT only needed for compatibility with
10267 ; earlier processors
10268 MOV ECX, DWORD PTR [TEMP+4]
10269 SHR ECX,20
10270 SUB ECX,3FFH
10271 TEST EAX,EAX ; clear zero flag
10272 BS2:
10273 Following piece of code expand ffs to similar beast.
10274 */
10275
10276 else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
10277 {
10278 rtx label = gen_label_rtx ();
10279 rtx lo, hi;
10280 rtx mem = assign_386_stack_local (DImode, 0);
10281 rtx fptmp = gen_reg_rtx (DFmode);
10282 split_di (&mem, 1, &lo, &hi);
10283
10284 emit_move_insn (out, const0_rtx);
10285
10286 emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, 0, label);
10287
10288 emit_move_insn (hi, out);
10289 emit_insn (gen_subsi3 (out, out, in));
10290 emit_insn (gen_andsi3 (out, out, in));
10291 emit_move_insn (lo, out);
10292 emit_insn (gen_floatdidf2 (fptmp,mem));
10293 emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
10294 emit_move_insn (out, hi);
10295 emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
10296 emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
10297
10298 emit_label (label);
10299 LABEL_NUSES (label) = 1;
10300
10301 emit_move_insn (operands[0], out);
10302 }
10303 else
10304 {
10305 emit_move_insn (tmp, const0_rtx);
10306 emit_insn (gen_ffssi_1 (out, in));
10307 emit_insn (gen_rtx_SET (VOIDmode,
10308 gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
10309 gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
10310 const0_rtx)));
10311 emit_insn (gen_negsi2 (tmp, tmp));
10312 emit_insn (gen_iorsi3 (out, out, tmp));
10313 emit_insn (gen_addsi3 (out, out, const1_rtx));
10314 emit_move_insn (operands[0], out);
10315 }
10316 DONE;
10317 }")
10318
10319 (define_insn "ffssi_1"
10320 [(set (reg:CCZ 17)
10321 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
10322 (const_int 0)))
10323 (set (match_operand:SI 0 "register_operand" "=r")
10324 (unspec:SI [(match_dup 1)] 5))]
10325 ""
10326 "bsf{l}\\t{%1, %0|%0, %1}"
10327 [(set_attr "prefix_0f" "1")
10328 (set_attr "ppro_uops" "few")])
10329
10330 ;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
10331 ;; and slower than the two-byte movzx insn needed to do the work in SImode.
10332 \f
10333 ;; These patterns match the binary 387 instructions for addM3, subM3,
10334 ;; mulM3 and divM3. There are three patterns for each of DFmode and
10335 ;; SFmode. The first is the normal insn, the second the same insn but
10336 ;; with one operand a conversion, and the third the same insn but with
10337 ;; the other operand a conversion. The conversion may be SFmode or
10338 ;; SImode if the target mode DFmode, but only SImode if the target mode
10339 ;; is SFmode.
10340
10341 ;; Gcc is slightly more smart about handling normal two address instructions
10342 ;; so use special patterns for add and mull.
10343 (define_insn "*fop_sf_comm"
10344 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
10345 (match_operator:SF 3 "binary_fp_operator"
10346 [(match_operand:SF 1 "register_operand" "%0,0")
10347 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
10348 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
10349 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10350 "* return output_387_binary_op (insn, operands);"
10351 [(set (attr "type")
10352 (if_then_else (eq_attr "alternative" "1")
10353 (const_string "sse")
10354 (if_then_else (match_operand:SF 3 "mult_operator" "")
10355 (const_string "fmul")
10356 (const_string "fop"))))
10357 (set_attr "mode" "SF")])
10358
10359 (define_insn "*fop_sf_comm_sse"
10360 [(set (match_operand:SF 0 "register_operand" "=x")
10361 (match_operator:SF 3 "binary_fp_operator"
10362 [(match_operand:SF 1 "register_operand" "%0")
10363 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
10364 "TARGET_SSE && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10365 "* return output_387_binary_op (insn, operands);"
10366 [(set_attr "type" "sse")
10367 (set_attr "mode" "SF")])
10368
10369 (define_insn "*fop_df_comm"
10370 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
10371 (match_operator:DF 3 "binary_fp_operator"
10372 [(match_operand:DF 1 "register_operand" "%0,0")
10373 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
10374 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
10375 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10376 "* return output_387_binary_op (insn, operands);"
10377 [(set (attr "type")
10378 (if_then_else (eq_attr "alternative" "1")
10379 (const_string "sse")
10380 (if_then_else (match_operand:SF 3 "mult_operator" "")
10381 (const_string "fmul")
10382 (const_string "fop"))))
10383 (set_attr "mode" "DF")])
10384
10385 (define_insn "*fop_df_comm_sse"
10386 [(set (match_operand:DF 0 "register_operand" "=Y")
10387 (match_operator:DF 3 "binary_fp_operator"
10388 [(match_operand:DF 1 "register_operand" "%0")
10389 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
10390 "TARGET_SSE2
10391 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10392 "* return output_387_binary_op (insn, operands);"
10393 [(set_attr "type" "sse")
10394 (set_attr "mode" "DF")])
10395
10396 (define_insn "*fop_xf_comm"
10397 [(set (match_operand:XF 0 "register_operand" "=f")
10398 (match_operator:XF 3 "binary_fp_operator"
10399 [(match_operand:XF 1 "register_operand" "%0")
10400 (match_operand:XF 2 "register_operand" "f")]))]
10401 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10402 "* return output_387_binary_op (insn, operands);"
10403 [(set (attr "type")
10404 (if_then_else (match_operand:XF 3 "mult_operator" "")
10405 (const_string "fmul")
10406 (const_string "fop")))
10407 (set_attr "mode" "XF")])
10408
10409 (define_insn "*fop_tf_comm"
10410 [(set (match_operand:TF 0 "register_operand" "=f")
10411 (match_operator:TF 3 "binary_fp_operator"
10412 [(match_operand:TF 1 "register_operand" "%0")
10413 (match_operand:TF 2 "register_operand" "f")]))]
10414 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
10415 "* return output_387_binary_op (insn, operands);"
10416 [(set (attr "type")
10417 (if_then_else (match_operand:TF 3 "mult_operator" "")
10418 (const_string "fmul")
10419 (const_string "fop")))
10420 (set_attr "mode" "XF")])
10421
10422 (define_insn "*fop_sf_1"
10423 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
10424 (match_operator:SF 3 "binary_fp_operator"
10425 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
10426 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
10427 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)
10428 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
10429 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10430 "* return output_387_binary_op (insn, operands);"
10431 [(set (attr "type")
10432 (cond [(eq_attr "alternative" "2")
10433 (const_string "sse")
10434 (match_operand:SF 3 "mult_operator" "")
10435 (const_string "fmul")
10436 (match_operand:SF 3 "div_operator" "")
10437 (const_string "fdiv")
10438 ]
10439 (const_string "fop")))
10440 (set_attr "mode" "SF")])
10441
10442 (define_insn "*fop_sf_1_sse"
10443 [(set (match_operand:SF 0 "register_operand" "=x")
10444 (match_operator:SF 3 "binary_fp_operator"
10445 [(match_operand:SF 1 "register_operand" "0")
10446 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
10447 "TARGET_SSE
10448 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10449 "* return output_387_binary_op (insn, operands);"
10450 [(set_attr "type" "sse")
10451 (set_attr "mode" "SF")])
10452
10453 ;; ??? Add SSE splitters for these!
10454 (define_insn "*fop_sf_2"
10455 [(set (match_operand:SF 0 "register_operand" "=f,f")
10456 (match_operator:SF 3 "binary_fp_operator"
10457 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10458 (match_operand:SF 2 "register_operand" "0,0")]))]
10459 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
10460 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10461 [(set (attr "type")
10462 (cond [(match_operand:SF 3 "mult_operator" "")
10463 (const_string "fmul")
10464 (match_operand:SF 3 "div_operator" "")
10465 (const_string "fdiv")
10466 ]
10467 (const_string "fop")))
10468 (set_attr "fp_int_src" "true")
10469 (set_attr "ppro_uops" "many")
10470 (set_attr "mode" "SI")])
10471
10472 (define_insn "*fop_sf_3"
10473 [(set (match_operand:SF 0 "register_operand" "=f,f")
10474 (match_operator:SF 3 "binary_fp_operator"
10475 [(match_operand:SF 1 "register_operand" "0,0")
10476 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10477 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE"
10478 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10479 [(set (attr "type")
10480 (cond [(match_operand:SF 3 "mult_operator" "")
10481 (const_string "fmul")
10482 (match_operand:SF 3 "div_operator" "")
10483 (const_string "fdiv")
10484 ]
10485 (const_string "fop")))
10486 (set_attr "fp_int_src" "true")
10487 (set_attr "ppro_uops" "many")
10488 (set_attr "mode" "SI")])
10489
10490 (define_insn "*fop_df_1"
10491 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
10492 (match_operator:DF 3 "binary_fp_operator"
10493 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
10494 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
10495 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)
10496 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
10497 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10498 "* return output_387_binary_op (insn, operands);"
10499 [(set (attr "type")
10500 (cond [(eq_attr "alternative" "2")
10501 (const_string "sse")
10502 (match_operand:DF 3 "mult_operator" "")
10503 (const_string "fmul")
10504 (match_operand:DF 3 "div_operator" "")
10505 (const_string "fdiv")
10506 ]
10507 (const_string "fop")))
10508 (set_attr "mode" "DF")])
10509
10510 (define_insn "*fop_df_1_sse"
10511 [(set (match_operand:DF 0 "register_operand" "=Y")
10512 (match_operator:DF 3 "binary_fp_operator"
10513 [(match_operand:DF 1 "register_operand" "0")
10514 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
10515 "TARGET_SSE
10516 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10517 "* return output_387_binary_op (insn, operands);"
10518 [(set_attr "type" "sse")])
10519
10520 ;; ??? Add SSE splitters for these!
10521 (define_insn "*fop_df_2"
10522 [(set (match_operand:DF 0 "register_operand" "=f,f")
10523 (match_operator:DF 3 "binary_fp_operator"
10524 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10525 (match_operand:DF 2 "register_operand" "0,0")]))]
10526 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
10527 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10528 [(set (attr "type")
10529 (cond [(match_operand:DF 3 "mult_operator" "")
10530 (const_string "fmul")
10531 (match_operand:DF 3 "div_operator" "")
10532 (const_string "fdiv")
10533 ]
10534 (const_string "fop")))
10535 (set_attr "fp_int_src" "true")
10536 (set_attr "ppro_uops" "many")
10537 (set_attr "mode" "SI")])
10538
10539 (define_insn "*fop_df_3"
10540 [(set (match_operand:DF 0 "register_operand" "=f,f")
10541 (match_operator:DF 3 "binary_fp_operator"
10542 [(match_operand:DF 1 "register_operand" "0,0")
10543 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10544 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE2"
10545 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10546 [(set (attr "type")
10547 (cond [(match_operand:DF 3 "mult_operator" "")
10548 (const_string "fmul")
10549 (match_operand:DF 3 "div_operator" "")
10550 (const_string "fdiv")
10551 ]
10552 (const_string "fop")))
10553 (set_attr "fp_int_src" "true")
10554 (set_attr "ppro_uops" "many")
10555 (set_attr "mode" "SI")])
10556
10557 (define_insn "*fop_df_4"
10558 [(set (match_operand:DF 0 "register_operand" "=f,f")
10559 (match_operator:DF 3 "binary_fp_operator"
10560 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10561 (match_operand:DF 2 "register_operand" "0,f")]))]
10562 "TARGET_80387
10563 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
10564 "* return output_387_binary_op (insn, operands);"
10565 [(set (attr "type")
10566 (cond [(match_operand:DF 3 "mult_operator" "")
10567 (const_string "fmul")
10568 (match_operand:DF 3 "div_operator" "")
10569 (const_string "fdiv")
10570 ]
10571 (const_string "fop")))
10572 (set_attr "mode" "SF")])
10573
10574 (define_insn "*fop_df_5"
10575 [(set (match_operand:DF 0 "register_operand" "=f,f")
10576 (match_operator:DF 3 "binary_fp_operator"
10577 [(match_operand:DF 1 "register_operand" "0,f")
10578 (float_extend:DF
10579 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10580 "TARGET_80387 && !TARGET_SSE2"
10581 "* return output_387_binary_op (insn, operands);"
10582 [(set (attr "type")
10583 (cond [(match_operand:DF 3 "mult_operator" "")
10584 (const_string "fmul")
10585 (match_operand:DF 3 "div_operator" "")
10586 (const_string "fdiv")
10587 ]
10588 (const_string "fop")))
10589 (set_attr "mode" "SF")])
10590
10591 (define_insn "*fop_xf_1"
10592 [(set (match_operand:XF 0 "register_operand" "=f,f")
10593 (match_operator:XF 3 "binary_fp_operator"
10594 [(match_operand:XF 1 "register_operand" "0,f")
10595 (match_operand:XF 2 "register_operand" "f,0")]))]
10596 "TARGET_80387
10597 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10598 "* return output_387_binary_op (insn, operands);"
10599 [(set (attr "type")
10600 (cond [(match_operand:XF 3 "mult_operator" "")
10601 (const_string "fmul")
10602 (match_operand:XF 3 "div_operator" "")
10603 (const_string "fdiv")
10604 ]
10605 (const_string "fop")))
10606 (set_attr "mode" "XF")])
10607
10608 (define_insn "*fop_tf_1"
10609 [(set (match_operand:TF 0 "register_operand" "=f,f")
10610 (match_operator:TF 3 "binary_fp_operator"
10611 [(match_operand:TF 1 "register_operand" "0,f")
10612 (match_operand:TF 2 "register_operand" "f,0")]))]
10613 "TARGET_80387
10614 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
10615 "* return output_387_binary_op (insn, operands);"
10616 [(set (attr "type")
10617 (cond [(match_operand:TF 3 "mult_operator" "")
10618 (const_string "fmul")
10619 (match_operand:TF 3 "div_operator" "")
10620 (const_string "fdiv")
10621 ]
10622 (const_string "fop")))
10623 (set_attr "mode" "XF")])
10624
10625 (define_insn "*fop_xf_2"
10626 [(set (match_operand:XF 0 "register_operand" "=f,f")
10627 (match_operator:XF 3 "binary_fp_operator"
10628 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10629 (match_operand:XF 2 "register_operand" "0,0")]))]
10630 "TARGET_80387 && TARGET_USE_FIOP"
10631 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10632 [(set (attr "type")
10633 (cond [(match_operand:XF 3 "mult_operator" "")
10634 (const_string "fmul")
10635 (match_operand:XF 3 "div_operator" "")
10636 (const_string "fdiv")
10637 ]
10638 (const_string "fop")))
10639 (set_attr "fp_int_src" "true")
10640 (set_attr "mode" "SI")
10641 (set_attr "ppro_uops" "many")])
10642
10643 (define_insn "*fop_tf_2"
10644 [(set (match_operand:TF 0 "register_operand" "=f,f")
10645 (match_operator:TF 3 "binary_fp_operator"
10646 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
10647 (match_operand:TF 2 "register_operand" "0,0")]))]
10648 "TARGET_80387 && TARGET_USE_FIOP"
10649 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10650 [(set (attr "type")
10651 (cond [(match_operand:TF 3 "mult_operator" "")
10652 (const_string "fmul")
10653 (match_operand:TF 3 "div_operator" "")
10654 (const_string "fdiv")
10655 ]
10656 (const_string "fop")))
10657 (set_attr "fp_int_src" "true")
10658 (set_attr "mode" "SI")
10659 (set_attr "ppro_uops" "many")])
10660
10661 (define_insn "*fop_xf_3"
10662 [(set (match_operand:XF 0 "register_operand" "=f,f")
10663 (match_operator:XF 3 "binary_fp_operator"
10664 [(match_operand:XF 1 "register_operand" "0,0")
10665 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10666 "TARGET_80387 && TARGET_USE_FIOP"
10667 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10668 [(set (attr "type")
10669 (cond [(match_operand:XF 3 "mult_operator" "")
10670 (const_string "fmul")
10671 (match_operand:XF 3 "div_operator" "")
10672 (const_string "fdiv")
10673 ]
10674 (const_string "fop")))
10675 (set_attr "fp_int_src" "true")
10676 (set_attr "mode" "SI")
10677 (set_attr "ppro_uops" "many")])
10678
10679 (define_insn "*fop_tf_3"
10680 [(set (match_operand:TF 0 "register_operand" "=f,f")
10681 (match_operator:TF 3 "binary_fp_operator"
10682 [(match_operand:TF 1 "register_operand" "0,0")
10683 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
10684 "TARGET_80387 && TARGET_USE_FIOP"
10685 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
10686 [(set (attr "type")
10687 (cond [(match_operand:TF 3 "mult_operator" "")
10688 (const_string "fmul")
10689 (match_operand:TF 3 "div_operator" "")
10690 (const_string "fdiv")
10691 ]
10692 (const_string "fop")))
10693 (set_attr "fp_int_src" "true")
10694 (set_attr "mode" "SI")
10695 (set_attr "ppro_uops" "many")])
10696
10697 (define_insn "*fop_xf_4"
10698 [(set (match_operand:XF 0 "register_operand" "=f,f")
10699 (match_operator:XF 3 "binary_fp_operator"
10700 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10701 (match_operand:XF 2 "register_operand" "0,f")]))]
10702 "TARGET_80387"
10703 "* return output_387_binary_op (insn, operands);"
10704 [(set (attr "type")
10705 (cond [(match_operand:XF 3 "mult_operator" "")
10706 (const_string "fmul")
10707 (match_operand:XF 3 "div_operator" "")
10708 (const_string "fdiv")
10709 ]
10710 (const_string "fop")))
10711 (set_attr "mode" "SF")])
10712
10713 (define_insn "*fop_tf_4"
10714 [(set (match_operand:TF 0 "register_operand" "=f,f")
10715 (match_operator:TF 3 "binary_fp_operator"
10716 [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
10717 (match_operand:TF 2 "register_operand" "0,f")]))]
10718 "TARGET_80387"
10719 "* return output_387_binary_op (insn, operands);"
10720 [(set (attr "type")
10721 (cond [(match_operand:TF 3 "mult_operator" "")
10722 (const_string "fmul")
10723 (match_operand:TF 3 "div_operator" "")
10724 (const_string "fdiv")
10725 ]
10726 (const_string "fop")))
10727 (set_attr "mode" "SF")])
10728
10729 (define_insn "*fop_xf_5"
10730 [(set (match_operand:XF 0 "register_operand" "=f,f")
10731 (match_operator:XF 3 "binary_fp_operator"
10732 [(match_operand:XF 1 "register_operand" "0,f")
10733 (float_extend:XF
10734 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10735 "TARGET_80387"
10736 "* return output_387_binary_op (insn, operands);"
10737 [(set (attr "type")
10738 (cond [(match_operand:XF 3 "mult_operator" "")
10739 (const_string "fmul")
10740 (match_operand:XF 3 "div_operator" "")
10741 (const_string "fdiv")
10742 ]
10743 (const_string "fop")))
10744 (set_attr "mode" "SF")])
10745
10746 (define_insn "*fop_tf_5"
10747 [(set (match_operand:TF 0 "register_operand" "=f,f")
10748 (match_operator:TF 3 "binary_fp_operator"
10749 [(match_operand:TF 1 "register_operand" "0,f")
10750 (float_extend:TF
10751 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
10752 "TARGET_80387"
10753 "* return output_387_binary_op (insn, operands);"
10754 [(set (attr "type")
10755 (cond [(match_operand:TF 3 "mult_operator" "")
10756 (const_string "fmul")
10757 (match_operand:TF 3 "div_operator" "")
10758 (const_string "fdiv")
10759 ]
10760 (const_string "fop")))
10761 (set_attr "mode" "SF")])
10762
10763 (define_insn "*fop_xf_6"
10764 [(set (match_operand:XF 0 "register_operand" "=f,f")
10765 (match_operator:XF 3 "binary_fp_operator"
10766 [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
10767 (match_operand:XF 2 "register_operand" "0,f")]))]
10768 "TARGET_80387"
10769 "* return output_387_binary_op (insn, operands);"
10770 [(set (attr "type")
10771 (cond [(match_operand:XF 3 "mult_operator" "")
10772 (const_string "fmul")
10773 (match_operand:XF 3 "div_operator" "")
10774 (const_string "fdiv")
10775 ]
10776 (const_string "fop")))
10777 (set_attr "mode" "DF")])
10778
10779 (define_insn "*fop_tf_6"
10780 [(set (match_operand:TF 0 "register_operand" "=f,f")
10781 (match_operator:TF 3 "binary_fp_operator"
10782 [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
10783 (match_operand:TF 2 "register_operand" "0,f")]))]
10784 "TARGET_80387"
10785 "* return output_387_binary_op (insn, operands);"
10786 [(set (attr "type")
10787 (cond [(match_operand:TF 3 "mult_operator" "")
10788 (const_string "fmul")
10789 (match_operand:TF 3 "div_operator" "")
10790 (const_string "fdiv")
10791 ]
10792 (const_string "fop")))
10793 (set_attr "mode" "DF")])
10794
10795 (define_insn "*fop_xf_7"
10796 [(set (match_operand:XF 0 "register_operand" "=f,f")
10797 (match_operator:XF 3 "binary_fp_operator"
10798 [(match_operand:XF 1 "register_operand" "0,f")
10799 (float_extend:XF
10800 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
10801 "TARGET_80387"
10802 "* return output_387_binary_op (insn, operands);"
10803 [(set (attr "type")
10804 (cond [(match_operand:XF 3 "mult_operator" "")
10805 (const_string "fmul")
10806 (match_operand:XF 3 "div_operator" "")
10807 (const_string "fdiv")
10808 ]
10809 (const_string "fop")))
10810 (set_attr "mode" "DF")])
10811
10812 (define_insn "*fop_tf_7"
10813 [(set (match_operand:TF 0 "register_operand" "=f,f")
10814 (match_operator:TF 3 "binary_fp_operator"
10815 [(match_operand:TF 1 "register_operand" "0,f")
10816 (float_extend:TF
10817 (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
10818 "TARGET_80387"
10819 "* return output_387_binary_op (insn, operands);"
10820 [(set (attr "type")
10821 (cond [(match_operand:TF 3 "mult_operator" "")
10822 (const_string "fmul")
10823 (match_operand:TF 3 "div_operator" "")
10824 (const_string "fdiv")
10825 ]
10826 (const_string "fop")))
10827 (set_attr "mode" "DF")])
10828
10829 (define_split
10830 [(set (match_operand 0 "register_operand" "")
10831 (match_operator 3 "binary_fp_operator"
10832 [(float (match_operand:SI 1 "register_operand" ""))
10833 (match_operand 2 "register_operand" "")]))]
10834 "TARGET_80387 && reload_completed
10835 && FLOAT_MODE_P (GET_MODE (operands[0]))"
10836 [(const_int 0)]
10837 "
10838 {
10839 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
10840 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
10841 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
10842 gen_rtx_fmt_ee (GET_CODE (operands[3]),
10843 GET_MODE (operands[3]),
10844 operands[4],
10845 operands[2])));
10846 ix86_free_from_memory (GET_MODE (operands[1]));
10847 DONE;
10848 }")
10849
10850 (define_split
10851 [(set (match_operand 0 "register_operand" "")
10852 (match_operator 3 "binary_fp_operator"
10853 [(match_operand 1 "register_operand" "")
10854 (float (match_operand:SI 2 "register_operand" ""))]))]
10855 "TARGET_80387 && reload_completed
10856 && FLOAT_MODE_P (GET_MODE (operands[0]))"
10857 [(const_int 0)]
10858 "
10859 {
10860 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10861 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
10862 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
10863 gen_rtx_fmt_ee (GET_CODE (operands[3]),
10864 GET_MODE (operands[3]),
10865 operands[1],
10866 operands[4])));
10867 ix86_free_from_memory (GET_MODE (operands[2]));
10868 DONE;
10869 }")
10870 \f
10871 ;; FPU special functions.
10872
10873 (define_expand "sqrtsf2"
10874 [(set (match_operand:SF 0 "register_operand" "")
10875 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10876 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
10877 "
10878 {
10879 if (!TARGET_SSE)
10880 operands[1] = force_reg (SFmode, operands[1]);
10881 }")
10882
10883 (define_insn "sqrtsf2_1"
10884 [(set (match_operand:SF 0 "register_operand" "=f#Y,Y#f")
10885 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
10886 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10887 && (TARGET_SSE && TARGET_MIX_SSE_I387)"
10888 "@
10889 fsqrt
10890 sqrtss\\t{%1, %0|%0, %1}"
10891 [(set_attr "type" "fpspc,sse")
10892 (set_attr "mode" "SF,SF")
10893 (set_attr "athlon_decode" "direct,*")])
10894
10895 (define_insn "sqrtsf2_1_sse_only"
10896 [(set (match_operand:SF 0 "register_operand" "=Y")
10897 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "Ym")))]
10898 "TARGET_SSE && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
10899 "sqrtss\\t{%1, %0|%0, %1}"
10900 [(set_attr "type" "sse")
10901 (set_attr "mode" "SF")
10902 (set_attr "athlon_decode" "*")])
10903
10904 (define_insn "sqrtsf2_i387"
10905 [(set (match_operand:SF 0 "register_operand" "=f")
10906 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
10907 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10908 && (!TARGET_SSE && !TARGET_MIX_SSE_I387)"
10909 "fsqrt"
10910 [(set_attr "type" "fpspc")
10911 (set_attr "mode" "SF")
10912 (set_attr "athlon_decode" "direct")])
10913
10914 (define_expand "sqrtdf2"
10915 [(set (match_operand:DF 0 "register_operand" "")
10916 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10917 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE2"
10918 "
10919 {
10920 if (!TARGET_SSE2)
10921 operands[1] = force_reg (SFmode, operands[1]);
10922 }")
10923
10924 (define_insn "sqrtdf2_1"
10925 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
10926 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
10927 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10928 && (TARGET_SSE2 && TARGET_MIX_SSE_I387)"
10929 "@
10930 fsqrt
10931 sqrtsd\\t{%1, %0|%0, %1}"
10932 [(set_attr "type" "fpspc,sse")
10933 (set_attr "mode" "DF,DF")
10934 (set_attr "athlon_decode" "direct,*")])
10935
10936 (define_insn "sqrtdf2_1_sse_only"
10937 [(set (match_operand:DF 0 "register_operand" "=Y")
10938 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
10939 "TARGET_SSE2 && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
10940 "sqrtsd\\t{%1, %0|%0, %1}"
10941 [(set_attr "type" "sse")
10942 (set_attr "mode" "DF")
10943 (set_attr "athlon_decode" "*")])
10944
10945 (define_insn "sqrtdf2_i387"
10946 [(set (match_operand:DF 0 "register_operand" "=f")
10947 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
10948 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10949 && (!TARGET_SSE2 && !TARGET_MIX_SSE_I387)"
10950 "fsqrt"
10951 [(set_attr "type" "fpspc")
10952 (set_attr "mode" "DF")
10953 (set_attr "athlon_decode" "direct")])
10954
10955 (define_insn "*sqrtextendsfdf2"
10956 [(set (match_operand:DF 0 "register_operand" "=f")
10957 (sqrt:DF (float_extend:DF
10958 (match_operand:SF 1 "register_operand" "0"))))]
10959 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10960 "fsqrt"
10961 [(set_attr "type" "fpspc")
10962 (set_attr "mode" "DF")
10963 (set_attr "athlon_decode" "direct")])
10964
10965 (define_insn "sqrtxf2"
10966 [(set (match_operand:XF 0 "register_operand" "=f")
10967 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
10968 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10969 && (TARGET_IEEE_FP || flag_fast_math) "
10970 "fsqrt"
10971 [(set_attr "type" "fpspc")
10972 (set_attr "mode" "XF")
10973 (set_attr "athlon_decode" "direct")])
10974
10975 (define_insn "sqrttf2"
10976 [(set (match_operand:TF 0 "register_operand" "=f")
10977 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
10978 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
10979 && (TARGET_IEEE_FP || flag_fast_math) "
10980 "fsqrt"
10981 [(set_attr "type" "fpspc")
10982 (set_attr "mode" "XF")
10983 (set_attr "athlon_decode" "direct")])
10984
10985 (define_insn "*sqrtextenddfxf2"
10986 [(set (match_operand:XF 0 "register_operand" "=f")
10987 (sqrt:XF (float_extend:XF
10988 (match_operand:DF 1 "register_operand" "0"))))]
10989 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
10990 "fsqrt"
10991 [(set_attr "type" "fpspc")
10992 (set_attr "mode" "XF")
10993 (set_attr "athlon_decode" "direct")])
10994
10995 (define_insn "*sqrtextenddftf2"
10996 [(set (match_operand:TF 0 "register_operand" "=f")
10997 (sqrt:TF (float_extend:TF
10998 (match_operand:DF 1 "register_operand" "0"))))]
10999 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11000 "fsqrt"
11001 [(set_attr "type" "fpspc")
11002 (set_attr "mode" "XF")
11003 (set_attr "athlon_decode" "direct")])
11004
11005 (define_insn "*sqrtextendsfxf2"
11006 [(set (match_operand:XF 0 "register_operand" "=f")
11007 (sqrt:XF (float_extend:XF
11008 (match_operand:SF 1 "register_operand" "0"))))]
11009 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11010 "fsqrt"
11011 [(set_attr "type" "fpspc")
11012 (set_attr "mode" "XF")
11013 (set_attr "athlon_decode" "direct")])
11014
11015 (define_insn "*sqrtextendsftf2"
11016 [(set (match_operand:TF 0 "register_operand" "=f")
11017 (sqrt:TF (float_extend:TF
11018 (match_operand:SF 1 "register_operand" "0"))))]
11019 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
11020 "fsqrt"
11021 [(set_attr "type" "fpspc")
11022 (set_attr "mode" "XF")
11023 (set_attr "athlon_decode" "direct")])
11024
11025 (define_insn "sindf2"
11026 [(set (match_operand:DF 0 "register_operand" "=f")
11027 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
11028 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11029 "fsin"
11030 [(set_attr "type" "fpspc")
11031 (set_attr "mode" "DF")])
11032
11033 (define_insn "sinsf2"
11034 [(set (match_operand:SF 0 "register_operand" "=f")
11035 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
11036 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11037 "fsin"
11038 [(set_attr "type" "fpspc")
11039 (set_attr "mode" "SF")])
11040
11041 (define_insn "*sinextendsfdf2"
11042 [(set (match_operand:DF 0 "register_operand" "=f")
11043 (unspec:DF [(float_extend:DF
11044 (match_operand:SF 1 "register_operand" "0"))] 1))]
11045 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11046 "fsin"
11047 [(set_attr "type" "fpspc")
11048 (set_attr "mode" "DF")])
11049
11050 (define_insn "sinxf2"
11051 [(set (match_operand:XF 0 "register_operand" "=f")
11052 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
11053 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11054 "fsin"
11055 [(set_attr "type" "fpspc")
11056 (set_attr "mode" "XF")])
11057
11058 (define_insn "sintf2"
11059 [(set (match_operand:TF 0 "register_operand" "=f")
11060 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
11061 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11062 "fsin"
11063 [(set_attr "type" "fpspc")
11064 (set_attr "mode" "XF")])
11065
11066 (define_insn "cosdf2"
11067 [(set (match_operand:DF 0 "register_operand" "=f")
11068 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
11069 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11070 "fcos"
11071 [(set_attr "type" "fpspc")
11072 (set_attr "mode" "DF")])
11073
11074 (define_insn "cossf2"
11075 [(set (match_operand:SF 0 "register_operand" "=f")
11076 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
11077 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11078 "fcos"
11079 [(set_attr "type" "fpspc")
11080 (set_attr "mode" "SF")])
11081
11082 (define_insn "*cosextendsfdf2"
11083 [(set (match_operand:DF 0 "register_operand" "=f")
11084 (unspec:DF [(float_extend:DF
11085 (match_operand:SF 1 "register_operand" "0"))] 2))]
11086 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11087 "fcos"
11088 [(set_attr "type" "fpspc")
11089 (set_attr "mode" "DF")])
11090
11091 (define_insn "cosxf2"
11092 [(set (match_operand:XF 0 "register_operand" "=f")
11093 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
11094 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11095 "fcos"
11096 [(set_attr "type" "fpspc")
11097 (set_attr "mode" "XF")])
11098
11099 (define_insn "costf2"
11100 [(set (match_operand:TF 0 "register_operand" "=f")
11101 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
11102 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
11103 "fcos"
11104 [(set_attr "type" "fpspc")
11105 (set_attr "mode" "XF")])
11106 \f
11107 ;; Block operation instructions
11108
11109 (define_insn "cld"
11110 [(set (reg:SI 19) (const_int 0))]
11111 ""
11112 "cld"
11113 [(set_attr "type" "cld")])
11114
11115 (define_expand "movstrsi"
11116 [(use (match_operand:BLK 0 "memory_operand" ""))
11117 (use (match_operand:BLK 1 "memory_operand" ""))
11118 (use (match_operand:SI 2 "nonmemory_operand" ""))
11119 (use (match_operand:SI 3 "const_int_operand" ""))]
11120 ""
11121 "
11122 {
11123 rtx srcreg, destreg, countreg;
11124 int align = 0;
11125 int count = -1;
11126
11127 if (GET_CODE (operands[3]) == CONST_INT)
11128 align = INTVAL (operands[3]);
11129
11130 /* This simple hack avoids all inlining code and simplifies code bellow. */
11131 if (!TARGET_ALIGN_STRINGOPS)
11132 align = 32;
11133
11134 if (GET_CODE (operands[2]) == CONST_INT)
11135 count = INTVAL (operands[2]);
11136
11137 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11138 srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
11139
11140 emit_insn (gen_cld());
11141
11142 /* When optimizing for size emit simple rep ; movsb instruction for
11143 counts not divisible by 4. */
11144
11145 if ((!optimize || optimize_size)
11146 && (count < 0 || (count & 0x03)))
11147 {
11148 countreg = copy_to_mode_reg (SImode, operands[2]);
11149 emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
11150 destreg, srcreg, countreg));
11151 }
11152
11153 /* For constant aligned (or small unaligned) copies use rep movsl
11154 followed by code copying the rest. For PentiumPro ensure 8 byte
11155 alignment to allow rep movsl acceleration. */
11156
11157 else if (count >= 0
11158 && (align >= 8
11159 || (!TARGET_PENTIUMPRO && align >= 4)
11160 || optimize_size || count < 64))
11161 {
11162 if (count & ~0x03)
11163 {
11164 countreg = copy_to_mode_reg (SImode,
11165 GEN_INT ((count >> 2)
11166 & 0x3fffffff));
11167 emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
11168 destreg, srcreg, countreg));
11169 }
11170 if (count & 0x02)
11171 emit_insn (gen_strmovhi (destreg, srcreg));
11172 if (count & 0x01)
11173 emit_insn (gen_strmovqi (destreg, srcreg));
11174 }
11175 /* The generic code based on the glibc implementation:
11176 - align destination to 4 bytes (8 byte alignment is used for PentiumPro
11177 allowing accelerated copying there)
11178 - copy the data using rep movsl
11179 - copy the rest. */
11180 else
11181 {
11182 rtx countreg2;
11183 rtx label = NULL;
11184
11185 /* In case we don't know anything about the alignment, default to
11186 library version, since it is usually equally fast and result in
11187 shorter code. */
11188 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
11189 FAIL;
11190
11191 if (TARGET_SINGLE_STRINGOP)
11192 emit_insn (gen_cld());
11193
11194 countreg2 = gen_reg_rtx (SImode);
11195 countreg = copy_to_mode_reg (SImode, operands[2]);
11196
11197 /* We don't use loops to align destination and to copy parts smaller
11198 than 4 bytes, because gcc is able to optimize such code better (in
11199 the case the destination or the count really is aligned, gcc is often
11200 able to predict the branches) and also it is friendlier to the
11201 hardware branch prediction.
11202
11203 Using loops is benefical for generic case, because we can
11204 handle small counts using the loops. Many CPUs (such as Athlon)
11205 have large REP prefix setup costs.
11206
11207 This is quite costy. Maybe we can revisit this decision later or
11208 add some customizability to this code. */
11209
11210 if (count < 0
11211 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11212 {
11213 label = gen_label_rtx ();
11214 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11215 LEU, 0, SImode, 1, 0, label);
11216 }
11217 if (align <= 1)
11218 {
11219 rtx label = gen_label_rtx ();
11220 rtx tmpcount = gen_reg_rtx (SImode);
11221 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11222 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11223 SImode, 1, 0, label);
11224 emit_insn (gen_strmovqi (destreg, srcreg));
11225 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11226 emit_label (label);
11227 LABEL_NUSES (label) = 1;
11228 }
11229 if (align <= 2)
11230 {
11231 rtx label = gen_label_rtx ();
11232 rtx tmpcount = gen_reg_rtx (SImode);
11233 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11234 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11235 SImode, 1, 0, label);
11236 emit_insn (gen_strmovhi (destreg, srcreg));
11237 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11238 emit_label (label);
11239 LABEL_NUSES (label) = 1;
11240 }
11241 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11242 {
11243 rtx label = gen_label_rtx ();
11244 rtx tmpcount = gen_reg_rtx (SImode);
11245 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11246 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11247 SImode, 1, 0, label);
11248 emit_insn (gen_strmovsi (destreg, srcreg));
11249 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11250 emit_label (label);
11251 LABEL_NUSES (label) = 1;
11252 }
11253
11254 if (!TARGET_SINGLE_STRINGOP)
11255 emit_insn (gen_cld());
11256 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11257 emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
11258 destreg, srcreg, countreg2));
11259
11260 if (label)
11261 {
11262 emit_label (label);
11263 LABEL_NUSES (label) = 1;
11264 }
11265 if (align > 2 && count > 0 && (count & 2))
11266 emit_insn (gen_strmovhi (destreg, srcreg));
11267 if (align <= 2 || count < 0)
11268 {
11269 rtx label = gen_label_rtx ();
11270 rtx tmpcount = gen_reg_rtx (SImode);
11271 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11272 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11273 SImode, 1, 0, label);
11274 emit_insn (gen_strmovhi (destreg, srcreg));
11275 emit_label (label);
11276 LABEL_NUSES (label) = 1;
11277 }
11278 if (align > 1 && count > 0 && (count & 1))
11279 emit_insn (gen_strmovsi (destreg, srcreg));
11280 if (align <= 1 || count < 0)
11281 {
11282 rtx label = gen_label_rtx ();
11283 rtx tmpcount = gen_reg_rtx (SImode);
11284 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11285 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11286 SImode, 1, 0, label);
11287 emit_insn (gen_strmovqi (destreg, srcreg));
11288 emit_label (label);
11289 LABEL_NUSES (label) = 1;
11290 }
11291 }
11292 DONE;
11293 }")
11294
11295 ;; Most CPUs don't like single string operations
11296 ;; Handle this case here to simplify previous expander.
11297
11298 (define_expand "strmovsi"
11299 [(set (match_dup 2)
11300 (mem:SI (match_operand:SI 1 "register_operand" "")))
11301 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
11302 (match_dup 2))
11303 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11304 (clobber (reg:CC 17))])
11305 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
11306 (clobber (reg:CC 17))])]
11307 ""
11308 "
11309 {
11310 if (TARGET_SINGLE_STRINGOP || optimize_size)
11311 {
11312 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
11313 operands[1]));
11314 DONE;
11315 }
11316 else
11317 operands[2] = gen_reg_rtx (SImode);
11318 }")
11319
11320 (define_expand "strmovhi"
11321 [(set (match_dup 2)
11322 (mem:HI (match_operand:SI 1 "register_operand" "")))
11323 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
11324 (match_dup 2))
11325 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
11326 (clobber (reg:CC 17))])
11327 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
11328 (clobber (reg:CC 17))])]
11329 ""
11330 "
11331 {
11332 if (TARGET_SINGLE_STRINGOP || optimize_size)
11333 {
11334 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
11335 operands[1]));
11336 DONE;
11337 }
11338 else
11339 operands[2] = gen_reg_rtx (HImode);
11340 }")
11341
11342 (define_expand "strmovqi"
11343 [(set (match_dup 2)
11344 (mem:QI (match_operand:SI 1 "register_operand" "")))
11345 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
11346 (match_dup 2))
11347 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11348 (clobber (reg:CC 17))])
11349 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
11350 (clobber (reg:CC 17))])]
11351 ""
11352 "
11353 {
11354 if (TARGET_SINGLE_STRINGOP || optimize_size)
11355 {
11356 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
11357 operands[1]));
11358 DONE;
11359 }
11360 else
11361 operands[2] = gen_reg_rtx (QImode);
11362 }")
11363
11364 (define_insn "strmovsi_1"
11365 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
11366 (mem:SI (match_operand:SI 3 "register_operand" "1")))
11367 (set (match_operand:SI 0 "register_operand" "=D")
11368 (plus:SI (match_dup 2)
11369 (const_int 4)))
11370 (set (match_operand:SI 1 "register_operand" "=S")
11371 (plus:SI (match_dup 3)
11372 (const_int 4)))
11373 (use (reg:SI 19))]
11374 "TARGET_SINGLE_STRINGOP || optimize_size"
11375 "movsl"
11376 [(set_attr "type" "str")
11377 (set_attr "mode" "SI")
11378 (set_attr "memory" "both")])
11379
11380 (define_insn "strmovhi_1"
11381 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
11382 (mem:HI (match_operand:SI 3 "register_operand" "1")))
11383 (set (match_operand:SI 0 "register_operand" "=D")
11384 (plus:SI (match_dup 2)
11385 (const_int 2)))
11386 (set (match_operand:SI 1 "register_operand" "=S")
11387 (plus:SI (match_dup 3)
11388 (const_int 2)))
11389 (use (reg:SI 19))]
11390 "TARGET_SINGLE_STRINGOP || optimize_size"
11391 "movsw"
11392 [(set_attr "type" "str")
11393 (set_attr "memory" "both")
11394 (set_attr "mode" "HI")])
11395
11396 (define_insn "strmovqi_1"
11397 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
11398 (mem:QI (match_operand:SI 3 "register_operand" "1")))
11399 (set (match_operand:SI 0 "register_operand" "=D")
11400 (plus:SI (match_dup 2)
11401 (const_int 1)))
11402 (set (match_operand:SI 1 "register_operand" "=S")
11403 (plus:SI (match_dup 3)
11404 (const_int 1)))
11405 (use (reg:SI 19))]
11406 "TARGET_SINGLE_STRINGOP || optimize_size"
11407 "movsb"
11408 [(set_attr "type" "str")
11409 (set_attr "memory" "both")
11410 (set_attr "mode" "QI")])
11411
11412 (define_insn "rep_movsi"
11413 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
11414 (set (match_operand:SI 0 "register_operand" "=D")
11415 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
11416 (const_int 2))
11417 (match_operand:SI 3 "register_operand" "0")))
11418 (set (match_operand:SI 1 "register_operand" "=S")
11419 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
11420 (match_operand:SI 4 "register_operand" "1")))
11421 (set (mem:BLK (match_dup 3))
11422 (mem:BLK (match_dup 4)))
11423 (use (match_dup 5))
11424 (use (reg:SI 19))]
11425 ""
11426 "rep\;movsl|rep movsd"
11427 [(set_attr "type" "str")
11428 (set_attr "prefix_rep" "1")
11429 (set_attr "memory" "both")
11430 (set_attr "mode" "SI")])
11431
11432 (define_insn "rep_movqi"
11433 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
11434 (set (match_operand:SI 0 "register_operand" "=D")
11435 (plus:SI (match_operand:SI 3 "register_operand" "0")
11436 (match_operand:SI 5 "register_operand" "2")))
11437 (set (match_operand:SI 1 "register_operand" "=S")
11438 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
11439 (set (mem:BLK (match_dup 3))
11440 (mem:BLK (match_dup 4)))
11441 (use (match_dup 5))
11442 (use (reg:SI 19))]
11443 ""
11444 "rep\;movsb|rep movsb"
11445 [(set_attr "type" "str")
11446 (set_attr "prefix_rep" "1")
11447 (set_attr "memory" "both")
11448 (set_attr "mode" "SI")])
11449
11450 (define_expand "clrstrsi"
11451 [(use (match_operand:BLK 0 "memory_operand" ""))
11452 (use (match_operand:SI 1 "nonmemory_operand" ""))
11453 (use (match_operand:SI 2 "const_int_operand" ""))]
11454 ""
11455 "
11456 {
11457 /* See comments in movstr expanders. The code is mostly identical. */
11458
11459 rtx destreg, zeroreg, countreg;
11460 int align = 0;
11461 int count = -1;
11462
11463 if (GET_CODE (operands[2]) == CONST_INT)
11464 align = INTVAL (operands[2]);
11465
11466 /* This simple hack avoids all inlining code and simplifies code bellow. */
11467 if (!TARGET_ALIGN_STRINGOPS)
11468 align = 32;
11469
11470 if (GET_CODE (operands[1]) == CONST_INT)
11471 count = INTVAL (operands[1]);
11472
11473 destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
11474
11475 emit_insn (gen_cld());
11476
11477 /* When optimizing for size emit simple rep ; movsb instruction for
11478 counts not divisible by 4. */
11479
11480 if ((!optimize || optimize_size)
11481 && (count < 0 || (count & 0x03)))
11482 {
11483 countreg = copy_to_mode_reg (SImode, operands[1]);
11484 zeroreg = copy_to_mode_reg (QImode, const0_rtx);
11485 emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
11486 destreg, countreg));
11487 }
11488 else if (count >= 0
11489 && (align >= 8
11490 || (!TARGET_PENTIUMPRO && align >= 4)
11491 || optimize_size || count < 64))
11492 {
11493 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11494 if (INTVAL (operands[1]) & ~0x03)
11495 {
11496 countreg = copy_to_mode_reg (SImode,
11497 GEN_INT ((INTVAL (operands[1]) >> 2)
11498 & 0x3fffffff));
11499 emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
11500 destreg, countreg));
11501 }
11502 if (INTVAL (operands[1]) & 0x02)
11503 emit_insn (gen_strsethi (destreg,
11504 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11505 if (INTVAL (operands[1]) & 0x01)
11506 emit_insn (gen_strsetqi (destreg,
11507 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11508 }
11509 else
11510 {
11511 rtx countreg2;
11512 rtx label = NULL;
11513
11514 /* In case we don't know anything about the alignment, default to
11515 library version, since it is usually equally fast and result in
11516 shorter code. */
11517 if (!TARGET_INLINE_ALL_STRINGOPS && align < 4)
11518 FAIL;
11519
11520 if (TARGET_SINGLE_STRINGOP)
11521 emit_insn (gen_cld());
11522
11523 countreg2 = gen_reg_rtx (SImode);
11524 countreg = copy_to_mode_reg (SImode, operands[1]);
11525 zeroreg = copy_to_mode_reg (SImode, const0_rtx);
11526
11527 if (count < 0
11528 && align < (TARGET_PENTIUMPRO && (count < 0 || count >= 260) ? 8 : 4))
11529 {
11530 label = gen_label_rtx ();
11531 emit_cmp_and_jump_insns (countreg, GEN_INT (3),
11532 LEU, 0, SImode, 1, 0, label);
11533 }
11534 if (align <= 1)
11535 {
11536 rtx label = gen_label_rtx ();
11537 rtx tmpcount = gen_reg_rtx (SImode);
11538 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (1)));
11539 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11540 SImode, 1, 0, label);
11541 emit_insn (gen_strsetqi (destreg,
11542 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11543 emit_insn (gen_addsi3 (countreg, countreg, constm1_rtx));
11544 emit_label (label);
11545 LABEL_NUSES (label) = 1;
11546 }
11547 if (align <= 2)
11548 {
11549 rtx label = gen_label_rtx ();
11550 rtx tmpcount = gen_reg_rtx (SImode);
11551 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (2)));
11552 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11553 SImode, 1, 0, label);
11554 emit_insn (gen_strsethi (destreg,
11555 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11556 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-2)));
11557 emit_label (label);
11558 LABEL_NUSES (label) = 1;
11559 }
11560 if (align <= 4 && TARGET_PENTIUMPRO && (count < 1 || count >= 260))
11561 {
11562 rtx label = gen_label_rtx ();
11563 rtx tmpcount = gen_reg_rtx (SImode);
11564 emit_insn (gen_andsi3 (tmpcount, destreg, GEN_INT (4)));
11565 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11566 SImode, 1, 0, label);
11567 emit_insn (gen_strsetsi (destreg, zeroreg));
11568 emit_insn (gen_addsi3 (countreg, countreg, GEN_INT (-4)));
11569 emit_label (label);
11570 LABEL_NUSES (label) = 1;
11571 }
11572
11573 if (!TARGET_SINGLE_STRINGOP)
11574 emit_insn (gen_cld());
11575 emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
11576 emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
11577 destreg, countreg2));
11578
11579 if (label)
11580 {
11581 emit_label (label);
11582 LABEL_NUSES (label) = 1;
11583 }
11584 if (align > 2 && count > 0 && (count & 2))
11585 emit_insn (gen_strsethi (destreg,
11586 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11587 if (align <= 2 || count < 0)
11588 {
11589 rtx label = gen_label_rtx ();
11590 rtx tmpcount = gen_reg_rtx (SImode);
11591 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (2)));
11592 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11593 SImode, 1, 0, label);
11594 emit_insn (gen_strsethi (destreg,
11595 gen_rtx_SUBREG (HImode, zeroreg, 0)));
11596 emit_label (label);
11597 LABEL_NUSES (label) = 1;
11598 }
11599 if (align > 1 && count > 0 && (count & 1))
11600 emit_insn (gen_strsetqi (destreg,
11601 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11602 if (align <= 1 || count < 0)
11603 {
11604 rtx label = gen_label_rtx ();
11605 rtx tmpcount = gen_reg_rtx (SImode);
11606 emit_insn (gen_andsi3 (tmpcount, countreg, GEN_INT (1)));
11607 emit_cmp_and_jump_insns (tmpcount, GEN_INT (0), EQ, 0,
11608 SImode, 1, 0, label);
11609 emit_insn (gen_strsetqi (destreg,
11610 gen_rtx_SUBREG (QImode, zeroreg, 0)));
11611 emit_label (label);
11612 LABEL_NUSES (label) = 1;
11613 }
11614 }
11615 DONE;
11616 }")
11617
11618 ;; Most CPUs don't like single string operations
11619 ;; Handle this case here to simplify previous expander.
11620
11621 (define_expand "strsetsi"
11622 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
11623 (match_operand:SI 1 "register_operand" ""))
11624 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
11625 (clobber (reg:CC 17))])]
11626 ""
11627 "
11628 {
11629 if (TARGET_SINGLE_STRINGOP || optimize_size)
11630 {
11631 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
11632 DONE;
11633 }
11634 }")
11635
11636 (define_expand "strsethi"
11637 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
11638 (match_operand:HI 1 "register_operand" ""))
11639 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
11640 (clobber (reg:CC 17))])]
11641 ""
11642 "
11643 {
11644 if (TARGET_SINGLE_STRINGOP || optimize_size)
11645 {
11646 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
11647 DONE;
11648 }
11649 }")
11650
11651 (define_expand "strsetqi"
11652 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
11653 (match_operand:QI 1 "register_operand" ""))
11654 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11655 (clobber (reg:CC 17))])]
11656 ""
11657 "
11658 {
11659 if (TARGET_SINGLE_STRINGOP || optimize_size)
11660 {
11661 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
11662 DONE;
11663 }
11664 }")
11665
11666 (define_insn "strsetsi_1"
11667 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
11668 (match_operand:SI 2 "register_operand" "a"))
11669 (set (match_operand:SI 0 "register_operand" "=D")
11670 (plus:SI (match_dup 1)
11671 (const_int 4)))
11672 (use (reg:SI 19))]
11673 "TARGET_SINGLE_STRINGOP || optimize_size"
11674 "stosl"
11675 [(set_attr "type" "str")
11676 (set_attr "memory" "store")
11677 (set_attr "mode" "SI")])
11678
11679 (define_insn "strsethi_1"
11680 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
11681 (match_operand:HI 2 "register_operand" "a"))
11682 (set (match_operand:SI 0 "register_operand" "=D")
11683 (plus:SI (match_dup 1)
11684 (const_int 2)))
11685 (use (reg:SI 19))]
11686 "TARGET_SINGLE_STRINGOP || optimize_size"
11687 "stosw"
11688 [(set_attr "type" "str")
11689 (set_attr "memory" "store")
11690 (set_attr "mode" "HI")])
11691
11692 (define_insn "strsetqi_1"
11693 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
11694 (match_operand:QI 2 "register_operand" "a"))
11695 (set (match_operand:SI 0 "register_operand" "=D")
11696 (plus:SI (match_dup 1)
11697 (const_int 1)))
11698 (use (reg:SI 19))]
11699 "TARGET_SINGLE_STRINGOP || optimize_size"
11700 "stosb"
11701 [(set_attr "type" "str")
11702 (set_attr "memory" "store")
11703 (set_attr "mode" "QI")])
11704
11705 (define_insn "rep_stossi"
11706 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
11707 (set (match_operand:SI 0 "register_operand" "=D")
11708 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
11709 (const_int 2))
11710 (match_operand:SI 3 "register_operand" "0")))
11711 (set (mem:BLK (match_dup 3))
11712 (const_int 0))
11713 (use (match_operand:SI 2 "register_operand" "a"))
11714 (use (match_dup 4))
11715 (use (reg:SI 19))]
11716 ""
11717 "rep\;stosl|rep stosd"
11718 [(set_attr "type" "str")
11719 (set_attr "prefix_rep" "1")
11720 (set_attr "memory" "store")
11721 (set_attr "mode" "SI")])
11722
11723 (define_insn "rep_stosqi"
11724 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
11725 (set (match_operand:SI 0 "register_operand" "=D")
11726 (plus:SI (match_operand:SI 3 "register_operand" "0")
11727 (match_operand:SI 4 "register_operand" "1")))
11728 (set (mem:BLK (match_dup 3))
11729 (const_int 0))
11730 (use (match_operand:QI 2 "register_operand" "a"))
11731 (use (match_dup 4))
11732 (use (reg:SI 19))]
11733 ""
11734 "rep\;stosb|rep stosb"
11735 [(set_attr "type" "str")
11736 (set_attr "prefix_rep" "1")
11737 (set_attr "memory" "store")
11738 (set_attr "mode" "QI")])
11739
11740 (define_expand "cmpstrsi"
11741 [(set (match_operand:SI 0 "register_operand" "")
11742 (compare:SI (match_operand:BLK 1 "general_operand" "")
11743 (match_operand:BLK 2 "general_operand" "")))
11744 (use (match_operand:SI 3 "general_operand" ""))
11745 (use (match_operand:SI 4 "immediate_operand" ""))]
11746 ""
11747 "
11748 {
11749 rtx addr1, addr2, out, outlow, count, countreg, align;
11750
11751 out = operands[0];
11752 if (GET_CODE (out) != REG)
11753 out = gen_reg_rtx (SImode);
11754
11755 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
11756 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
11757
11758 count = operands[3];
11759 countreg = copy_to_mode_reg (SImode, count);
11760
11761 /* %%% Iff we are testing strict equality, we can use known alignment
11762 to good advantage. This may be possible with combine, particularly
11763 once cc0 is dead. */
11764 align = operands[4];
11765
11766 emit_insn (gen_cld ());
11767 if (GET_CODE (count) == CONST_INT)
11768 {
11769 if (INTVAL (count) == 0)
11770 {
11771 emit_move_insn (operands[0], const0_rtx);
11772 DONE;
11773 }
11774 emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align,
11775 addr1, addr2, countreg));
11776 }
11777 else
11778 {
11779 emit_insn (gen_cmpsi_1 (countreg, countreg));
11780 emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align,
11781 addr1, addr2, countreg));
11782 }
11783
11784 outlow = gen_lowpart (QImode, out);
11785 emit_insn (gen_cmpintqi (outlow));
11786 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
11787
11788 if (operands[0] != out)
11789 emit_move_insn (operands[0], out);
11790
11791 DONE;
11792 }")
11793
11794 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
11795
11796 (define_expand "cmpintqi"
11797 [(set (match_dup 1)
11798 (gtu:QI (reg:CC 17) (const_int 0)))
11799 (set (match_dup 2)
11800 (ltu:QI (reg:CC 17) (const_int 0)))
11801 (parallel [(set (match_operand:QI 0 "register_operand" "")
11802 (minus:QI (match_dup 1)
11803 (match_dup 2)))
11804 (clobber (reg:CC 17))])]
11805 ""
11806 "operands[1] = gen_reg_rtx (QImode);
11807 operands[2] = gen_reg_rtx (QImode);")
11808
11809 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
11810 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
11811
11812 (define_insn "cmpstrsi_nz_1"
11813 [(set (reg:CC 17)
11814 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
11815 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
11816 (use (match_operand:SI 6 "register_operand" "2"))
11817 (use (match_operand:SI 3 "immediate_operand" "i"))
11818 (use (reg:SI 19))
11819 (clobber (match_operand:SI 0 "register_operand" "=S"))
11820 (clobber (match_operand:SI 1 "register_operand" "=D"))
11821 (clobber (match_operand:SI 2 "register_operand" "=c"))]
11822 ""
11823 "repz{\;| }cmpsb"
11824 [(set_attr "type" "str")
11825 (set_attr "mode" "QI")
11826 (set_attr "prefix_rep" "1")])
11827
11828 ;; The same, but the count is not known to not be zero.
11829
11830 (define_insn "cmpstrsi_1"
11831 [(set (reg:CC 17)
11832 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
11833 (const_int 0))
11834 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
11835 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
11836 (const_int 0)))
11837 (use (match_operand:SI 3 "immediate_operand" "i"))
11838 (use (reg:CC 17))
11839 (use (reg:SI 19))
11840 (clobber (match_operand:SI 0 "register_operand" "=S"))
11841 (clobber (match_operand:SI 1 "register_operand" "=D"))
11842 (clobber (match_operand:SI 2 "register_operand" "=c"))]
11843 ""
11844 "repz{\;| }cmpsb"
11845 [(set_attr "type" "str")
11846 (set_attr "mode" "QI")
11847 (set_attr "prefix_rep" "1")])
11848
11849 (define_expand "strlensi"
11850 [(set (match_operand:SI 0 "register_operand" "")
11851 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
11852 (match_operand:QI 2 "immediate_operand" "")
11853 (match_operand:SI 3 "immediate_operand" "")] 0))]
11854 ""
11855 "
11856 {
11857 rtx out, addr, scratch1, scratch2, scratch3;
11858 rtx eoschar = operands[2];
11859 rtx align = operands[3];
11860
11861 /* The generic case of strlen expander is long. Avoid it's
11862 expanding unless TARGET_INLINE_ALL_STRINGOPS. */
11863
11864 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
11865 && !TARGET_INLINE_ALL_STRINGOPS
11866 && !optimize_size
11867 && (GET_CODE (align) != CONST_INT || INTVAL (align) < 4))
11868 FAIL;
11869
11870 out = operands[0];
11871 addr = force_reg (Pmode, XEXP (operands[1], 0));
11872 scratch1 = gen_reg_rtx (SImode);
11873
11874 if (TARGET_UNROLL_STRLEN && eoschar == const0_rtx && optimize > 1
11875 && !optimize_size)
11876 {
11877 /* Well it seems that some optimizer does not combine a call like
11878 foo(strlen(bar), strlen(bar));
11879 when the move and the subtraction is done here. It does calculate
11880 the length just once when these instructions are done inside of
11881 output_strlen_unroll(). But I think since &bar[strlen(bar)] is
11882 often used and I use one fewer register for the lifetime of
11883 output_strlen_unroll() this is better. */
11884
11885 if (GET_CODE (align) != CONST_INT || INTVAL (align) < 4)
11886 emit_move_insn (scratch1, addr);
11887
11888 emit_move_insn (out, addr);
11889
11890 ix86_expand_strlensi_unroll_1 (out, align, scratch1);
11891
11892 /* strlensi_unroll_1 returns the address of the zero at the end of
11893 the string, like memchr(), so compute the length by subtracting
11894 the start address. */
11895 emit_insn (gen_subsi3 (out, out, addr));
11896 }
11897 else
11898 {
11899 scratch2 = gen_reg_rtx (SImode);
11900 scratch3 = gen_reg_rtx (SImode);
11901
11902 emit_move_insn (scratch3, addr);
11903
11904 emit_insn (gen_cld ());
11905 emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
11906 align, constm1_rtx, scratch3));
11907 emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
11908 emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
11909 }
11910 DONE;
11911 }")
11912
11913 (define_insn "strlensi_1"
11914 [(set (match_operand:SI 0 "register_operand" "=&c")
11915 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
11916 (match_operand:QI 2 "general_operand" "a")
11917 (match_operand:SI 3 "immediate_operand" "i")
11918 (match_operand:SI 4 "immediate_operand" "0")] 0))
11919 (use (reg:SI 19))
11920 (clobber (match_operand:SI 1 "register_operand" "=D"))
11921 (clobber (reg:CC 17))]
11922 ""
11923 "repnz{\;| }scasb"
11924 [(set_attr "type" "str")
11925 (set_attr "mode" "QI")
11926 (set_attr "prefix_rep" "1")])
11927 \f
11928 ;; Conditional move instructions.
11929
11930 (define_expand "movsicc"
11931 [(set (match_operand:SI 0 "register_operand" "")
11932 (if_then_else:SI (match_operand 1 "comparison_operator" "")
11933 (match_operand:SI 2 "general_operand" "")
11934 (match_operand:SI 3 "general_operand" "")))]
11935 ""
11936 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
11937
11938 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
11939 ;; the register first winds up with `sbbl $0,reg', which is also weird.
11940 ;; So just document what we're doing explicitly.
11941
11942 (define_insn "x86_movsicc_0_m1"
11943 [(set (match_operand:SI 0 "register_operand" "=r")
11944 (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
11945 (const_int -1)
11946 (const_int 0)))
11947 (clobber (reg:CC 17))]
11948 ""
11949 "sbb{l}\\t%0, %0"
11950 ; Since we don't have the proper number of operands for an alu insn,
11951 ; fill in all the blanks.
11952 [(set_attr "type" "alu")
11953 (set_attr "memory" "none")
11954 (set_attr "imm_disp" "false")
11955 (set_attr "mode" "SI")
11956 (set_attr "length_immediate" "0")])
11957
11958 (define_insn "*movsicc_noc"
11959 [(set (match_operand:SI 0 "register_operand" "=r,r")
11960 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
11961 [(reg 17) (const_int 0)])
11962 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
11963 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
11964 "TARGET_CMOVE
11965 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
11966 "@
11967 cmov%C1\\t{%2, %0|%0, %2}
11968 cmov%c1\\t{%3, %0|%0, %3}"
11969 [(set_attr "type" "icmov")
11970 (set_attr "mode" "SI")])
11971
11972 (define_expand "movhicc"
11973 [(set (match_operand:HI 0 "register_operand" "")
11974 (if_then_else:HI (match_operand 1 "comparison_operator" "")
11975 (match_operand:HI 2 "nonimmediate_operand" "")
11976 (match_operand:HI 3 "nonimmediate_operand" "")))]
11977 "TARGET_CMOVE && TARGET_HIMODE_MATH"
11978 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
11979
11980 (define_insn "*movhicc_noc"
11981 [(set (match_operand:HI 0 "register_operand" "=r,r")
11982 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
11983 [(reg 17) (const_int 0)])
11984 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
11985 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
11986 "TARGET_CMOVE
11987 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
11988 "@
11989 cmov%C1\\t{%2, %0|%0, %2}
11990 cmov%c1\\t{%3, %0|%0, %3}"
11991 [(set_attr "type" "icmov")
11992 (set_attr "mode" "HI")])
11993
11994 (define_expand "movsfcc"
11995 [(set (match_operand:SF 0 "register_operand" "")
11996 (if_then_else:SF (match_operand 1 "comparison_operator" "")
11997 (match_operand:SF 2 "register_operand" "")
11998 (match_operand:SF 3 "register_operand" "")))]
11999 "TARGET_CMOVE"
12000 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12001
12002 (define_insn "*movsfcc_1"
12003 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
12004 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
12005 [(reg 17) (const_int 0)])
12006 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
12007 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
12008 "TARGET_CMOVE
12009 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12010 "@
12011 fcmov%F1\\t{%2, %0|%0, %2}
12012 fcmov%f1\\t{%3, %0|%0, %3}
12013 cmov%C1\\t{%2, %0|%0, %2}
12014 cmov%c1\\t{%3, %0|%0, %3}"
12015 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
12016 (set_attr "mode" "SF,SF,SI,SI")])
12017
12018 (define_expand "movdfcc"
12019 [(set (match_operand:DF 0 "register_operand" "")
12020 (if_then_else:DF (match_operand 1 "comparison_operator" "")
12021 (match_operand:DF 2 "register_operand" "")
12022 (match_operand:DF 3 "register_operand" "")))]
12023 "TARGET_CMOVE"
12024 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12025
12026 (define_insn "*movdfcc_1"
12027 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
12028 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12029 [(reg 17) (const_int 0)])
12030 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
12031 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
12032 "TARGET_CMOVE
12033 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
12034 "@
12035 fcmov%F1\\t{%2, %0|%0, %2}
12036 fcmov%f1\\t{%3, %0|%0, %3}
12037 #
12038 #"
12039 [(set_attr "type" "fcmov,fcmov,multi,multi")
12040 (set_attr "mode" "DF")])
12041
12042 (define_split
12043 [(set (match_operand:DF 0 "register_operand" "")
12044 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
12045 [(match_operand 4 "" "") (const_int 0)])
12046 (match_operand:DF 2 "nonimmediate_operand" "")
12047 (match_operand:DF 3 "nonimmediate_operand" "")))]
12048 "!ANY_FP_REG_P (operands[0]) && reload_completed"
12049 [(set (match_dup 2)
12050 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
12051 (match_dup 5)
12052 (match_dup 7)))
12053 (set (match_dup 3)
12054 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
12055 (match_dup 6)
12056 (match_dup 8)))]
12057 "split_di (operands+2, 1, operands+5, operands+6);
12058 split_di (operands+3, 1, operands+7, operands+8);
12059 split_di (operands, 1, operands+2, operands+3);")
12060
12061 (define_expand "movxfcc"
12062 [(set (match_operand:XF 0 "register_operand" "")
12063 (if_then_else:XF (match_operand 1 "comparison_operator" "")
12064 (match_operand:XF 2 "register_operand" "")
12065 (match_operand:XF 3 "register_operand" "")))]
12066 "TARGET_CMOVE"
12067 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12068
12069 (define_expand "movtfcc"
12070 [(set (match_operand:TF 0 "register_operand" "")
12071 (if_then_else:TF (match_operand 1 "comparison_operator" "")
12072 (match_operand:TF 2 "register_operand" "")
12073 (match_operand:TF 3 "register_operand" "")))]
12074 "TARGET_CMOVE"
12075 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
12076
12077 (define_insn "*movxfcc_1"
12078 [(set (match_operand:XF 0 "register_operand" "=f,f")
12079 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
12080 [(reg 17) (const_int 0)])
12081 (match_operand:XF 2 "register_operand" "f,0")
12082 (match_operand:XF 3 "register_operand" "0,f")))]
12083 "TARGET_CMOVE"
12084 "@
12085 fcmov%F1\\t{%2, %0|%0, %2}
12086 fcmov%f1\\t{%3, %0|%0, %3}"
12087 [(set_attr "type" "fcmov")
12088 (set_attr "mode" "XF")])
12089
12090 (define_insn "*movtfcc_1"
12091 [(set (match_operand:TF 0 "register_operand" "=f,f")
12092 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
12093 [(reg 17) (const_int 0)])
12094 (match_operand:TF 2 "register_operand" "f,0")
12095 (match_operand:TF 3 "register_operand" "0,f")))]
12096 "TARGET_CMOVE"
12097 "@
12098 fcmov%F1\\t{%2, %0|%0, %2}
12099 fcmov%f1\\t{%3, %0|%0, %3}"
12100 [(set_attr "type" "fcmov")
12101 (set_attr "mode" "XF")])
12102 \f
12103 ;; Misc patterns (?)
12104
12105 ;; This pattern exists to put a dependancy on all ebp-based memory accesses.
12106 ;; Otherwise there will be nothing to keep
12107 ;;
12108 ;; [(set (reg ebp) (reg esp))]
12109 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
12110 ;; (clobber (eflags)]
12111 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
12112 ;;
12113 ;; in proper program order.
12114
12115 (define_insn "pro_epilogue_adjust_stack"
12116 [(set (match_operand:SI 0 "register_operand" "=r,r")
12117 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
12118 (match_operand:SI 2 "immediate_operand" "i,i")))
12119 (set (match_operand:SI 3 "register_operand" "+r,r")
12120 (match_dup 3))
12121 (clobber (reg:CC 17))]
12122 ""
12123 "*
12124 {
12125 switch (get_attr_type (insn))
12126 {
12127 case TYPE_IMOV:
12128 return \"mov{l}\\t{%1, %0|%0, %1}\";
12129
12130 case TYPE_ALU:
12131 if (GET_CODE (operands[2]) == CONST_INT
12132 && (INTVAL (operands[2]) == 128
12133 || (INTVAL (operands[2]) < 0
12134 && INTVAL (operands[2]) != -128)))
12135 {
12136 operands[2] = GEN_INT (-INTVAL (operands[2]));
12137 return \"sub{l}\\t{%2, %0|%0, %2}\";
12138 }
12139 return \"add{l}\\t{%2, %0|%0, %2}\";
12140
12141 case TYPE_LEA:
12142 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
12143 return \"lea{l}\\t{%a2, %0|%0, %a2}\";
12144
12145 default:
12146 abort ();
12147 }
12148 }"
12149 [(set (attr "type")
12150 (cond [(eq_attr "alternative" "0")
12151 (const_string "alu")
12152 (match_operand:SI 2 "const0_operand" "")
12153 (const_string "imov")
12154 ]
12155 (const_string "lea")))
12156 (set_attr "mode" "SI")])
12157
12158 (define_insn "allocate_stack_worker"
12159 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
12160 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
12161 (clobber (match_dup 0))
12162 (clobber (reg:CC 17))]
12163 "TARGET_STACK_PROBE"
12164 "call\\t__alloca"
12165 [(set_attr "type" "multi")
12166 (set_attr "length" "5")])
12167
12168 (define_expand "allocate_stack"
12169 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
12170 (minus:SI (reg:SI 7)
12171 (match_operand:SI 1 "general_operand" "")))
12172 (clobber (reg:CC 17))])
12173 (parallel [(set (reg:SI 7)
12174 (minus:SI (reg:SI 7) (match_dup 1)))
12175 (clobber (reg:CC 17))])]
12176 "TARGET_STACK_PROBE"
12177 "
12178 {
12179 #ifdef CHECK_STACK_LIMIT
12180 if (GET_CODE (operands[1]) == CONST_INT
12181 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
12182 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
12183 operands[1]));
12184 else
12185 #endif
12186 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
12187 operands[1])));
12188
12189 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
12190 DONE;
12191 }")
12192
12193 (define_expand "exception_receiver"
12194 [(const_int 0)]
12195 "flag_pic"
12196 "
12197 {
12198 load_pic_register ();
12199 DONE;
12200 }")
12201
12202 (define_expand "builtin_setjmp_receiver"
12203 [(label_ref (match_operand 0 "" ""))]
12204 "flag_pic"
12205 "
12206 {
12207 load_pic_register ();
12208 DONE;
12209 }")
12210 \f
12211 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
12212
12213 (define_split
12214 [(set (match_operand 0 "register_operand" "")
12215 (match_operator 3 "promotable_binary_operator"
12216 [(match_operand 1 "register_operand" "")
12217 (match_operand 2 "aligned_operand" "")]))
12218 (clobber (reg:CC 17))]
12219 "! TARGET_PARTIAL_REG_STALL && reload_completed
12220 && ((GET_MODE (operands[0]) == HImode
12221 && (!optimize_size || GET_CODE (operands[2]) != CONST_INT
12222 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
12223 || (GET_MODE (operands[0]) == QImode
12224 && (TARGET_PROMOTE_QImode || optimize_size)))"
12225 [(parallel [(set (match_dup 0)
12226 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
12227 (clobber (reg:CC 17))])]
12228 "operands[0] = gen_lowpart (SImode, operands[0]);
12229 operands[1] = gen_lowpart (SImode, operands[1]);
12230 if (GET_CODE (operands[3]) != ASHIFT)
12231 operands[2] = gen_lowpart (SImode, operands[2]);
12232 GET_MODE (operands[3]) = SImode;")
12233
12234 (define_split
12235 [(set (reg 17)
12236 (compare (and (match_operand 1 "aligned_operand" "")
12237 (match_operand 2 "const_int_operand" ""))
12238 (const_int 0)))
12239 (set (match_operand 0 "register_operand" "")
12240 (and (match_dup 1) (match_dup 2)))]
12241 "! TARGET_PARTIAL_REG_STALL && reload_completed
12242 && ix86_match_ccmode (insn, CCNOmode)
12243 && (GET_MODE (operands[0]) == HImode
12244 || (GET_MODE (operands[0]) == QImode
12245 && (TARGET_PROMOTE_QImode || optimize_size)))"
12246 [(parallel [(set (reg:CCNO 17)
12247 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
12248 (const_int 0)))
12249 (set (match_dup 0)
12250 (and:SI (match_dup 1) (match_dup 2)))])]
12251 "operands[2]
12252 = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
12253 operands[0] = gen_lowpart (SImode, operands[0]);
12254 operands[1] = gen_lowpart (SImode, operands[1]);")
12255
12256 (define_split
12257 [(set (reg 17)
12258 (compare (and (match_operand 0 "aligned_operand" "")
12259 (match_operand 1 "const_int_operand" ""))
12260 (const_int 0)))]
12261 "! TARGET_PARTIAL_REG_STALL && reload_completed
12262 && ix86_match_ccmode (insn, CCNOmode)
12263 && (GET_MODE (operands[0]) == HImode
12264 || (GET_MODE (operands[0]) == QImode
12265 && (TARGET_PROMOTE_QImode || optimize_size)))"
12266 [(set (reg:CCNO 17)
12267 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
12268 (const_int 0)))]
12269 "operands[1]
12270 = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
12271 operands[0] = gen_lowpart (SImode, operands[0]);")
12272
12273 (define_split
12274 [(set (match_operand 0 "register_operand" "")
12275 (neg (match_operand 1 "register_operand" "")))
12276 (clobber (reg:CC 17))]
12277 "! TARGET_PARTIAL_REG_STALL && reload_completed
12278 && (GET_MODE (operands[0]) == HImode
12279 || (GET_MODE (operands[0]) == QImode
12280 && (TARGET_PROMOTE_QImode || optimize_size)))"
12281 [(parallel [(set (match_dup 0)
12282 (neg:SI (match_dup 1)))
12283 (clobber (reg:CC 17))])]
12284 "operands[0] = gen_lowpart (SImode, operands[0]);
12285 operands[1] = gen_lowpart (SImode, operands[1]);")
12286
12287 (define_split
12288 [(set (match_operand 0 "register_operand" "")
12289 (not (match_operand 1 "register_operand" "")))]
12290 "! TARGET_PARTIAL_REG_STALL && reload_completed
12291 && (GET_MODE (operands[0]) == HImode
12292 || (GET_MODE (operands[0]) == QImode
12293 && (TARGET_PROMOTE_QImode || optimize_size)))"
12294 [(set (match_dup 0)
12295 (not:SI (match_dup 1)))]
12296 "operands[0] = gen_lowpart (SImode, operands[0]);
12297 operands[1] = gen_lowpart (SImode, operands[1]);")
12298
12299 (define_split
12300 [(set (match_operand 0 "register_operand" "")
12301 (if_then_else (match_operator 1 "comparison_operator"
12302 [(reg 17) (const_int 0)])
12303 (match_operand 2 "register_operand" "")
12304 (match_operand 3 "register_operand" "")))]
12305 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
12306 && (GET_MODE (operands[0]) == HImode
12307 || (GET_MODE (operands[0]) == QImode
12308 && (TARGET_PROMOTE_QImode || optimize_size)))"
12309 [(set (match_dup 0)
12310 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
12311 "operands[0] = gen_lowpart (SImode, operands[0]);
12312 operands[2] = gen_lowpart (SImode, operands[2]);
12313 operands[3] = gen_lowpart (SImode, operands[3]);")
12314
12315 \f
12316 ;; RTL Peephole optimizations, run before sched2. These primarily look to
12317 ;; transform a complex memory operation into two memory to register operations.
12318
12319 ;; Don't push memory operands
12320 (define_peephole2
12321 [(set (match_operand:SI 0 "push_operand" "")
12322 (match_operand:SI 1 "memory_operand" ""))
12323 (match_scratch:SI 2 "r")]
12324 "! optimize_size && ! TARGET_PUSH_MEMORY"
12325 [(set (match_dup 2) (match_dup 1))
12326 (set (match_dup 0) (match_dup 2))]
12327 "")
12328
12329 ;; We need to handle SFmode only, because DFmode and XFmode is split to
12330 ;; SImode pushes.
12331 (define_peephole2
12332 [(set (match_operand:SF 0 "push_operand" "")
12333 (match_operand:SF 1 "memory_operand" ""))
12334 (match_scratch:SF 2 "r")]
12335 "! optimize_size && ! TARGET_PUSH_MEMORY"
12336 [(set (match_dup 2) (match_dup 1))
12337 (set (match_dup 0) (match_dup 2))]
12338 "")
12339
12340 (define_peephole2
12341 [(set (match_operand:HI 0 "push_operand" "")
12342 (match_operand:HI 1 "memory_operand" ""))
12343 (match_scratch:HI 2 "r")]
12344 "! optimize_size && ! TARGET_PUSH_MEMORY"
12345 [(set (match_dup 2) (match_dup 1))
12346 (set (match_dup 0) (match_dup 2))]
12347 "")
12348
12349 (define_peephole2
12350 [(set (match_operand:QI 0 "push_operand" "")
12351 (match_operand:QI 1 "memory_operand" ""))
12352 (match_scratch:QI 2 "q")]
12353 "! optimize_size && ! TARGET_PUSH_MEMORY"
12354 [(set (match_dup 2) (match_dup 1))
12355 (set (match_dup 0) (match_dup 2))]
12356 "")
12357
12358 ;; Don't move an immediate directly to memory when the instruction
12359 ;; gets too big.
12360 (define_peephole2
12361 [(match_scratch:SI 1 "r")
12362 (set (match_operand:SI 0 "memory_operand" "")
12363 (const_int 0))]
12364 "! optimize_size
12365 && ! TARGET_USE_MOV0
12366 && TARGET_SPLIT_LONG_MOVES
12367 && get_attr_length (insn) >= ix86_cost->large_insn
12368 && peep2_regno_dead_p (0, FLAGS_REG)"
12369 [(parallel [(set (match_dup 1) (const_int 0))
12370 (clobber (reg:CC 17))])
12371 (set (match_dup 0) (match_dup 1))]
12372 "")
12373
12374 (define_peephole2
12375 [(match_scratch:HI 1 "r")
12376 (set (match_operand:HI 0 "memory_operand" "")
12377 (const_int 0))]
12378 "! optimize_size
12379 && ! TARGET_USE_MOV0
12380 && TARGET_SPLIT_LONG_MOVES
12381 && get_attr_length (insn) >= ix86_cost->large_insn
12382 && peep2_regno_dead_p (0, FLAGS_REG)"
12383 [(parallel [(set (match_dup 2) (const_int 0))
12384 (clobber (reg:CC 17))])
12385 (set (match_dup 0) (match_dup 1))]
12386 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
12387
12388 (define_peephole2
12389 [(match_scratch:QI 1 "q")
12390 (set (match_operand:QI 0 "memory_operand" "")
12391 (const_int 0))]
12392 "! optimize_size
12393 && ! TARGET_USE_MOV0
12394 && TARGET_SPLIT_LONG_MOVES
12395 && get_attr_length (insn) >= ix86_cost->large_insn
12396 && peep2_regno_dead_p (0, FLAGS_REG)"
12397 [(parallel [(set (match_dup 2) (const_int 0))
12398 (clobber (reg:CC 17))])
12399 (set (match_dup 0) (match_dup 1))]
12400 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
12401
12402 (define_peephole2
12403 [(match_scratch:SI 2 "r")
12404 (set (match_operand:SI 0 "memory_operand" "")
12405 (match_operand:SI 1 "immediate_operand" ""))]
12406 "! optimize_size
12407 && get_attr_length (insn) >= ix86_cost->large_insn
12408 && TARGET_SPLIT_LONG_MOVES"
12409 [(set (match_dup 2) (match_dup 1))
12410 (set (match_dup 0) (match_dup 2))]
12411 "")
12412
12413 (define_peephole2
12414 [(match_scratch:HI 2 "r")
12415 (set (match_operand:HI 0 "memory_operand" "")
12416 (match_operand:HI 1 "immediate_operand" ""))]
12417 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
12418 && TARGET_SPLIT_LONG_MOVES"
12419 [(set (match_dup 2) (match_dup 1))
12420 (set (match_dup 0) (match_dup 2))]
12421 "")
12422
12423 (define_peephole2
12424 [(match_scratch:QI 2 "q")
12425 (set (match_operand:QI 0 "memory_operand" "")
12426 (match_operand:QI 1 "immediate_operand" ""))]
12427 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
12428 && TARGET_SPLIT_LONG_MOVES"
12429 [(set (match_dup 2) (match_dup 1))
12430 (set (match_dup 0) (match_dup 2))]
12431 "")
12432
12433 ;; Don't compare memory with zero, load and use a test instead.
12434 (define_peephole2
12435 [(set (reg 17)
12436 (compare (match_operand:SI 0 "memory_operand" "")
12437 (const_int 0)))
12438 (match_scratch:SI 3 "r")]
12439 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
12440 [(set (match_dup 3) (match_dup 0))
12441 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
12442 "")
12443
12444 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
12445 ;; Don't split NOTs with a displacement operand, because resulting XOR
12446 ;; will not be pariable anyway.
12447 ;;
12448 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
12449 ;; represented using a modRM byte. The XOR replacement is long decoded,
12450 ;; so this split helps here as well.
12451 ;;
12452 ;; Note: Can't do this as a regular split because we can't get proper
12453 ;; lifetime information then.
12454
12455 (define_peephole2
12456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12457 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
12458 "!optimize_size
12459 && peep2_regno_dead_p (0, FLAGS_REG)
12460 && ((TARGET_PENTIUM
12461 && (GET_CODE (operands[0]) != MEM
12462 || !memory_displacement_operand (operands[0], SImode)))
12463 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
12464 [(parallel [(set (match_dup 0)
12465 (xor:SI (match_dup 1) (const_int -1)))
12466 (clobber (reg:CC 17))])]
12467 "")
12468
12469 (define_peephole2
12470 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12471 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
12472 "!optimize_size
12473 && peep2_regno_dead_p (0, FLAGS_REG)
12474 && ((TARGET_PENTIUM
12475 && (GET_CODE (operands[0]) != MEM
12476 || !memory_displacement_operand (operands[0], HImode)))
12477 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
12478 [(parallel [(set (match_dup 0)
12479 (xor:HI (match_dup 1) (const_int -1)))
12480 (clobber (reg:CC 17))])]
12481 "")
12482
12483 (define_peephole2
12484 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
12485 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))]
12486 "!optimize_size
12487 && peep2_regno_dead_p (0, FLAGS_REG)
12488 && ((TARGET_PENTIUM
12489 && (GET_CODE (operands[0]) != MEM
12490 || !memory_displacement_operand (operands[0], QImode)))
12491 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
12492 [(parallel [(set (match_dup 0)
12493 (xor:QI (match_dup 1) (const_int -1)))
12494 (clobber (reg:CC 17))])]
12495 "")
12496
12497 ;; Non pairable "test imm, reg" instructions can be translated to
12498 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
12499 ;; byte opcode instead of two, have a short form for byte operands),
12500 ;; so do it for other CPUs as well. Given that the value was dead,
12501 ;; this should not create any new dependancies. Pass on the sub-word
12502 ;; versions if we're concerned about partial register stalls.
12503
12504 (define_peephole2
12505 [(set (reg 17)
12506 (compare (and:SI (match_operand:SI 0 "register_operand" "")
12507 (match_operand:SI 1 "immediate_operand" ""))
12508 (const_int 0)))]
12509 "ix86_match_ccmode (insn, CCNOmode)
12510 && (true_regnum (operands[0]) != 0
12511 || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
12512 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12513 [(parallel
12514 [(set (reg:CCNO 17)
12515 (compare:CCNO (and:SI (match_dup 0)
12516 (match_dup 1))
12517 (const_int 0)))
12518 (set (match_dup 0)
12519 (and:SI (match_dup 0) (match_dup 1)))])]
12520 "")
12521
12522 ;; We don't need to handle HImode case, because it will be promoted to SImode
12523 ;; on ! TARGET_PARTIAL_REG_STALL
12524
12525 (define_peephole2
12526 [(set (reg 17)
12527 (compare (and:QI (match_operand:QI 0 "register_operand" "")
12528 (match_operand:QI 1 "immediate_operand" ""))
12529 (const_int 0)))]
12530 "! TARGET_PARTIAL_REG_STALL
12531 && ix86_match_ccmode (insn, CCNOmode)
12532 && true_regnum (operands[0]) != 0
12533 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12534 [(parallel
12535 [(set (reg:CCNO 17)
12536 (compare:CCNO (and:QI (match_dup 0)
12537 (match_dup 1))
12538 (const_int 0)))
12539 (set (match_dup 0)
12540 (and:QI (match_dup 0) (match_dup 1)))])]
12541 "")
12542
12543 (define_peephole2
12544 [(set (reg 17)
12545 (compare
12546 (and:SI
12547 (zero_extract:SI
12548 (match_operand 0 "ext_register_operand" "q")
12549 (const_int 8)
12550 (const_int 8))
12551 (match_operand 1 "const_int_operand" "n"))
12552 (const_int 0)))]
12553 "! TARGET_PARTIAL_REG_STALL
12554 && ix86_match_ccmode (insn, CCNOmode)
12555 && true_regnum (operands[0]) != 0
12556 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12557 [(parallel [(set (reg:CCNO 17)
12558 (compare:CCNO
12559 (and:SI
12560 (zero_extract:SI
12561 (match_dup 0)
12562 (const_int 8)
12563 (const_int 8))
12564 (match_dup 1))
12565 (const_int 0)))
12566 (set (zero_extract:SI (match_dup 0)
12567 (const_int 8)
12568 (const_int 8))
12569 (and:SI
12570 (zero_extract:SI
12571 (match_dup 0)
12572 (const_int 8)
12573 (const_int 8))
12574 (match_dup 1)))])]
12575 "")
12576
12577 ;; Don't do logical operations with memory inputs.
12578 (define_peephole2
12579 [(match_scratch:SI 2 "r")
12580 (parallel [(set (match_operand:SI 0 "register_operand" "")
12581 (match_operator:SI 3 "arith_or_logical_operator"
12582 [(match_dup 0)
12583 (match_operand:SI 1 "memory_operand" "")]))
12584 (clobber (reg:CC 17))])]
12585 "! optimize_size && ! TARGET_READ_MODIFY"
12586 [(set (match_dup 2) (match_dup 1))
12587 (parallel [(set (match_dup 0)
12588 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
12589 (clobber (reg:CC 17))])]
12590 "")
12591
12592 (define_peephole2
12593 [(match_scratch:SI 2 "r")
12594 (parallel [(set (match_operand:SI 0 "register_operand" "")
12595 (match_operator:SI 3 "arith_or_logical_operator"
12596 [(match_operand:SI 1 "memory_operand" "")
12597 (match_dup 0)]))
12598 (clobber (reg:CC 17))])]
12599 "! optimize_size && ! TARGET_READ_MODIFY"
12600 [(set (match_dup 2) (match_dup 1))
12601 (parallel [(set (match_dup 0)
12602 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
12603 (clobber (reg:CC 17))])]
12604 "")
12605
12606 ; Don't do logical operations with memory outputs
12607 ;
12608 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
12609 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
12610 ; the same decoder scheduling characteristics as the original.
12611
12612 (define_peephole2
12613 [(match_scratch:SI 2 "r")
12614 (parallel [(set (match_operand:SI 0 "memory_operand" "")
12615 (match_operator:SI 3 "arith_or_logical_operator"
12616 [(match_dup 0)
12617 (match_operand:SI 1 "nonmemory_operand" "")]))
12618 (clobber (reg:CC 17))])]
12619 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
12620 [(set (match_dup 2) (match_dup 0))
12621 (parallel [(set (match_dup 2)
12622 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
12623 (clobber (reg:CC 17))])
12624 (set (match_dup 0) (match_dup 2))]
12625 "")
12626
12627 (define_peephole2
12628 [(match_scratch:SI 2 "r")
12629 (parallel [(set (match_operand:SI 0 "memory_operand" "")
12630 (match_operator:SI 3 "arith_or_logical_operator"
12631 [(match_operand:SI 1 "nonmemory_operand" "")
12632 (match_dup 0)]))
12633 (clobber (reg:CC 17))])]
12634 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
12635 [(set (match_dup 2) (match_dup 0))
12636 (parallel [(set (match_dup 2)
12637 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
12638 (clobber (reg:CC 17))])
12639 (set (match_dup 0) (match_dup 2))]
12640 "")
12641
12642 ;; Attempt to always use XOR for zeroing registers.
12643 (define_peephole2
12644 [(set (match_operand 0 "register_operand" "")
12645 (const_int 0))]
12646 "(GET_MODE (operands[0]) == QImode
12647 || GET_MODE (operands[0]) == HImode
12648 || GET_MODE (operands[0]) == SImode)
12649 && (! TARGET_USE_MOV0 || optimize_size)
12650 && peep2_regno_dead_p (0, FLAGS_REG)"
12651 [(parallel [(set (match_dup 0) (const_int 0))
12652 (clobber (reg:CC 17))])]
12653 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
12654
12655 (define_peephole2
12656 [(set (strict_low_part (match_operand 0 "register_operand" ""))
12657 (const_int 0))]
12658 "(GET_MODE (operands[0]) == QImode
12659 || GET_MODE (operands[0]) == HImode)
12660 && (! TARGET_USE_MOV0 || optimize_size)
12661 && peep2_regno_dead_p (0, FLAGS_REG)"
12662 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
12663 (clobber (reg:CC 17))])])
12664
12665 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
12666 (define_peephole2
12667 [(set (match_operand 0 "register_operand" "")
12668 (const_int -1))]
12669 "(GET_MODE (operands[0]) == HImode
12670 || GET_MODE (operands[0]) == SImode)
12671 && (optimize_size || TARGET_PENTIUM)
12672 && peep2_regno_dead_p (0, FLAGS_REG)"
12673 [(parallel [(set (match_dup 0) (const_int -1))
12674 (clobber (reg:CC 17))])]
12675 "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));")
12676
12677 ;; Attempt to convert simple leas to adds. These can be created by
12678 ;; move expanders.
12679 (define_peephole2
12680 [(set (match_operand:SI 0 "register_operand" "")
12681 (plus:SI (match_dup 0)
12682 (match_operand:SI 1 "nonmemory_operand" "")))]
12683 "peep2_regno_dead_p (0, FLAGS_REG)"
12684 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
12685 (clobber (reg:CC 17))])]
12686 "")
12687
12688 (define_peephole2
12689 [(set (match_operand:SI 0 "register_operand" "")
12690 (mult:SI (match_dup 0)
12691 (match_operand:SI 1 "immediate_operand" "")))]
12692 "exact_log2 (INTVAL (operands[1])) >= 0
12693 && peep2_regno_dead_p (0, FLAGS_REG)"
12694 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
12695 (clobber (reg:CC 17))])]
12696 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
12697
12698 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
12699 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
12700 ;; many CPUs it is also faster, since special hardware to avoid esp
12701 ;; dependancies is present.
12702
12703 ;; While some of these converisons may be done using splitters, we use peepholes
12704 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
12705
12706 ;; Convert prologue esp substractions to push.
12707 ;; We need register to push. In order to keep verify_flow_info happy we have
12708 ;; two choices
12709 ;; - use scratch and clobber it in order to avoid dependencies
12710 ;; - use already live register
12711 ;; We can't use the second way right now, since there is no reliable way how to
12712 ;; verify that given register is live. First choice will also most likely in
12713 ;; fewer dependencies. On the place of esp adjustments it is very likely that
12714 ;; call clobbered registers are dead. We may want to use base pointer as an
12715 ;; alternative when no register is available later.
12716
12717 (define_peephole2
12718 [(match_scratch:SI 0 "r")
12719 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
12720 (set (reg:SI 6) (reg:SI 6))
12721 (clobber (reg:CC 17))])]
12722 "optimize_size || !TARGET_SUB_ESP_4"
12723 [(clobber (match_dup 0))
12724 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12725 (set (reg:SI 6) (reg:SI 6))])])
12726
12727 (define_peephole2
12728 [(match_scratch:SI 0 "r")
12729 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12730 (set (reg:SI 6) (reg:SI 6))
12731 (clobber (reg:CC 17))])]
12732 "optimize_size || !TARGET_SUB_ESP_8"
12733 [(clobber (match_dup 0))
12734 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12735 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12736 (set (reg:SI 6) (reg:SI 6))])])
12737
12738 ;; Convert esp substractions to push.
12739 (define_peephole2
12740 [(match_scratch:SI 0 "r")
12741 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
12742 (clobber (reg:CC 17))])]
12743 "optimize_size || !TARGET_SUB_ESP_4"
12744 [(clobber (match_dup 0))
12745 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
12746
12747 (define_peephole2
12748 [(match_scratch:SI 0 "r")
12749 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
12750 (clobber (reg:CC 17))])]
12751 "optimize_size || !TARGET_SUB_ESP_8"
12752 [(clobber (match_dup 0))
12753 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
12754 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
12755
12756 ;; Convert epilogue deallocator to pop.
12757 (define_peephole2
12758 [(match_scratch:SI 0 "r")
12759 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12760 (set (reg:SI 6) (reg:SI 6))
12761 (clobber (reg:CC 17))])]
12762 "optimize_size || !TARGET_ADD_ESP_4"
12763 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12764 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12765 (set (reg:SI 6) (reg:SI 6))])]
12766 "")
12767
12768 ;; Two pops case is tricky, since pop causes dependency on destination register.
12769 ;; We use two registers if available.
12770 (define_peephole2
12771 [(match_scratch:SI 0 "r")
12772 (match_scratch:SI 1 "r")
12773 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12774 (set (reg:SI 6) (reg:SI 6))
12775 (clobber (reg:CC 17))])]
12776 "optimize_size || !TARGET_ADD_ESP_8"
12777 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12778 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12779 (set (reg:SI 6) (reg:SI 6))])
12780 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
12781 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12782 "")
12783
12784 (define_peephole2
12785 [(match_scratch:SI 0 "r")
12786 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12787 (set (reg:SI 6) (reg:SI 6))
12788 (clobber (reg:CC 17))])]
12789 "optimize_size"
12790 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12791 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12792 (set (reg:SI 6) (reg:SI 6))])
12793 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12794 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12795 "")
12796
12797 ;; Convert esp additions to pop.
12798 (define_peephole2
12799 [(match_scratch:SI 0 "r")
12800 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
12801 (clobber (reg:CC 17))])]
12802 ""
12803 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12804 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12805 "")
12806
12807 ;; Two pops case is tricky, since pop causes dependency on destination register.
12808 ;; We use two registers if available.
12809 (define_peephole2
12810 [(match_scratch:SI 0 "r")
12811 (match_scratch:SI 1 "r")
12812 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12813 (clobber (reg:CC 17))])]
12814 ""
12815 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12816 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
12817 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
12818 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12819 "")
12820
12821 (define_peephole2
12822 [(match_scratch:SI 0 "r")
12823 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
12824 (clobber (reg:CC 17))])]
12825 "optimize_size"
12826 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12827 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
12828 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
12829 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
12830 "")
12831 \f
12832 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
12833 ;; required and register dies.
12834 (define_peephole2
12835 [(set (reg 17)
12836 (compare (match_operand:SI 0 "register_operand" "")
12837 (match_operand:SI 1 "incdec_operand" "")))]
12838 "ix86_match_ccmode (insn, CCGCmode)
12839 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12840 [(parallel [(set (reg:CCGC 17)
12841 (compare:CCGC (match_dup 0)
12842 (match_dup 1)))
12843 (clobber (match_dup 0))])]
12844 "")
12845
12846 (define_peephole2
12847 [(set (reg 17)
12848 (compare (match_operand:HI 0 "register_operand" "")
12849 (match_operand:HI 1 "incdec_operand" "")))]
12850 "ix86_match_ccmode (insn, CCGCmode)
12851 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12852 [(parallel [(set (reg:CCGC 17)
12853 (compare:CCGC (match_dup 0)
12854 (match_dup 1)))
12855 (clobber (match_dup 0))])]
12856 "")
12857
12858 (define_peephole2
12859 [(set (reg 17)
12860 (compare (match_operand:QI 0 "register_operand" "")
12861 (match_operand:QI 1 "incdec_operand" "")))]
12862 "ix86_match_ccmode (insn, CCGCmode)
12863 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12864 [(parallel [(set (reg:CCGC 17)
12865 (compare:CCGC (match_dup 0)
12866 (match_dup 1)))
12867 (clobber (match_dup 0))])]
12868 "")
12869
12870 ;; Convert compares with 128 to shorter add -128
12871 (define_peephole2
12872 [(set (reg 17)
12873 (compare (match_operand:SI 0 "register_operand" "")
12874 (const_int 128)))]
12875 "ix86_match_ccmode (insn, CCGCmode)
12876 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12877 [(parallel [(set (reg:CCGC 17)
12878 (compare:CCGC (match_dup 0)
12879 (const_int 128)))
12880 (clobber (match_dup 0))])]
12881 "")
12882
12883 (define_peephole2
12884 [(set (reg 17)
12885 (compare (match_operand:HI 0 "register_operand" "")
12886 (const_int 128)))]
12887 "ix86_match_ccmode (insn, CCGCmode)
12888 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
12889 [(parallel [(set (reg:CCGC 17)
12890 (compare:CCGC (match_dup 0)
12891 (const_int 128)))
12892 (clobber (match_dup 0))])]
12893 "")
12894 \f
12895 ;; Call-value patterns last so that the wildcard operand does not
12896 ;; disrupt insn-recog's switch tables.
12897
12898 (define_insn "*call_value_pop_0"
12899 [(set (match_operand 0 "" "")
12900 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
12901 (match_operand:SI 2 "" "")))
12902 (set (reg:SI 7) (plus:SI (reg:SI 7)
12903 (match_operand:SI 3 "immediate_operand" "")))]
12904 ""
12905 "*
12906 {
12907 if (SIBLING_CALL_P (insn))
12908 return \"jmp\\t%P1\";
12909 else
12910 return \"call\\t%P1\";
12911 }"
12912 [(set_attr "type" "callv")])
12913
12914 (define_insn "*call_value_pop_1"
12915 [(set (match_operand 0 "" "")
12916 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
12917 (match_operand:SI 2 "" "")))
12918 (set (reg:SI 7) (plus:SI (reg:SI 7)
12919 (match_operand:SI 3 "immediate_operand" "i")))]
12920 ""
12921 "*
12922 {
12923 if (constant_call_address_operand (operands[1], QImode))
12924 {
12925 if (SIBLING_CALL_P (insn))
12926 return \"jmp\\t%P1\";
12927 else
12928 return \"call\\t%P1\";
12929 }
12930 if (SIBLING_CALL_P (insn))
12931 return \"jmp\\t%A1\";
12932 else
12933 return \"call\\t%A1\";
12934 }"
12935 [(set_attr "type" "callv")])
12936
12937 (define_insn "*call_value_0"
12938 [(set (match_operand 0 "" "")
12939 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
12940 (match_operand:SI 2 "" "")))]
12941 ""
12942 "*
12943 {
12944 if (SIBLING_CALL_P (insn))
12945 return \"jmp\\t%P1\";
12946 else
12947 return \"call\\t%P1\";
12948 }"
12949 [(set_attr "type" "callv")])
12950
12951 (define_insn "*call_value_1"
12952 [(set (match_operand 0 "" "")
12953 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
12954 (match_operand:SI 2 "" "")))]
12955 ""
12956 "*
12957 {
12958 if (constant_call_address_operand (operands[1], QImode))
12959 {
12960 if (SIBLING_CALL_P (insn))
12961 return \"jmp\\t%P1\";
12962 else
12963 return \"call\\t%P1\";
12964 }
12965 if (SIBLING_CALL_P (insn))
12966 return \"jmp\\t%A1\";
12967 else
12968 return \"call\\t%A1\";
12969 }"
12970 [(set_attr "type" "callv")])
12971 \f
12972 (define_insn "trap"
12973 [(trap_if (const_int 1) (const_int 5))]
12974 ""
12975 "int\\t$5")
12976
12977 ;;; ix86 doesn't have conditional trap instructions, but we fake them
12978 ;;; for the sake of bounds checking. By emitting bounds checks as
12979 ;;; conditional traps rather than as conditional jumps around
12980 ;;; unconditional traps we avoid introducing spurious basic-block
12981 ;;; boundaries and facilitate elimination of redundant checks. In
12982 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
12983 ;;; interrupt 5.
12984 ;;;
12985 ;;; FIXME: Static branch prediction rules for ix86 are such that
12986 ;;; forward conditional branches predict as untaken. As implemented
12987 ;;; below, pseudo conditional traps violate that rule. We should use
12988 ;;; .pushsection/.popsection to place all of the `int 5's in a special
12989 ;;; section loaded at the end of the text segment and branch forward
12990 ;;; there on bounds-failure, and then jump back immediately (in case
12991 ;;; the system chooses to ignore bounds violations, or to report
12992 ;;; violations and continue execution).
12993
12994 (define_expand "conditional_trap"
12995 [(trap_if (match_operator 0 "comparison_operator"
12996 [(match_dup 2) (const_int 0)])
12997 (match_operand 1 "const_int_operand" ""))]
12998 ""
12999 "
13000 {
13001 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
13002 ix86_expand_compare (GET_CODE (operands[0]),
13003 NULL_RTX, NULL_RTX),
13004 operands[1]));
13005 DONE;
13006 }")
13007
13008 (define_insn ""
13009 [(trap_if (match_operator 0 "comparison_operator"
13010 [(reg 17) (const_int 0)])
13011 (match_operand 1 "const_int_operand" ""))]
13012 ""
13013 "*
13014 {
13015 operands[2] = gen_label_rtx ();
13016 output_asm_insn (\"j%c0\\t%l2\; int\\t%1\", operands);
13017 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
13018 CODE_LABEL_NUMBER (operands[2]));
13019 RET;
13020 }")
13021
13022 ;; Pentium III SIMD instructions.
13023
13024 ;; Moves for SSE/MMX regs.
13025
13026 (define_insn "movv4sf_internal"
13027 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13028 (match_operand:V4SF 1 "general_operand" "xm,x"))]
13029 "TARGET_SSE"
13030 ;; @@@ let's try to use movaps here.
13031 "movaps\\t{%1, %0|%0, %1}"
13032 [(set_attr "type" "sse")])
13033
13034 (define_insn "movv4si_internal"
13035 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
13036 (match_operand:V4SI 1 "general_operand" "xm,x"))]
13037 "TARGET_SSE"
13038 ;; @@@ let's try to use movaps here.
13039 "movaps\\t{%1, %0|%0, %1}"
13040 [(set_attr "type" "sse")])
13041
13042 (define_insn "movv8qi_internal"
13043 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
13044 (match_operand:V8QI 1 "general_operand" "ym,y"))]
13045 "TARGET_MMX"
13046 "movq\\t{%1, %0|%0, %1}"
13047 [(set_attr "type" "mmx")])
13048
13049 (define_insn "movv4hi_internal"
13050 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
13051 (match_operand:V4HI 1 "general_operand" "ym,y"))]
13052 "TARGET_MMX"
13053 "movq\\t{%1, %0|%0, %1}"
13054 [(set_attr "type" "mmx")])
13055
13056 (define_insn "movv2si_internal"
13057 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
13058 (match_operand:V2SI 1 "general_operand" "ym,y"))]
13059 "TARGET_MMX"
13060 "movq\\t{%1, %0|%0, %1}"
13061 [(set_attr "type" "mmx")])
13062
13063 (define_expand "movti"
13064 [(set (match_operand:TI 0 "general_operand" "")
13065 (match_operand:TI 1 "general_operand" ""))]
13066 "TARGET_SSE"
13067 "
13068 {
13069 /* For constants other than zero into memory. We do not know how the
13070 instructions used to build constants modify the upper 64 bits
13071 of the register, once we have that information we may be able
13072 to handle some of them more efficiently. */
13073 if ((reload_in_progress | reload_completed) == 0
13074 && register_operand (operands[0], TImode)
13075 && CONSTANT_P (operands[1]))
13076 {
13077 rtx addr = gen_reg_rtx (Pmode);
13078
13079 emit_move_insn (addr, XEXP (force_const_mem (TImode, operands[1]), 0));
13080 operands[1] = gen_rtx_MEM (TImode, addr);
13081 }
13082
13083 /* Make operand1 a register if it isn't already. */
13084 if ((reload_in_progress | reload_completed) == 0
13085 && !register_operand (operands[0], TImode)
13086 && !register_operand (operands[1], TImode)
13087 && operands[1] != CONST0_RTX (TImode))
13088 {
13089 rtx temp = force_reg (TImode, operands[1]);
13090 emit_move_insn (operands[0], temp);
13091 DONE;
13092 }
13093 }")
13094
13095 (define_expand "movv4sf"
13096 [(set (match_operand:V4SF 0 "general_operand" "")
13097 (match_operand:V4SF 1 "general_operand" ""))]
13098 "TARGET_SSE"
13099 "
13100 {
13101 /* For constants other than zero into memory. We do not know how the
13102 instructions used to build constants modify the upper 64 bits
13103 of the register, once we have that information we may be able
13104 to handle some of them more efficiently. */
13105 if ((reload_in_progress | reload_completed) == 0
13106 && register_operand (operands[0], V4SFmode)
13107 && CONSTANT_P (operands[1]))
13108 {
13109 rtx addr = gen_reg_rtx (Pmode);
13110
13111 emit_move_insn (addr, XEXP (force_const_mem (V4SFmode, operands[1]), 0));
13112 operands[1] = gen_rtx_MEM (V4SFmode, addr);
13113 }
13114
13115 /* Make operand1 a register if it isn't already. */
13116 if ((reload_in_progress | reload_completed) == 0
13117 && !register_operand (operands[0], V4SFmode)
13118 && !register_operand (operands[1], V4SFmode)
13119 && operands[1] != CONST0_RTX (V4SFmode))
13120 {
13121 rtx temp = force_reg (V4SFmode, operands[1]);
13122 emit_move_insn (operands[0], temp);
13123 DONE;
13124 }
13125 }")
13126
13127 (define_expand "movv4si"
13128 [(set (match_operand:V4SI 0 "general_operand" "")
13129 (match_operand:V4SI 1 "general_operand" ""))]
13130 "TARGET_MMX"
13131 "
13132 {
13133 /* For constants other than zero into memory. We do not know how the
13134 instructions used to build constants modify the upper 64 bits
13135 of the register, once we have that information we may be able
13136 to handle some of them more efficiently. */
13137 if ((reload_in_progress | reload_completed) == 0
13138 && register_operand (operands[0], V4SImode)
13139 && CONSTANT_P (operands[1]))
13140 {
13141 rtx addr = gen_reg_rtx (Pmode);
13142
13143 emit_move_insn (addr, XEXP (force_const_mem (V4SImode, operands[1]), 0));
13144 operands[1] = gen_rtx_MEM (V4SImode, addr);
13145 }
13146
13147 /* Make operand1 a register if it isn't already. */
13148 if ((reload_in_progress | reload_completed) == 0
13149 && !register_operand (operands[0], V4SImode)
13150 && !register_operand (operands[1], V4SImode)
13151 && operands[1] != CONST0_RTX (V4SImode))
13152 {
13153 rtx temp = force_reg (V4SImode, operands[1]);
13154 emit_move_insn (operands[0], temp);
13155 DONE;
13156 }
13157 }")
13158
13159 (define_expand "movv2si"
13160 [(set (match_operand:V2SI 0 "general_operand" "")
13161 (match_operand:V2SI 1 "general_operand" ""))]
13162 "TARGET_MMX"
13163 "
13164 {
13165 /* For constants other than zero into memory. We do not know how the
13166 instructions used to build constants modify the upper 64 bits
13167 of the register, once we have that information we may be able
13168 to handle some of them more efficiently. */
13169 if ((reload_in_progress | reload_completed) == 0
13170 && register_operand (operands[0], V2SImode)
13171 && CONSTANT_P (operands[1]))
13172 {
13173 rtx addr = gen_reg_rtx (Pmode);
13174
13175 emit_move_insn (addr, XEXP (force_const_mem (V2SImode, operands[1]), 0));
13176 operands[1] = gen_rtx_MEM (V2SImode, addr);
13177 }
13178
13179 /* Make operand1 a register if it isn't already. */
13180 if ((reload_in_progress | reload_completed) == 0
13181 && !register_operand (operands[0], V2SImode)
13182 && !register_operand (operands[1], V2SImode)
13183 && operands[1] != CONST0_RTX (V2SImode))
13184 {
13185 rtx temp = force_reg (V2SImode, operands[1]);
13186 emit_move_insn (operands[0], temp);
13187 DONE;
13188 }
13189 }")
13190
13191 (define_expand "movv4hi"
13192 [(set (match_operand:V4HI 0 "general_operand" "")
13193 (match_operand:V4HI 1 "general_operand" ""))]
13194 "TARGET_MMX"
13195 "
13196 {
13197 /* For constants other than zero into memory. We do not know how the
13198 instructions used to build constants modify the upper 64 bits
13199 of the register, once we have that information we may be able
13200 to handle some of them more efficiently. */
13201 if ((reload_in_progress | reload_completed) == 0
13202 && register_operand (operands[0], V4HImode)
13203 && CONSTANT_P (operands[1]))
13204 {
13205 rtx addr = gen_reg_rtx (Pmode);
13206
13207 emit_move_insn (addr, XEXP (force_const_mem (V4HImode, operands[1]), 0));
13208 operands[1] = gen_rtx_MEM (V4HImode, addr);
13209 }
13210
13211 /* Make operand1 a register if it isn't already. */
13212 if ((reload_in_progress | reload_completed) == 0
13213 && !register_operand (operands[0], V4HImode)
13214 && !register_operand (operands[1], V4HImode)
13215 && operands[1] != CONST0_RTX (V4HImode))
13216 {
13217 rtx temp = force_reg (V4HImode, operands[1]);
13218 emit_move_insn (operands[0], temp);
13219 DONE;
13220 }
13221 }")
13222
13223 (define_expand "movv8qi"
13224 [(set (match_operand:V8QI 0 "general_operand" "")
13225 (match_operand:V8QI 1 "general_operand" ""))]
13226 "TARGET_MMX"
13227 "
13228 {
13229 /* For constants other than zero into memory. We do not know how the
13230 instructions used to build constants modify the upper 64 bits
13231 of the register, once we have that information we may be able
13232 to handle some of them more efficiently. */
13233 if ((reload_in_progress | reload_completed) == 0
13234 && register_operand (operands[0], V8QImode)
13235 && CONSTANT_P (operands[1]))
13236 {
13237 rtx addr = gen_reg_rtx (Pmode);
13238
13239 emit_move_insn (addr, XEXP (force_const_mem (V8QImode, operands[1]), 0));
13240 operands[1] = gen_rtx_MEM (V8QImode, addr);
13241 }
13242
13243 /* Make operand1 a register if it isn't already. */
13244 if ((reload_in_progress | reload_completed) == 0
13245 && !register_operand (operands[0], V8QImode)
13246 && !register_operand (operands[1], V8QImode)
13247 && operands[1] != CONST0_RTX (V8QImode))
13248 {
13249 rtx temp = force_reg (V8QImode, operands[1]);
13250 emit_move_insn (operands[0], temp);
13251 DONE;
13252 }
13253 }")
13254
13255 (define_insn_and_split "*pushti"
13256 [(set (match_operand:TI 0 "push_operand" "=<")
13257 (match_operand:TI 1 "nonmemory_operand" "x"))]
13258 "TARGET_SSE"
13259 "#"
13260 ""
13261 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
13262 (set (mem:TI (reg:SI 7)) (match_dup 1))]
13263 ""
13264 [(set_attr "type" "sse")])
13265
13266 (define_insn_and_split "*pushv4sf"
13267 [(set (match_operand:V4SF 0 "push_operand" "=<")
13268 (match_operand:V4SF 1 "nonmemory_operand" "x"))]
13269 "TARGET_SSE"
13270 "#"
13271 ""
13272 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
13273 (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
13274 ""
13275 [(set_attr "type" "sse")])
13276
13277 (define_insn_and_split "*pushv4si"
13278 [(set (match_operand:V4SI 0 "push_operand" "=<")
13279 (match_operand:V4SI 1 "nonmemory_operand" "x"))]
13280 "TARGET_SSE"
13281 "#"
13282 ""
13283 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
13284 (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
13285 ""
13286 [(set_attr "type" "sse")])
13287
13288 (define_insn_and_split "*pushv2si"
13289 [(set (match_operand:V2SI 0 "push_operand" "=<")
13290 (match_operand:V2SI 1 "nonmemory_operand" "y"))]
13291 "TARGET_MMX"
13292 "#"
13293 ""
13294 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13295 (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
13296 ""
13297 [(set_attr "type" "mmx")])
13298
13299 (define_insn_and_split "*pushv4hi"
13300 [(set (match_operand:V4HI 0 "push_operand" "=<")
13301 (match_operand:V4HI 1 "nonmemory_operand" "y"))]
13302 "TARGET_MMX"
13303 "#"
13304 ""
13305 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13306 (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
13307 ""
13308 [(set_attr "type" "mmx")])
13309
13310 (define_insn_and_split "*pushv8qi"
13311 [(set (match_operand:V8QI 0 "push_operand" "=<")
13312 (match_operand:V8QI 1 "nonmemory_operand" "y"))]
13313 "TARGET_MMX"
13314 "#"
13315 ""
13316 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
13317 (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
13318 ""
13319 [(set_attr "type" "mmx")])
13320
13321 (define_insn "movti_internal"
13322 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,m")
13323 (match_operand:TI 1 "general_operand" "xm,x"))]
13324 "TARGET_SSE"
13325 "@
13326 movaps\\t{%1, %0|%0, %1}
13327 movaps\\t{%1, %0|%0, %1}"
13328 [(set_attr "type" "sse")])
13329
13330 ;; These two patterns are useful for specifying exactly whether to use
13331 ;; movaps or movups
13332 (define_insn "sse_movaps"
13333 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13334 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 38))]
13335 "TARGET_SSE"
13336 "@
13337 movaps\\t{%1, %0|%0, %1}
13338 movaps\\t{%1, %0|%0, %1}"
13339 [(set_attr "type" "sse")])
13340
13341 (define_insn "sse_movups"
13342 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13343 (unspec:V4SF [(match_operand:V4SF 1 "general_operand" "xm,x")] 39))]
13344 "TARGET_SSE"
13345 "@
13346 movups\\t{%1, %0|%0, %1}
13347 movups\\t{%1, %0|%0, %1}"
13348 [(set_attr "type" "sse")])
13349
13350
13351 ;; SSE Strange Moves.
13352
13353 (define_insn "sse_movmskps"
13354 [(set (match_operand:SI 0 "register_operand" "=r")
13355 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
13356 "TARGET_SSE"
13357 "movmskps\\t{%1, %0|%0, %1}"
13358 [(set_attr "type" "sse")])
13359
13360 (define_insn "mmx_pmovmskb"
13361 [(set (match_operand:SI 0 "register_operand" "=r")
13362 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
13363 "TARGET_SSE"
13364 "pmovmskb\\t{%1, %0|%0, %1}"
13365 [(set_attr "type" "sse")])
13366
13367 (define_insn "mmx_maskmovq"
13368 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
13369 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
13370 (match_operand:V8QI 2 "register_operand" "y")] 32))]
13371 "TARGET_SSE"
13372 ;; @@@ check ordering of operands in intel/nonintel syntax
13373 "maskmovq\\t{%2, %1|%1, %2}"
13374 [(set_attr "type" "sse")])
13375
13376 (define_insn "sse_movntv4sf"
13377 [(set (match_operand:V4SF 0 "memory_operand" "=m")
13378 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
13379 "TARGET_SSE"
13380 "movntps\\t{%1, %0|%0, %1}"
13381 [(set_attr "type" "sse")])
13382
13383 (define_insn "sse_movntdi"
13384 [(set (match_operand:DI 0 "memory_operand" "=m")
13385 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
13386 "TARGET_SSE"
13387 "movntq\\t{%1, %0|%0, %1}"
13388 [(set_attr "type" "sse")])
13389
13390 (define_insn "sse_movhlps"
13391 [(set (match_operand:V4SF 0 "register_operand" "=x")
13392 (vec_merge:V4SF
13393 (match_operand:V4SF 1 "register_operand" "0")
13394 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
13395 (parallel [(const_int 2)
13396 (const_int 3)
13397 (const_int 0)
13398 (const_int 1)]))
13399 (const_int 3)))]
13400 "TARGET_SSE"
13401 "movhlps\\t{%2, %0|%0, %2}"
13402 [(set_attr "type" "sse")])
13403
13404 (define_insn "sse_movlhps"
13405 [(set (match_operand:V4SF 0 "register_operand" "=x")
13406 (vec_merge:V4SF
13407 (match_operand:V4SF 1 "register_operand" "0")
13408 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
13409 (parallel [(const_int 2)
13410 (const_int 3)
13411 (const_int 0)
13412 (const_int 1)]))
13413 (const_int 12)))]
13414 "TARGET_SSE"
13415 "movlhps\\t{%2, %0|%0, %2}"
13416 [(set_attr "type" "sse")])
13417
13418 (define_insn "sse_movhps"
13419 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13420 (vec_merge:V4SF
13421 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
13422 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
13423 (const_int 12)))]
13424 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
13425 "movhps\\t{%2, %0|%0, %2}"
13426 [(set_attr "type" "sse")])
13427
13428 (define_insn "sse_movlps"
13429 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
13430 (vec_merge:V4SF
13431 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
13432 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
13433 (const_int 3)))]
13434 "TARGET_SSE && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
13435 "movlps\\t{%2, %0|%0, %2}"
13436 [(set_attr "type" "sse")])
13437
13438 (define_insn "sse_loadss"
13439 [(set (match_operand:V4SF 0 "register_operand" "=x")
13440 (vec_merge:V4SF
13441 (match_operand:V4SF 1 "memory_operand" "m")
13442 (vec_duplicate:V4SF (float:SF (const_int 0)))
13443 (const_int 1)))]
13444 "TARGET_SSE"
13445 "movss\\t{%1, %0|%0, %1}"
13446 [(set_attr "type" "sse")])
13447
13448 (define_insn "sse_movss"
13449 [(set (match_operand:V4SF 0 "register_operand" "=x")
13450 (vec_merge:V4SF
13451 (match_operand:V4SF 1 "register_operand" "0")
13452 (match_operand:V4SF 2 "register_operand" "x")
13453 (const_int 1)))]
13454 "TARGET_SSE"
13455 "movss\\t{%2, %0|%0, %2}"
13456 [(set_attr "type" "sse")])
13457
13458 (define_insn "sse_storess"
13459 [(set (match_operand:SF 0 "memory_operand" "=m")
13460 (vec_select:SF
13461 (match_operand:V4SF 1 "register_operand" "x")
13462 (parallel [(const_int 0)])))]
13463 "TARGET_SSE"
13464 "movss\\t{%1, %0|%0, %1}"
13465 [(set_attr "type" "sse")])
13466
13467 (define_insn "sse_shufps"
13468 [(set (match_operand:V4SF 0 "register_operand" "=x")
13469 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
13470 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
13471 (match_operand:SI 3 "immediate_operand" "i")] 41))]
13472 "TARGET_SSE"
13473 ;; @@@ check operand order for intel/nonintel syntax
13474 "shufps\\t{%3, %2, %0|%0, %2, %3}"
13475 [(set_attr "type" "sse")])
13476
13477
13478 ;; SSE arithmetic
13479
13480 (define_insn "addv4sf3"
13481 [(set (match_operand:V4SF 0 "register_operand" "=x")
13482 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13483 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13484 "TARGET_SSE"
13485 "addps\\t{%2, %0|%0, %2}"
13486 [(set_attr "type" "sse")])
13487
13488 (define_insn "vmaddv4sf3"
13489 [(set (match_operand:V4SF 0 "register_operand" "=x")
13490 (vec_merge:V4SF (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13491 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13492 (match_dup 1)
13493 (const_int 1)))]
13494 "TARGET_SSE"
13495 "addss\\t{%2, %0|%0, %2}"
13496 [(set_attr "type" "sse")])
13497
13498 (define_insn "subv4sf3"
13499 [(set (match_operand:V4SF 0 "register_operand" "=x")
13500 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13501 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13502 "TARGET_SSE"
13503 "subps\\t{%2, %0|%0, %2}"
13504 [(set_attr "type" "sse")])
13505
13506 (define_insn "vmsubv4sf3"
13507 [(set (match_operand:V4SF 0 "register_operand" "=x")
13508 (vec_merge:V4SF (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
13509 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13510 (match_dup 1)
13511 (const_int 1)))]
13512 "TARGET_SSE"
13513 "subss\\t{%2, %0|%0, %2}"
13514 [(set_attr "type" "sse")])
13515
13516 (define_insn "mulv4sf3"
13517 [(set (match_operand:V4SF 0 "register_operand" "=x")
13518 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
13519 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13520 "TARGET_SSE"
13521 "mulps\\t{%2, %0|%0, %2}"
13522 [(set_attr "type" "sse")])
13523
13524 (define_insn "vmmulv4sf3"
13525 [(set (match_operand:V4SF 0 "register_operand" "=x")
13526 (vec_merge:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
13527 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13528 (match_dup 1)
13529 (const_int 1)))]
13530 "TARGET_SSE"
13531 "mulss\\t{%2, %0|%0, %2}"
13532 [(set_attr "type" "sse")])
13533
13534 (define_insn "divv4sf3"
13535 [(set (match_operand:V4SF 0 "register_operand" "=x")
13536 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
13537 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13538 "TARGET_SSE"
13539 "divps\\t{%2, %0|%0, %2}"
13540 [(set_attr "type" "sse")])
13541
13542 (define_insn "vmdivv4sf3"
13543 [(set (match_operand:V4SF 0 "register_operand" "=x")
13544 (vec_merge:V4SF (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
13545 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13546 (match_dup 1)
13547 (const_int 1)))]
13548 "TARGET_SSE"
13549 "divss\\t{%2, %0|%0, %2}"
13550 [(set_attr "type" "sse")])
13551
13552
13553 ;; SSE square root/reciprocal
13554
13555 (define_insn "rcpv4sf2"
13556 [(set (match_operand:V4SF 0 "register_operand" "=x")
13557 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42))]
13558 "TARGET_SSE"
13559 "rcpps\\t{%1, %0|%0, %1}"
13560 [(set_attr "type" "sse")])
13561
13562 (define_insn "vmrcpv4sf2"
13563 [(set (match_operand:V4SF 0 "register_operand" "=x")
13564 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 42)
13565 (match_operand:V4SF 2 "register_operand" "0")
13566 (const_int 1)))]
13567 "TARGET_SSE"
13568 "rcpss\\t{%1, %0|%0, %1}"
13569 [(set_attr "type" "sse")])
13570
13571 (define_insn "rsqrtv4sf2"
13572 [(set (match_operand:V4SF 0 "register_operand" "=x")
13573 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43))]
13574 "TARGET_SSE"
13575 "rsqrtps\\t{%1, %0|%0, %1}"
13576 [(set_attr "type" "sse")])
13577
13578 (define_insn "vmrsqrtv4sf2"
13579 [(set (match_operand:V4SF 0 "register_operand" "=x")
13580 (vec_merge:V4SF (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "xm")] 43)
13581 (match_operand:V4SF 2 "register_operand" "0")
13582 (const_int 1)))]
13583 "TARGET_SSE"
13584 "rsqrtss\\t{%1, %0|%0, %1}"
13585 [(set_attr "type" "sse")])
13586
13587 (define_insn "sqrtv4sf2"
13588 [(set (match_operand:V4SF 0 "register_operand" "=x")
13589 (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm")))]
13590 "TARGET_SSE"
13591 "sqrtps\\t{%1, %0|%0, %1}"
13592 [(set_attr "type" "sse")])
13593
13594 (define_insn "vmsqrtv4sf2"
13595 [(set (match_operand:V4SF 0 "register_operand" "=x")
13596 (vec_merge:V4SF (sqrt:V4SF (match_operand:V4SF 1 "register_operand" "xm"))
13597 (match_operand:V4SF 2 "register_operand" "0")
13598 (const_int 1)))]
13599 "TARGET_SSE"
13600 "sqrtss\\t{%1, %0|%0, %1}"
13601 [(set_attr "type" "sse")])
13602
13603
13604 ;; SSE logical operations.
13605
13606 ;; These are not called andti3 etc. because we really really don't want
13607 ;; the compiler to widen DImode ands to TImode ands and then try to move
13608 ;; into DImode subregs of SSE registers, and them together, and move out
13609 ;; of DImode subregs again!
13610
13611 (define_insn "sse_andti3"
13612 [(set (match_operand:TI 0 "register_operand" "=x")
13613 (and:TI (match_operand:TI 1 "register_operand" "0")
13614 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13615 "TARGET_SSE"
13616 "andps\\t{%2, %0|%0, %2}"
13617 [(set_attr "type" "sse")])
13618
13619 (define_insn "sse_nandti3"
13620 [(set (match_operand:TI 0 "register_operand" "=x")
13621 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
13622 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13623 "TARGET_SSE"
13624 "andnps\\t{%2, %0|%0, %2}"
13625 [(set_attr "type" "sse")])
13626
13627 (define_insn "sse_iorti3"
13628 [(set (match_operand:TI 0 "register_operand" "=x")
13629 (ior:TI (match_operand:TI 1 "register_operand" "0")
13630 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13631 "TARGET_SSE"
13632 "iorps\\t{%2, %0|%0, %2}"
13633 [(set_attr "type" "sse")])
13634
13635 (define_insn "sse_xorti3"
13636 [(set (match_operand:TI 0 "register_operand" "=x")
13637 (xor:TI (match_operand:TI 1 "register_operand" "0")
13638 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
13639 "TARGET_SSE"
13640 "xorps\\t{%2, %0|%0, %2}"
13641 [(set_attr "type" "sse")])
13642
13643 ;; Use xor, but don't show input operands so they aren't live before
13644 ;; this insn.
13645 (define_insn "sse_clrti"
13646 [(set (match_operand:TI 0 "register_operand" "=x")
13647 (unspec:TI [(const_int 0)] 45))]
13648 "TARGET_SSE"
13649 "xorps\\t{%0, %0|%0, %0}"
13650 [(set_attr "type" "sse")])
13651
13652
13653 ;; SSE mask-generating compares
13654
13655 (define_insn "maskcmpv4sf3"
13656 [(set (match_operand:V4SI 0 "register_operand" "=x")
13657 (match_operator:V4SI 3 "sse_comparison_operator"
13658 [(match_operand:V4SF 1 "register_operand" "0")
13659 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
13660 "TARGET_SSE"
13661 "*
13662 {
13663 switch (GET_CODE (operands[3]))
13664 {
13665 case EQ:
13666 return \"cmpeqps\\t{%2, %0|%0, %2}\";
13667 case LT:
13668 return \"cmpltps\\t{%2, %0|%0, %2}\";
13669 case LE:
13670 return \"cmpleps\\t{%2, %0|%0, %2}\";
13671 case UNORDERED:
13672 return \"cmpunordps\\t{%2, %0|%0, %2}\";
13673 default:
13674 abort ();
13675 }
13676 }"
13677 [(set_attr "type" "sse")])
13678
13679 (define_insn "maskncmpv4sf3"
13680 [(set (match_operand:V4SI 0 "register_operand" "=x")
13681 (not:V4SI
13682 (match_operator:V4SI 3 "sse_comparison_operator"
13683 [(match_operand:V4SF 1 "register_operand" "0")
13684 (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
13685 "TARGET_SSE"
13686 "*
13687 {
13688 switch (GET_CODE (operands[3]))
13689 {
13690 case EQ:
13691 return \"cmpneqps\\t{%2, %0|%0, %2}\";
13692 case LT:
13693 return \"cmpnltps\\t{%2, %0|%0, %2}\";
13694 case LE:
13695 return \"cmpnleps\\t{%2, %0|%0, %2}\";
13696 case UNORDERED:
13697 return \"cmpordps\\t{%2, %0|%0, %2}\";
13698 default:
13699 abort ();
13700 }
13701 }"
13702 [(set_attr "type" "sse")])
13703
13704 (define_insn "vmmaskcmpv4sf3"
13705 [(set (match_operand:V4SI 0 "register_operand" "=x")
13706 (vec_merge:V4SI
13707 (match_operator:V4SI 3 "sse_comparison_operator"
13708 [(match_operand:V4SF 1 "register_operand" "0")
13709 (match_operand:V4SF 2 "nonimmediate_operand" "x")])
13710 (match_dup 1)
13711 (const_int 1)))]
13712 "TARGET_SSE"
13713 "*
13714 {
13715 switch (GET_CODE (operands[3]))
13716 {
13717 case EQ:
13718 return \"cmpeqss\\t{%2, %0|%0, %2}\";
13719 case LT:
13720 return \"cmpltss\\t{%2, %0|%0, %2}\";
13721 case LE:
13722 return \"cmpless\\t{%2, %0|%0, %2}\";
13723 case UNORDERED:
13724 return \"cmpunordss\\t{%2, %0|%0, %2}\";
13725 default:
13726 abort ();
13727 }
13728 }"
13729 [(set_attr "type" "sse")])
13730
13731 (define_insn "vmmaskncmpv4sf3"
13732 [(set (match_operand:V4SI 0 "register_operand" "=x")
13733 (vec_merge:V4SI
13734 (not:V4SI
13735 (match_operator:V4SI 3 "sse_comparison_operator"
13736 [(match_operand:V4SF 1 "register_operand" "0")
13737 (match_operand:V4SF 2 "nonimmediate_operand" "x")]))
13738 (subreg:V4SI (match_dup 1) 0)
13739 (const_int 1)))]
13740 "TARGET_SSE"
13741 "*
13742 {
13743 switch (GET_CODE (operands[3]))
13744 {
13745 case EQ:
13746 return \"cmpneqss\\t{%2, %0|%0, %2}\";
13747 case LT:
13748 return \"cmpnltss\\t{%2, %0|%0, %2}\";
13749 case LE:
13750 return \"cmpnless\\t{%2, %0|%0, %2}\";
13751 case UNORDERED:
13752 return \"cmpordss\\t{%2, %0|%0, %2}\";
13753 default:
13754 abort ();
13755 }
13756 }"
13757 [(set_attr "type" "sse")])
13758
13759 (define_insn "sse_comi"
13760 [(set (reg:CCFP 17)
13761 (match_operator:CCFP 2 "sse_comparison_operator"
13762 [(vec_select:SF
13763 (match_operand:V4SF 0 "register_operand" "x")
13764 (parallel [(const_int 0)]))
13765 (vec_select:SF
13766 (match_operand:V4SF 1 "register_operand" "x")
13767 (parallel [(const_int 0)]))]))]
13768 "TARGET_SSE"
13769 "comiss\\t{%2, %0|%0, %2}"
13770 [(set_attr "type" "sse")])
13771
13772 (define_insn "sse_ucomi"
13773 [(set (reg:CCFPU 17)
13774 (match_operator:CCFPU 2 "sse_comparison_operator"
13775 [(vec_select:SF
13776 (match_operand:V4SF 0 "register_operand" "x")
13777 (parallel [(const_int 0)]))
13778 (vec_select:SF
13779 (match_operand:V4SF 1 "register_operand" "x")
13780 (parallel [(const_int 0)]))]))]
13781 "TARGET_SSE"
13782 "ucomiss\\t{%2, %0|%0, %2}"
13783 [(set_attr "type" "sse")])
13784
13785
13786 ;; SSE unpack
13787
13788 (define_insn "sse_unpckhps"
13789 [(set (match_operand:V4SF 0 "register_operand" "=x")
13790 (vec_merge:V4SF
13791 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
13792 (parallel [(const_int 2)
13793 (const_int 0)
13794 (const_int 3)
13795 (const_int 1)]))
13796 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
13797 (parallel [(const_int 0)
13798 (const_int 2)
13799 (const_int 1)
13800 (const_int 3)]))
13801 (const_int 5)))]
13802 "TARGET_SSE"
13803 "unpckhps\\t{%2, %0|%0, %2}"
13804 [(set_attr "type" "sse")])
13805
13806 (define_insn "sse_unpcklps"
13807 [(set (match_operand:V4SF 0 "register_operand" "=x")
13808 (vec_merge:V4SF
13809 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
13810 (parallel [(const_int 0)
13811 (const_int 2)
13812 (const_int 1)
13813 (const_int 3)]))
13814 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "x")
13815 (parallel [(const_int 2)
13816 (const_int 0)
13817 (const_int 3)
13818 (const_int 1)]))
13819 (const_int 5)))]
13820 "TARGET_SSE"
13821 "unpcklps\\t{%2, %0|%0, %2}"
13822 [(set_attr "type" "sse")])
13823
13824
13825 ;; SSE min/max
13826
13827 (define_insn "smaxv4sf3"
13828 [(set (match_operand:V4SF 0 "register_operand" "=x")
13829 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
13830 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13831 "TARGET_SSE"
13832 "maxps\\t{%2, %0|%0, %2}"
13833 [(set_attr "type" "sse")])
13834
13835 (define_insn "vmsmaxv4sf3"
13836 [(set (match_operand:V4SF 0 "register_operand" "=x")
13837 (vec_merge:V4SF (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
13838 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13839 (match_dup 1)
13840 (const_int 1)))]
13841 "TARGET_SSE"
13842 "maxss\\t{%2, %0|%0, %2}"
13843 [(set_attr "type" "sse")])
13844
13845 (define_insn "sminv4sf3"
13846 [(set (match_operand:V4SF 0 "register_operand" "=x")
13847 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
13848 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
13849 "TARGET_SSE"
13850 "minps\\t{%2, %0|%0, %2}"
13851 [(set_attr "type" "sse")])
13852
13853 (define_insn "vmsminv4sf3"
13854 [(set (match_operand:V4SF 0 "register_operand" "=x")
13855 (vec_merge:V4SF (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
13856 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
13857 (match_dup 1)
13858 (const_int 1)))]
13859 "TARGET_SSE"
13860 "minss\\t{%2, %0|%0, %2}"
13861 [(set_attr "type" "sse")])
13862
13863
13864 ;; SSE <-> integer/MMX conversions
13865
13866 (define_insn "cvtpi2ps"
13867 [(set (match_operand:V4SF 0 "register_operand" "=x")
13868 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
13869 (vec_duplicate:V4SF
13870 (float:V2SF (match_operand:V2SI 2 "register_operand" "ym")))
13871 (const_int 12)))]
13872 "TARGET_SSE"
13873 "cvtpi2ps\\t{%2, %0|%0, %2}"
13874 [(set_attr "type" "sse")])
13875
13876 (define_insn "cvtps2pi"
13877 [(set (match_operand:V2SI 0 "register_operand" "=y")
13878 (vec_select:V2SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
13879 (parallel
13880 [(const_int 0)
13881 (const_int 1)])))]
13882 "TARGET_SSE"
13883 "cvtps2pi\\t{%1, %0|%0, %1}"
13884 [(set_attr "type" "sse")])
13885
13886 (define_insn "cvttps2pi"
13887 [(set (match_operand:V2SI 0 "register_operand" "=y")
13888 (vec_select:V2SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
13889 (parallel
13890 [(const_int 0)
13891 (const_int 1)])))]
13892 "TARGET_SSE"
13893 "cvttps2pi\\t{%1, %0|%0, %1}"
13894 [(set_attr "type" "sse")])
13895
13896 (define_insn "cvtsi2ss"
13897 [(set (match_operand:V4SF 0 "register_operand" "=x")
13898 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
13899 (vec_duplicate:V4SF
13900 (float:SF (match_operand:SI 2 "register_operand" "rm")))
13901 (const_int 15)))]
13902 "TARGET_SSE"
13903 "cvtsi2ss\\t{%2, %0|%0, %2}"
13904 [(set_attr "type" "sse")])
13905
13906 (define_insn "cvtss2si"
13907 [(set (match_operand:SI 0 "register_operand" "=y")
13908 (vec_select:SI (fix:V4SI (match_operand:V4SF 1 "register_operand" "xm"))
13909 (parallel [(const_int 0)])))]
13910 "TARGET_SSE"
13911 "cvtss2si\\t{%1, %0|%0, %1}"
13912 [(set_attr "type" "sse")])
13913
13914 (define_insn "cvttss2si"
13915 [(set (match_operand:SI 0 "register_operand" "=y")
13916 (vec_select:SI (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "xm")] 30)
13917 (parallel [(const_int 0)])))]
13918 "TARGET_SSE"
13919 "cvttss2si\\t{%1, %0|%0, %1}"
13920 [(set_attr "type" "sse")])
13921
13922
13923 ;; MMX insns
13924
13925 ;; MMX arithmetic
13926
13927 (define_insn "addv8qi3"
13928 [(set (match_operand:V8QI 0 "register_operand" "=y")
13929 (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13930 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13931 "TARGET_MMX"
13932 "paddb\\t{%2, %0|%0, %2}"
13933 [(set_attr "type" "mmx")])
13934
13935 (define_insn "addv4hi3"
13936 [(set (match_operand:V4HI 0 "register_operand" "=y")
13937 (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13938 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13939 "TARGET_MMX"
13940 "paddw\\t{%2, %0|%0, %2}"
13941 [(set_attr "type" "mmx")])
13942
13943 (define_insn "addv2si3"
13944 [(set (match_operand:V2SI 0 "register_operand" "=y")
13945 (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
13946 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
13947 "TARGET_MMX"
13948 "paddd\\t{%2, %0|%0, %2}"
13949 [(set_attr "type" "mmx")])
13950
13951 (define_insn "ssaddv8qi3"
13952 [(set (match_operand:V8QI 0 "register_operand" "=y")
13953 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13954 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13955 "TARGET_MMX"
13956 "paddsb\\t{%2, %0|%0, %2}"
13957 [(set_attr "type" "mmx")])
13958
13959 (define_insn "ssaddv4hi3"
13960 [(set (match_operand:V4HI 0 "register_operand" "=y")
13961 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13962 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13963 "TARGET_MMX"
13964 "paddsw\\t{%2, %0|%0, %2}"
13965 [(set_attr "type" "mmx")])
13966
13967 (define_insn "usaddv8qi3"
13968 [(set (match_operand:V8QI 0 "register_operand" "=y")
13969 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13970 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13971 "TARGET_MMX"
13972 "paddusb\\t{%2, %0|%0, %2}"
13973 [(set_attr "type" "mmx")])
13974
13975 (define_insn "usaddv4hi3"
13976 [(set (match_operand:V4HI 0 "register_operand" "=y")
13977 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13978 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13979 "TARGET_MMX"
13980 "paddusw\\t{%2, %0|%0, %2}"
13981 [(set_attr "type" "mmx")])
13982
13983 (define_insn "subv8qi3"
13984 [(set (match_operand:V8QI 0 "register_operand" "=y")
13985 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
13986 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
13987 "TARGET_MMX"
13988 "psubb\\t{%2, %0|%0, %2}"
13989 [(set_attr "type" "mmx")])
13990
13991 (define_insn "subv4hi3"
13992 [(set (match_operand:V4HI 0 "register_operand" "=y")
13993 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
13994 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
13995 "TARGET_MMX"
13996 "psubw\\t{%2, %0|%0, %2}"
13997 [(set_attr "type" "mmx")])
13998
13999 (define_insn "subv2si3"
14000 [(set (match_operand:V2SI 0 "register_operand" "=y")
14001 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
14002 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14003 "TARGET_MMX"
14004 "psubd\\t{%2, %0|%0, %2}"
14005 [(set_attr "type" "mmx")])
14006
14007 (define_insn "sssubv8qi3"
14008 [(set (match_operand:V8QI 0 "register_operand" "=y")
14009 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14010 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14011 "TARGET_MMX"
14012 "psubsb\\t{%2, %0|%0, %2}"
14013 [(set_attr "type" "mmx")])
14014
14015 (define_insn "sssubv4hi3"
14016 [(set (match_operand:V4HI 0 "register_operand" "=y")
14017 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14018 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14019 "TARGET_MMX"
14020 "psubsw\\t{%2, %0|%0, %2}"
14021 [(set_attr "type" "mmx")])
14022
14023 (define_insn "ussubv8qi3"
14024 [(set (match_operand:V8QI 0 "register_operand" "=y")
14025 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14026 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14027 "TARGET_MMX"
14028 "psubusb\\t{%2, %0|%0, %2}"
14029 [(set_attr "type" "mmx")])
14030
14031 (define_insn "ussubv4hi3"
14032 [(set (match_operand:V4HI 0 "register_operand" "=y")
14033 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
14034 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14035 "TARGET_MMX"
14036 "psubusw\\t{%2, %0|%0, %2}"
14037 [(set_attr "type" "mmx")])
14038
14039 (define_insn "mulv4hi3"
14040 [(set (match_operand:V4HI 0 "register_operand" "=y")
14041 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
14042 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14043 "TARGET_MMX"
14044 "pmullw\\t{%2, %0|%0, %2}"
14045 [(set_attr "type" "mmx")])
14046
14047 (define_insn "smulv4hi3_highpart"
14048 [(set (match_operand:V4HI 0 "register_operand" "=y")
14049 (truncate:V4HI
14050 (lshiftrt:V4SI
14051 (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
14052 (sign_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
14053 (const_int 16))))]
14054 "TARGET_MMX"
14055 "pmulhw\\t{%2, %0|%0, %2}"
14056 [(set_attr "type" "mmx")])
14057
14058 (define_insn "umulv4hi3_highpart"
14059 [(set (match_operand:V4HI 0 "register_operand" "=y")
14060 (truncate:V4HI
14061 (lshiftrt:V4SI
14062 (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "0"))
14063 (zero_extend:V4SI (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
14064 (const_int 16))))]
14065 "TARGET_MMX"
14066 "pmulhuw\\t{%2, %0|%0, %2}"
14067 [(set_attr "type" "mmx")])
14068
14069 (define_insn "mmx_pmaddwd"
14070 [(set (match_operand:V2SI 0 "register_operand" "=y")
14071 (plus:V2SI
14072 (mult:V2SI
14073 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
14074 (parallel [(const_int 0)
14075 (const_int 2)])))
14076 (sign_extend:V2SI (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
14077 (parallel [(const_int 0)
14078 (const_int 2)]))))
14079 (mult:V2SI
14080 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
14081 (parallel [(const_int 1)
14082 (const_int 3)])))
14083 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
14084 (parallel [(const_int 1)
14085 (const_int 3)]))))))]
14086 "TARGET_MMX"
14087 "pmaddwd\\t{%2, %0|%0, %2}"
14088 [(set_attr "type" "mmx")])
14089
14090
14091 ;; MMX logical operations
14092 ;; Note we don't want to declare these as regular iordi3 insns to prevent
14093 ;; normal code that also wants to use the FPU from getting broken.
14094 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
14095 (define_insn "mmx_iordi3"
14096 [(set (match_operand:DI 0 "register_operand" "=y")
14097 (unspec:DI
14098 [(ior:DI (match_operand:DI 1 "register_operand" "0")
14099 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14100 "TARGET_MMX"
14101 "por\\t{%2, %0|%0, %2}"
14102 [(set_attr "type" "mmx")])
14103
14104 (define_insn "mmx_xordi3"
14105 [(set (match_operand:DI 0 "register_operand" "=y")
14106 (unspec:DI
14107 [(xor:DI (match_operand:DI 1 "register_operand" "0")
14108 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14109 "TARGET_MMX"
14110 "pxor\\t{%2, %0|%0, %2}"
14111 [(set_attr "type" "mmx")])
14112
14113 ;; Same as pxor, but don't show input operands so that we don't think
14114 ;; they are live.
14115 (define_insn "mmx_clrdi"
14116 [(set (match_operand:DI 0 "register_operand" "=y")
14117 (unspec:DI [(const_int 0)] 45))]
14118 "TARGET_MMX"
14119 "pxor\\t{%0, %0|%0, %0}"
14120 [(set_attr "type" "mmx")])
14121
14122 (define_insn "mmx_anddi3"
14123 [(set (match_operand:DI 0 "register_operand" "=y")
14124 (unspec:DI
14125 [(and:DI (match_operand:DI 1 "register_operand" "0")
14126 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14127 "TARGET_MMX"
14128 "pand\\t{%2, %0|%0, %2}"
14129 [(set_attr "type" "mmx")])
14130
14131 (define_insn "mmx_nanddi3"
14132 [(set (match_operand:DI 0 "register_operand" "=y")
14133 (unspec:DI
14134 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
14135 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
14136 "TARGET_MMX"
14137 "pandn\\t{%2, %0|%0, %2}"
14138 [(set_attr "type" "mmx")])
14139
14140
14141 ;; MMX unsigned averages/sum of absolute differences
14142
14143 (define_insn "mmx_uavgv8qi3"
14144 [(set (match_operand:V8QI 0 "register_operand" "=y")
14145 (ashiftrt:V8QI
14146 (plus:V8QI (plus:V8QI
14147 (match_operand:V8QI 1 "register_operand" "0")
14148 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
14149 (vec_const:V8QI (parallel [(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 (const_int 1)))]
14158 "TARGET_SSE"
14159 "pavgb\\t{%2, %0|%0, %2}"
14160 [(set_attr "type" "sse")])
14161
14162 (define_insn "mmx_uavgv4hi3"
14163 [(set (match_operand:V4HI 0 "register_operand" "=y")
14164 (ashiftrt:V4HI
14165 (plus:V4HI (plus:V4HI
14166 (match_operand:V4HI 1 "register_operand" "0")
14167 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
14168 (vec_const:V4HI (parallel [(const_int 1)
14169 (const_int 1)
14170 (const_int 1)
14171 (const_int 1)])))
14172 (const_int 1)))]
14173 "TARGET_SSE"
14174 "pavgw\\t{%2, %0|%0, %2}"
14175 [(set_attr "type" "sse")])
14176
14177 (define_insn "mmx_psadbw"
14178 [(set (match_operand:V8QI 0 "register_operand" "=y")
14179 (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
14180 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
14181 "TARGET_SSE"
14182 "psadbw\\t{%2, %0|%0, %2}"
14183 [(set_attr "type" "sse")])
14184
14185
14186 ;; MMX insert/extract/shuffle
14187
14188 (define_insn "mmx_pinsrw"
14189 [(set (match_operand:V4HI 0 "register_operand" "=y")
14190 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
14191 (vec_duplicate:V4HI
14192 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
14193 (match_operand:SI 3 "immediate_operand" "i")))]
14194 "TARGET_SSE"
14195 "pinsrw\\t{%3, %2, %0|%0, %2, %3}"
14196 [(set_attr "type" "sse")])
14197
14198 (define_insn "mmx_pextrw"
14199 [(set (match_operand:SI 0 "register_operand" "=r")
14200 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
14201 (parallel
14202 [(match_operand:SI 2 "immediate_operand" "i")]))))]
14203 "TARGET_SSE"
14204 "pextrw\\t{%2, %1, %0|%0, %1, %2}"
14205 [(set_attr "type" "sse")])
14206
14207 (define_insn "mmx_pshufw"
14208 [(set (match_operand:V4HI 0 "register_operand" "=y")
14209 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
14210 (match_operand:V4HI 2 "nonimmediate_operand" "ym")
14211 (match_operand:SI 3 "immediate_operand" "i")] 41))]
14212 "TARGET_SSE"
14213 "pshufw\\t{%3, %2, %0|%0, %2, %3}"
14214 [(set_attr "type" "sse")])
14215
14216
14217 ;; MMX mask-generating comparisons
14218
14219 (define_insn "eqv8qi3"
14220 [(set (match_operand:V8QI 0 "register_operand" "=y")
14221 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
14222 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14223 "TARGET_MMX"
14224 "pcmpeqb\\t{%2, %0|%0, %2}"
14225 [(set_attr "type" "mmx")])
14226
14227 (define_insn "eqv4hi3"
14228 [(set (match_operand:V4HI 0 "register_operand" "=y")
14229 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
14230 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14231 "TARGET_MMX"
14232 "pcmpeqw\\t{%2, %0|%0, %2}"
14233 [(set_attr "type" "mmx")])
14234
14235 (define_insn "eqv2si3"
14236 [(set (match_operand:V2SI 0 "register_operand" "=y")
14237 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
14238 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14239 "TARGET_MMX"
14240 "pcmpeqd\\t{%2, %0|%0, %2}"
14241 [(set_attr "type" "mmx")])
14242
14243 (define_insn "gtv8qi3"
14244 [(set (match_operand:V8QI 0 "register_operand" "=y")
14245 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
14246 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14247 "TARGET_MMX"
14248 "pcmpgtb\\t{%2, %0|%0, %2}"
14249 [(set_attr "type" "mmx")])
14250
14251 (define_insn "gtv4hi3"
14252 [(set (match_operand:V4HI 0 "register_operand" "=y")
14253 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14254 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14255 "TARGET_MMX"
14256 "pcmpgtw\\t{%2, %0|%0, %2}"
14257 [(set_attr "type" "mmx")])
14258
14259 (define_insn "gtv2si3"
14260 [(set (match_operand:V2SI 0 "register_operand" "=y")
14261 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14262 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
14263 "TARGET_MMX"
14264 "pcmpgtd\\t{%2, %0|%0, %2}"
14265 [(set_attr "type" "mmx")])
14266
14267
14268 ;; MMX max/min insns
14269
14270 (define_insn "umaxv8qi3"
14271 [(set (match_operand:V8QI 0 "register_operand" "=y")
14272 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
14273 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14274 "TARGET_SSE"
14275 "pmaxub\\t{%2, %0|%0, %2}"
14276 [(set_attr "type" "sse")])
14277
14278 (define_insn "smaxv4hi3"
14279 [(set (match_operand:V4HI 0 "register_operand" "=y")
14280 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
14281 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14282 "TARGET_SSE"
14283 "pmaxsw\\t{%2, %0|%0, %2}"
14284 [(set_attr "type" "sse")])
14285
14286 (define_insn "uminv8qi3"
14287 [(set (match_operand:V8QI 0 "register_operand" "=y")
14288 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
14289 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
14290 "TARGET_SSE"
14291 "pminub\\t{%2, %0|%0, %2}"
14292 [(set_attr "type" "sse")])
14293
14294 (define_insn "sminv4hi3"
14295 [(set (match_operand:V4HI 0 "register_operand" "=y")
14296 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
14297 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
14298 "TARGET_SSE"
14299 "pminsw\\t{%2, %0|%0, %2}"
14300 [(set_attr "type" "sse")])
14301
14302
14303 ;; MMX shifts
14304
14305 (define_insn "ashrv4hi3"
14306 [(set (match_operand:V4HI 0 "register_operand" "=y")
14307 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14308 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14309 "TARGET_MMX"
14310 "psraw\\t{%2, %0|%0, %2}"
14311 [(set_attr "type" "mmx")])
14312
14313 (define_insn "ashrv2si3"
14314 [(set (match_operand:V2SI 0 "register_operand" "=y")
14315 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14316 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14317 "TARGET_MMX"
14318 "psrad\\t{%2, %0|%0, %2}"
14319 [(set_attr "type" "mmx")])
14320
14321 (define_insn "lshrv4hi3"
14322 [(set (match_operand:V4HI 0 "register_operand" "=y")
14323 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
14324 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14325 "TARGET_MMX"
14326 "psrlw\\t{%2, %0|%0, %2}"
14327 [(set_attr "type" "mmx")])
14328
14329 (define_insn "lshrv2si3"
14330 [(set (match_operand:V2SI 0 "register_operand" "=y")
14331 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
14332 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14333 "TARGET_MMX"
14334 "psrld\\t{%2, %0|%0, %2}"
14335 [(set_attr "type" "mmx")])
14336
14337 ;; See logical MMX insns.
14338 (define_insn "mmx_lshrdi3"
14339 [(set (match_operand:DI 0 "register_operand" "=y")
14340 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
14341 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14342 "TARGET_MMX"
14343 "psrlq\\t{%2, %0|%0, %2}"
14344 [(set_attr "type" "mmx")])
14345
14346 (define_insn "ashlv4hi3"
14347 [(set (match_operand:V4HI 0 "register_operand" "=y")
14348 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
14349 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14350 "TARGET_MMX"
14351 "psllw\\t{%2, %0|%0, %2}"
14352 [(set_attr "type" "mmx")])
14353
14354 (define_insn "ashlv2si3"
14355 [(set (match_operand:V2SI 0 "register_operand" "=y")
14356 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
14357 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14358 "TARGET_MMX"
14359 "pslld\\t{%2, %0|%0, %2}"
14360 [(set_attr "type" "mmx")])
14361
14362 ;; See logical MMX insns.
14363 (define_insn "mmx_ashldi3"
14364 [(set (match_operand:DI 0 "register_operand" "=y")
14365 (ashift:DI (match_operand:DI 1 "register_operand" "0")
14366 (match_operand:DI 2 "nonmemory_operand" "yi")))]
14367 "TARGET_MMX"
14368 "psllq\\t{%2, %0|%0, %2}"
14369 [(set_attr "type" "mmx")])
14370
14371
14372 ;; MMX pack/unpack insns.
14373
14374 (define_insn "mmx_packsswb"
14375 [(set (match_operand:V8QI 0 "register_operand" "=y")
14376 (vec_concat:V8QI
14377 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
14378 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
14379 "TARGET_MMX"
14380 "packsswb\\t{%2, %0|%0, %2}"
14381 [(set_attr "type" "mmx")])
14382
14383 (define_insn "mmx_packssdw"
14384 [(set (match_operand:V4HI 0 "register_operand" "=y")
14385 (vec_concat:V4HI
14386 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
14387 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
14388 "TARGET_MMX"
14389 "packssdw\\t{%2, %0|%0, %2}"
14390 [(set_attr "type" "mmx")])
14391
14392 (define_insn "mmx_packuswb"
14393 [(set (match_operand:V8QI 0 "register_operand" "=y")
14394 (vec_concat:V8QI
14395 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
14396 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
14397 "TARGET_MMX"
14398 "packuswb\\t{%2, %0|%0, %2}"
14399 [(set_attr "type" "mmx")])
14400
14401 (define_insn "mmx_punpckhbw"
14402 [(set (match_operand:V8QI 0 "register_operand" "=y")
14403 (vec_merge:V8QI
14404 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
14405 (parallel [(const_int 4)
14406 (const_int 0)
14407 (const_int 5)
14408 (const_int 1)
14409 (const_int 6)
14410 (const_int 2)
14411 (const_int 7)
14412 (const_int 3)]))
14413 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
14414 (parallel [(const_int 0)
14415 (const_int 4)
14416 (const_int 1)
14417 (const_int 5)
14418 (const_int 2)
14419 (const_int 6)
14420 (const_int 3)
14421 (const_int 7)]))
14422 (const_int 85)))]
14423 "TARGET_MMX"
14424 "punpckhbw\\t{%2, %0|%0, %2}"
14425 [(set_attr "type" "mmx")])
14426
14427 (define_insn "mmx_punpckhwd"
14428 [(set (match_operand:V4HI 0 "register_operand" "=y")
14429 (vec_merge:V4HI
14430 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
14431 (parallel [(const_int 0)
14432 (const_int 2)
14433 (const_int 1)
14434 (const_int 3)]))
14435 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
14436 (parallel [(const_int 2)
14437 (const_int 0)
14438 (const_int 3)
14439 (const_int 1)]))
14440 (const_int 5)))]
14441 "TARGET_MMX"
14442 "punpckhwd\\t{%2, %0|%0, %2}"
14443 [(set_attr "type" "mmx")])
14444
14445 (define_insn "mmx_punpckhdq"
14446 [(set (match_operand:V2SI 0 "register_operand" "=y")
14447 (vec_merge:V2SI
14448 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
14449 (parallel [(const_int 0)
14450 (const_int 1)]))
14451 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
14452 (parallel [(const_int 1)
14453 (const_int 0)]))
14454 (const_int 1)))]
14455 "TARGET_MMX"
14456 "punpckhdq\\t{%2, %0|%0, %2}"
14457 [(set_attr "type" "mmx")])
14458
14459 (define_insn "mmx_punpcklbw"
14460 [(set (match_operand:V8QI 0 "register_operand" "=y")
14461 (vec_merge:V8QI
14462 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
14463 (parallel [(const_int 0)
14464 (const_int 4)
14465 (const_int 1)
14466 (const_int 5)
14467 (const_int 2)
14468 (const_int 6)
14469 (const_int 3)
14470 (const_int 7)]))
14471 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
14472 (parallel [(const_int 4)
14473 (const_int 0)
14474 (const_int 5)
14475 (const_int 1)
14476 (const_int 6)
14477 (const_int 2)
14478 (const_int 7)
14479 (const_int 3)]))
14480 (const_int 85)))]
14481 "TARGET_MMX"
14482 "punpcklbw\\t{%2, %0|%0, %2}"
14483 [(set_attr "type" "mmx")])
14484
14485 (define_insn "mmx_punpcklwd"
14486 [(set (match_operand:V4HI 0 "register_operand" "=y")
14487 (vec_merge:V4HI
14488 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
14489 (parallel [(const_int 2)
14490 (const_int 0)
14491 (const_int 3)
14492 (const_int 1)]))
14493 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
14494 (parallel [(const_int 0)
14495 (const_int 2)
14496 (const_int 1)
14497 (const_int 3)]))
14498 (const_int 5)))]
14499 "TARGET_MMX"
14500 "punpcklwd\\t{%2, %0|%0, %2}"
14501 [(set_attr "type" "mmx")])
14502
14503 (define_insn "mmx_punpckldq"
14504 [(set (match_operand:V2SI 0 "register_operand" "=y")
14505 (vec_merge:V2SI
14506 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
14507 (parallel [(const_int 1)
14508 (const_int 0)]))
14509 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
14510 (parallel [(const_int 0)
14511 (const_int 1)]))
14512 (const_int 1)))]
14513 "TARGET_MMX"
14514 "punpckldq\\t{%2, %0|%0, %2}"
14515 [(set_attr "type" "mmx")])
14516
14517
14518 ;; Miscellaneous stuff
14519
14520 (define_insn "emms"
14521 [(unspec_volatile [(const_int 0)] 31)
14522 (clobber (reg:XF 8))
14523 (clobber (reg:XF 9))
14524 (clobber (reg:XF 10))
14525 (clobber (reg:XF 11))
14526 (clobber (reg:XF 12))
14527 (clobber (reg:XF 13))
14528 (clobber (reg:XF 14))
14529 (clobber (reg:XF 15))
14530 (clobber (reg:DI 29))
14531 (clobber (reg:DI 30))
14532 (clobber (reg:DI 31))
14533 (clobber (reg:DI 32))
14534 (clobber (reg:DI 33))
14535 (clobber (reg:DI 34))
14536 (clobber (reg:DI 35))
14537 (clobber (reg:DI 36))]
14538 "TARGET_MMX"
14539 "emms"
14540 [(set_attr "type" "mmx")
14541 (set_attr "memory" "unknown")])
14542
14543 (define_insn "ldmxcsr"
14544 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
14545 "TARGET_MMX"
14546 "ldmxcsr\\t%0"
14547 [(set_attr "type" "mmx")])
14548
14549 (define_insn "stmxcsr"
14550 [(set (match_operand:SI 0 "memory_operand" "=m")
14551 (unspec_volatile:SI [(const_int 0)] 40))]
14552 "TARGET_MMX"
14553 "stmxcsr\\t%0"
14554 [(set_attr "type" "mmx")])
14555
14556 (define_expand "sfence"
14557 [(set (match_dup 0)
14558 (unspec:BLK [(match_dup 0)] 44))]
14559 "TARGET_SSE"
14560 "
14561 {
14562 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14563 MEM_VOLATILE_P (operands[0]) = 1;
14564 }")
14565
14566 (define_insn "*sfence_insn"
14567 [(set (match_operand:BLK 0 "" "")
14568 (unspec:BLK [(match_dup 0)] 44))]
14569 "TARGET_SSE"
14570 "sfence"
14571 [(set_attr "type" "sse")
14572 (set_attr "memory" "unknown")])
14573
14574 (define_insn "prefetch"
14575 [(unspec [(match_operand:SI 0 "address_operand" "p")
14576 (match_operand:SI 1 "immediate_operand" "n")] 35)]
14577 "TARGET_SSE"
14578 "*
14579 {
14580 switch (INTVAL (operands[1]))
14581 {
14582 case 0:
14583 return \"prefetchnta\\t%a0\";
14584 case 1:
14585 return \"prefetcht0\\t%a0\";
14586 case 2:
14587 return \"prefetcht1\\t%a0\";
14588 case 3:
14589 return \"prefetcht2\\t%a0\";
14590 default:
14591 abort ();
14592 }
14593 }"
14594 [(set_attr "type" "sse")])
14595
This page took 0.677786 seconds and 5 git commands to generate.