vxlib.c: Fix comment typos.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;; operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54 [; Relocation specifiers
55 (UNSPEC_GOT 0)
56 (UNSPEC_GOTOFF 1)
57 (UNSPEC_GOTPCREL 2)
58 (UNSPEC_GOTTPOFF 3)
59 (UNSPEC_TPOFF 4)
60 (UNSPEC_NTPOFF 5)
61 (UNSPEC_DTPOFF 6)
62 (UNSPEC_GOTNTPOFF 7)
63 (UNSPEC_INDNTPOFF 8)
64
65 ; Prologue support
66 (UNSPEC_STACK_PROBE 10)
67 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SET_GOT 12)
69 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70
71 ; TLS support
72 (UNSPEC_TP 15)
73 (UNSPEC_TLS_GD 16)
74 (UNSPEC_TLS_LD_BASE 17)
75
76 ; Other random patterns
77 (UNSPEC_SCAS 20)
78 (UNSPEC_SIN 21)
79 (UNSPEC_COS 22)
80 (UNSPEC_FNSTSW 24)
81 (UNSPEC_SAHF 25)
82 (UNSPEC_FSTCW 26)
83 (UNSPEC_ADD_CARRY 27)
84 (UNSPEC_FLDCW 28)
85
86 ; For SSE/MMX support:
87 (UNSPEC_FIX 30)
88 (UNSPEC_MASKMOV 32)
89 (UNSPEC_MOVMSK 33)
90 (UNSPEC_MOVNT 34)
91 (UNSPEC_MOVA 38)
92 (UNSPEC_MOVU 39)
93 (UNSPEC_SHUFFLE 41)
94 (UNSPEC_RCP 42)
95 (UNSPEC_RSQRT 43)
96 (UNSPEC_SFENCE 44)
97 (UNSPEC_NOP 45) ; prevents combiner cleverness
98 (UNSPEC_PAVGUSB 49)
99 (UNSPEC_PFRCP 50)
100 (UNSPEC_PFRCPIT1 51)
101 (UNSPEC_PFRCPIT2 52)
102 (UNSPEC_PFRSQRT 53)
103 (UNSPEC_PFRSQIT1 54)
104 (UNSPEC_PSHUFLW 55)
105 (UNSPEC_PSHUFHW 56)
106 (UNSPEC_MFENCE 59)
107 (UNSPEC_LFENCE 60)
108 (UNSPEC_PSADBW 61)
109 (UNSPEC_ADDSUB 71)
110 (UNSPEC_HADD 72)
111 (UNSPEC_HSUB 73)
112 (UNSPEC_MOVSHDUP 74)
113 (UNSPEC_MOVSLDUP 75)
114 (UNSPEC_LDQQU 76)
115 (UNSPEC_MOVDDUP 77)
116
117 ; x87 Floating point
118 (UNSPEC_FPATAN 65)
119 (UNSPEC_FYL2X 66)
120 (UNSPEC_FSCALE 67)
121 (UNSPEC_FRNDINT 68)
122 (UNSPEC_F2XM1 69)
123
124 ; REP instruction
125 (UNSPEC_REP 75)
126 ])
127
128 (define_constants
129 [(UNSPECV_BLOCKAGE 0)
130 (UNSPECV_EH_RETURN 13)
131 (UNSPECV_EMMS 31)
132 (UNSPECV_LDMXCSR 37)
133 (UNSPECV_STMXCSR 40)
134 (UNSPECV_FEMMS 46)
135 (UNSPECV_CLFLUSH 57)
136 (UNSPECV_ALIGN 68)
137 (UNSPECV_MONITOR 69)
138 (UNSPECV_MWAIT 70)
139 ])
140
141 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
142 ;; from i386.c.
143
144 ;; In C guard expressions, put expressions which may be compile-time
145 ;; constants first. This allows for better optimization. For
146 ;; example, write "TARGET_64BIT && reload_completed", not
147 ;; "reload_completed && TARGET_64BIT".
148
149 \f
150 ;; Processor type. This attribute must exactly match the processor_type
151 ;; enumeration in i386.h.
152 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
153 (const (symbol_ref "ix86_tune")))
154
155 ;; A basic instruction type. Refinements due to arguments to be
156 ;; provided in other attributes.
157 (define_attr "type"
158 "other,multi,
159 alu,alu1,negnot,imov,imovx,lea,
160 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
161 icmp,test,ibr,setcc,icmov,
162 push,pop,call,callv,leave,
163 str,cld,
164 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
165 sselog,sseiadd,sseishft,sseimul,
166 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
167 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
168 (const_string "other"))
169
170 ;; Main data type used by the insn
171 (define_attr "mode"
172 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
173 (const_string "unknown"))
174
175 ;; The CPU unit operations uses.
176 (define_attr "unit" "integer,i387,sse,mmx,unknown"
177 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
178 (const_string "i387")
179 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
180 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
181 (const_string "sse")
182 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
183 (const_string "mmx")
184 (eq_attr "type" "other")
185 (const_string "unknown")]
186 (const_string "integer")))
187
188 ;; The (bounding maximum) length of an instruction immediate.
189 (define_attr "length_immediate" ""
190 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
191 (const_int 0)
192 (eq_attr "unit" "i387,sse,mmx")
193 (const_int 0)
194 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
195 imul,icmp,push,pop")
196 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
197 (eq_attr "type" "imov,test")
198 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
199 (eq_attr "type" "call")
200 (if_then_else (match_operand 0 "constant_call_address_operand" "")
201 (const_int 4)
202 (const_int 0))
203 (eq_attr "type" "callv")
204 (if_then_else (match_operand 1 "constant_call_address_operand" "")
205 (const_int 4)
206 (const_int 0))
207 ;; We don't know the size before shorten_branches. Expect
208 ;; the instruction to fit for better scheduling.
209 (eq_attr "type" "ibr")
210 (const_int 1)
211 ]
212 (symbol_ref "/* Update immediate_length and other attributes! */
213 abort(),1")))
214
215 ;; The (bounding maximum) length of an instruction address.
216 (define_attr "length_address" ""
217 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
218 (const_int 0)
219 (and (eq_attr "type" "call")
220 (match_operand 0 "constant_call_address_operand" ""))
221 (const_int 0)
222 (and (eq_attr "type" "callv")
223 (match_operand 1 "constant_call_address_operand" ""))
224 (const_int 0)
225 ]
226 (symbol_ref "ix86_attr_length_address_default (insn)")))
227
228 ;; Set when length prefix is used.
229 (define_attr "prefix_data16" ""
230 (if_then_else (ior (eq_attr "mode" "HI")
231 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
232 (const_int 1)
233 (const_int 0)))
234
235 ;; Set when string REP prefix is used.
236 (define_attr "prefix_rep" ""
237 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
238 (const_int 1)
239 (const_int 0)))
240
241 ;; Set when 0f opcode prefix is used.
242 (define_attr "prefix_0f" ""
243 (if_then_else
244 (ior (eq_attr "type" "imovx,setcc,icmov")
245 (eq_attr "unit" "sse,mmx"))
246 (const_int 1)
247 (const_int 0)))
248
249 ;; Set when 0f opcode prefix is used.
250 (define_attr "prefix_rex" ""
251 (cond [(and (eq_attr "mode" "DI")
252 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
253 (const_int 1)
254 (and (eq_attr "mode" "QI")
255 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
256 (const_int 0)))
257 (const_int 1)
258 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
259 (const_int 0))
260 (const_int 1)
261 ]
262 (const_int 0)))
263
264 ;; Set when modrm byte is used.
265 (define_attr "modrm" ""
266 (cond [(eq_attr "type" "str,cld,leave")
267 (const_int 0)
268 (eq_attr "unit" "i387")
269 (const_int 0)
270 (and (eq_attr "type" "incdec")
271 (ior (match_operand:SI 1 "register_operand" "")
272 (match_operand:HI 1 "register_operand" "")))
273 (const_int 0)
274 (and (eq_attr "type" "push")
275 (not (match_operand 1 "memory_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "pop")
278 (not (match_operand 0 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "imov")
281 (and (match_operand 0 "register_operand" "")
282 (match_operand 1 "immediate_operand" "")))
283 (const_int 0)
284 (and (eq_attr "type" "call")
285 (match_operand 0 "constant_call_address_operand" ""))
286 (const_int 0)
287 (and (eq_attr "type" "callv")
288 (match_operand 1 "constant_call_address_operand" ""))
289 (const_int 0)
290 ]
291 (const_int 1)))
292
293 ;; The (bounding maximum) length of an instruction in bytes.
294 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
295 ;; to split it and compute proper length as for other insns.
296 (define_attr "length" ""
297 (cond [(eq_attr "type" "other,multi,fistp")
298 (const_int 16)
299 (eq_attr "type" "fcmp")
300 (const_int 4)
301 (eq_attr "unit" "i387")
302 (plus (const_int 2)
303 (plus (attr "prefix_data16")
304 (attr "length_address")))]
305 (plus (plus (attr "modrm")
306 (plus (attr "prefix_0f")
307 (plus (attr "prefix_rex")
308 (const_int 1))))
309 (plus (attr "prefix_rep")
310 (plus (attr "prefix_data16")
311 (plus (attr "length_immediate")
312 (attr "length_address")))))))
313
314 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
315 ;; `store' if there is a simple memory reference therein, or `unknown'
316 ;; if the instruction is complex.
317
318 (define_attr "memory" "none,load,store,both,unknown"
319 (cond [(eq_attr "type" "other,multi,str")
320 (const_string "unknown")
321 (eq_attr "type" "lea,fcmov,fpspc,cld")
322 (const_string "none")
323 (eq_attr "type" "fistp,leave")
324 (const_string "both")
325 (eq_attr "type" "push")
326 (if_then_else (match_operand 1 "memory_operand" "")
327 (const_string "both")
328 (const_string "store"))
329 (eq_attr "type" "pop")
330 (if_then_else (match_operand 0 "memory_operand" "")
331 (const_string "both")
332 (const_string "load"))
333 (eq_attr "type" "setcc")
334 (if_then_else (match_operand 0 "memory_operand" "")
335 (const_string "store")
336 (const_string "none"))
337 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
338 (if_then_else (ior (match_operand 0 "memory_operand" "")
339 (match_operand 1 "memory_operand" ""))
340 (const_string "load")
341 (const_string "none"))
342 (eq_attr "type" "ibr")
343 (if_then_else (match_operand 0 "memory_operand" "")
344 (const_string "load")
345 (const_string "none"))
346 (eq_attr "type" "call")
347 (if_then_else (match_operand 0 "constant_call_address_operand" "")
348 (const_string "none")
349 (const_string "load"))
350 (eq_attr "type" "callv")
351 (if_then_else (match_operand 1 "constant_call_address_operand" "")
352 (const_string "none")
353 (const_string "load"))
354 (and (eq_attr "type" "alu1,negnot,ishift1")
355 (match_operand 1 "memory_operand" ""))
356 (const_string "both")
357 (and (match_operand 0 "memory_operand" "")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (match_operand 0 "memory_operand" "")
361 (const_string "store")
362 (match_operand 1 "memory_operand" "")
363 (const_string "load")
364 (and (eq_attr "type"
365 "!alu1,negnot,ishift1,
366 imov,imovx,icmp,test,
367 fmov,fcmp,fsgn,
368 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
369 mmx,mmxmov,mmxcmp,mmxcvt")
370 (match_operand 2 "memory_operand" ""))
371 (const_string "load")
372 (and (eq_attr "type" "icmov")
373 (match_operand 3 "memory_operand" ""))
374 (const_string "load")
375 ]
376 (const_string "none")))
377
378 ;; Indicates if an instruction has both an immediate and a displacement.
379
380 (define_attr "imm_disp" "false,true,unknown"
381 (cond [(eq_attr "type" "other,multi")
382 (const_string "unknown")
383 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
384 (and (match_operand 0 "memory_displacement_operand" "")
385 (match_operand 1 "immediate_operand" "")))
386 (const_string "true")
387 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
388 (and (match_operand 0 "memory_displacement_operand" "")
389 (match_operand 2 "immediate_operand" "")))
390 (const_string "true")
391 ]
392 (const_string "false")))
393
394 ;; Indicates if an FP operation has an integer source.
395
396 (define_attr "fp_int_src" "false,true"
397 (const_string "false"))
398
399 ;; Describe a user's asm statement.
400 (define_asm_attributes
401 [(set_attr "length" "128")
402 (set_attr "type" "multi")])
403 \f
404 (include "pentium.md")
405 (include "ppro.md")
406 (include "k6.md")
407 (include "athlon.md")
408 \f
409 ;; Compare instructions.
410
411 ;; All compare insns have expanders that save the operands away without
412 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
413 ;; after the cmp) will actually emit the cmpM.
414
415 (define_expand "cmpdi"
416 [(set (reg:CC 17)
417 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
418 (match_operand:DI 1 "x86_64_general_operand" "")))]
419 ""
420 {
421 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
422 operands[0] = force_reg (DImode, operands[0]);
423 ix86_compare_op0 = operands[0];
424 ix86_compare_op1 = operands[1];
425 DONE;
426 })
427
428 (define_expand "cmpsi"
429 [(set (reg:CC 17)
430 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
431 (match_operand:SI 1 "general_operand" "")))]
432 ""
433 {
434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
435 operands[0] = force_reg (SImode, operands[0]);
436 ix86_compare_op0 = operands[0];
437 ix86_compare_op1 = operands[1];
438 DONE;
439 })
440
441 (define_expand "cmphi"
442 [(set (reg:CC 17)
443 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
444 (match_operand:HI 1 "general_operand" "")))]
445 ""
446 {
447 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
448 operands[0] = force_reg (HImode, operands[0]);
449 ix86_compare_op0 = operands[0];
450 ix86_compare_op1 = operands[1];
451 DONE;
452 })
453
454 (define_expand "cmpqi"
455 [(set (reg:CC 17)
456 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
457 (match_operand:QI 1 "general_operand" "")))]
458 "TARGET_QIMODE_MATH"
459 {
460 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
461 operands[0] = force_reg (QImode, operands[0]);
462 ix86_compare_op0 = operands[0];
463 ix86_compare_op1 = operands[1];
464 DONE;
465 })
466
467 (define_insn "cmpdi_ccno_1_rex64"
468 [(set (reg 17)
469 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
470 (match_operand:DI 1 "const0_operand" "n,n")))]
471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
472 "@
473 test{q}\t{%0, %0|%0, %0}
474 cmp{q}\t{%1, %0|%0, %1}"
475 [(set_attr "type" "test,icmp")
476 (set_attr "length_immediate" "0,1")
477 (set_attr "mode" "DI")])
478
479 (define_insn "*cmpdi_minus_1_rex64"
480 [(set (reg 17)
481 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
482 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
483 (const_int 0)))]
484 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
485 "cmp{q}\t{%1, %0|%0, %1}"
486 [(set_attr "type" "icmp")
487 (set_attr "mode" "DI")])
488
489 (define_expand "cmpdi_1_rex64"
490 [(set (reg:CC 17)
491 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
492 (match_operand:DI 1 "general_operand" "")))]
493 "TARGET_64BIT"
494 "")
495
496 (define_insn "cmpdi_1_insn_rex64"
497 [(set (reg 17)
498 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
499 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
500 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
501 "cmp{q}\t{%1, %0|%0, %1}"
502 [(set_attr "type" "icmp")
503 (set_attr "mode" "DI")])
504
505
506 (define_insn "*cmpsi_ccno_1"
507 [(set (reg 17)
508 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
509 (match_operand:SI 1 "const0_operand" "n,n")))]
510 "ix86_match_ccmode (insn, CCNOmode)"
511 "@
512 test{l}\t{%0, %0|%0, %0}
513 cmp{l}\t{%1, %0|%0, %1}"
514 [(set_attr "type" "test,icmp")
515 (set_attr "length_immediate" "0,1")
516 (set_attr "mode" "SI")])
517
518 (define_insn "*cmpsi_minus_1"
519 [(set (reg 17)
520 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
521 (match_operand:SI 1 "general_operand" "ri,mr"))
522 (const_int 0)))]
523 "ix86_match_ccmode (insn, CCGOCmode)"
524 "cmp{l}\t{%1, %0|%0, %1}"
525 [(set_attr "type" "icmp")
526 (set_attr "mode" "SI")])
527
528 (define_expand "cmpsi_1"
529 [(set (reg:CC 17)
530 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
531 (match_operand:SI 1 "general_operand" "ri,mr")))]
532 ""
533 "")
534
535 (define_insn "*cmpsi_1_insn"
536 [(set (reg 17)
537 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
538 (match_operand:SI 1 "general_operand" "ri,mr")))]
539 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
540 && ix86_match_ccmode (insn, CCmode)"
541 "cmp{l}\t{%1, %0|%0, %1}"
542 [(set_attr "type" "icmp")
543 (set_attr "mode" "SI")])
544
545 (define_insn "*cmphi_ccno_1"
546 [(set (reg 17)
547 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
548 (match_operand:HI 1 "const0_operand" "n,n")))]
549 "ix86_match_ccmode (insn, CCNOmode)"
550 "@
551 test{w}\t{%0, %0|%0, %0}
552 cmp{w}\t{%1, %0|%0, %1}"
553 [(set_attr "type" "test,icmp")
554 (set_attr "length_immediate" "0,1")
555 (set_attr "mode" "HI")])
556
557 (define_insn "*cmphi_minus_1"
558 [(set (reg 17)
559 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
560 (match_operand:HI 1 "general_operand" "ri,mr"))
561 (const_int 0)))]
562 "ix86_match_ccmode (insn, CCGOCmode)"
563 "cmp{w}\t{%1, %0|%0, %1}"
564 [(set_attr "type" "icmp")
565 (set_attr "mode" "HI")])
566
567 (define_insn "*cmphi_1"
568 [(set (reg 17)
569 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:HI 1 "general_operand" "ri,mr")))]
571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
572 && ix86_match_ccmode (insn, CCmode)"
573 "cmp{w}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "HI")])
576
577 (define_insn "*cmpqi_ccno_1"
578 [(set (reg 17)
579 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
580 (match_operand:QI 1 "const0_operand" "n,n")))]
581 "ix86_match_ccmode (insn, CCNOmode)"
582 "@
583 test{b}\t{%0, %0|%0, %0}
584 cmp{b}\t{$0, %0|%0, 0}"
585 [(set_attr "type" "test,icmp")
586 (set_attr "length_immediate" "0,1")
587 (set_attr "mode" "QI")])
588
589 (define_insn "*cmpqi_1"
590 [(set (reg 17)
591 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
592 (match_operand:QI 1 "general_operand" "qi,mq")))]
593 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
594 && ix86_match_ccmode (insn, CCmode)"
595 "cmp{b}\t{%1, %0|%0, %1}"
596 [(set_attr "type" "icmp")
597 (set_attr "mode" "QI")])
598
599 (define_insn "*cmpqi_minus_1"
600 [(set (reg 17)
601 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
602 (match_operand:QI 1 "general_operand" "qi,mq"))
603 (const_int 0)))]
604 "ix86_match_ccmode (insn, CCGOCmode)"
605 "cmp{b}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "QI")])
608
609 (define_insn "*cmpqi_ext_1"
610 [(set (reg 17)
611 (compare
612 (match_operand:QI 0 "general_operand" "Qm")
613 (subreg:QI
614 (zero_extract:SI
615 (match_operand 1 "ext_register_operand" "Q")
616 (const_int 8)
617 (const_int 8)) 0)))]
618 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
619 "cmp{b}\t{%h1, %0|%0, %h1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "QI")])
622
623 (define_insn "*cmpqi_ext_1_rex64"
624 [(set (reg 17)
625 (compare
626 (match_operand:QI 0 "register_operand" "Q")
627 (subreg:QI
628 (zero_extract:SI
629 (match_operand 1 "ext_register_operand" "Q")
630 (const_int 8)
631 (const_int 8)) 0)))]
632 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
633 "cmp{b}\t{%h1, %0|%0, %h1}"
634 [(set_attr "type" "icmp")
635 (set_attr "mode" "QI")])
636
637 (define_insn "*cmpqi_ext_2"
638 [(set (reg 17)
639 (compare
640 (subreg:QI
641 (zero_extract:SI
642 (match_operand 0 "ext_register_operand" "Q")
643 (const_int 8)
644 (const_int 8)) 0)
645 (match_operand:QI 1 "const0_operand" "n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
647 "test{b}\t%h0, %h0"
648 [(set_attr "type" "test")
649 (set_attr "length_immediate" "0")
650 (set_attr "mode" "QI")])
651
652 (define_expand "cmpqi_ext_3"
653 [(set (reg:CC 17)
654 (compare:CC
655 (subreg:QI
656 (zero_extract:SI
657 (match_operand 0 "ext_register_operand" "")
658 (const_int 8)
659 (const_int 8)) 0)
660 (match_operand:QI 1 "general_operand" "")))]
661 ""
662 "")
663
664 (define_insn "cmpqi_ext_3_insn"
665 [(set (reg 17)
666 (compare
667 (subreg:QI
668 (zero_extract:SI
669 (match_operand 0 "ext_register_operand" "Q")
670 (const_int 8)
671 (const_int 8)) 0)
672 (match_operand:QI 1 "general_operand" "Qmn")))]
673 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %h0|%h0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
677
678 (define_insn "cmpqi_ext_3_insn_rex64"
679 [(set (reg 17)
680 (compare
681 (subreg:QI
682 (zero_extract:SI
683 (match_operand 0 "ext_register_operand" "Q")
684 (const_int 8)
685 (const_int 8)) 0)
686 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{b}\t{%1, %h0|%h0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_ext_4"
693 [(set (reg 17)
694 (compare
695 (subreg:QI
696 (zero_extract:SI
697 (match_operand 0 "ext_register_operand" "Q")
698 (const_int 8)
699 (const_int 8)) 0)
700 (subreg:QI
701 (zero_extract:SI
702 (match_operand 1 "ext_register_operand" "Q")
703 (const_int 8)
704 (const_int 8)) 0)))]
705 "ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %h0|%h0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
709
710 ;; These implement float point compares.
711 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
712 ;; which would allow mix and match FP modes on the compares. Which is what
713 ;; the old patterns did, but with many more of them.
714
715 (define_expand "cmpxf"
716 [(set (reg:CC 17)
717 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
718 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
719 "TARGET_80387"
720 {
721 ix86_compare_op0 = operands[0];
722 ix86_compare_op1 = operands[1];
723 DONE;
724 })
725
726 (define_expand "cmpdf"
727 [(set (reg:CC 17)
728 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
729 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
730 "TARGET_80387 || TARGET_SSE2"
731 {
732 ix86_compare_op0 = operands[0];
733 ix86_compare_op1 = operands[1];
734 DONE;
735 })
736
737 (define_expand "cmpsf"
738 [(set (reg:CC 17)
739 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
740 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
741 "TARGET_80387 || TARGET_SSE"
742 {
743 ix86_compare_op0 = operands[0];
744 ix86_compare_op1 = operands[1];
745 DONE;
746 })
747
748 ;; FP compares, step 1:
749 ;; Set the FP condition codes.
750 ;;
751 ;; CCFPmode compare with exceptions
752 ;; CCFPUmode compare with no exceptions
753
754 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
755 ;; and that fp moves clobber the condition codes, and that there is
756 ;; currently no way to describe this fact to reg-stack. So there are
757 ;; no splitters yet for this.
758
759 ;; %%% YIKES! This scheme does not retain a strong connection between
760 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
761 ;; work! Only allow tos/mem with tos in op 0.
762 ;;
763 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
764 ;; things aren't as bad as they sound...
765
766 (define_insn "*cmpfp_0"
767 [(set (match_operand:HI 0 "register_operand" "=a")
768 (unspec:HI
769 [(compare:CCFP (match_operand 1 "register_operand" "f")
770 (match_operand 2 "const0_operand" "X"))]
771 UNSPEC_FNSTSW))]
772 "TARGET_80387
773 && FLOAT_MODE_P (GET_MODE (operands[1]))
774 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
775 {
776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
777 return "ftst\;fnstsw\t%0\;fstp\t%y0";
778 else
779 return "ftst\;fnstsw\t%0";
780 }
781 [(set_attr "type" "multi")
782 (set (attr "mode")
783 (cond [(match_operand:SF 1 "" "")
784 (const_string "SF")
785 (match_operand:DF 1 "" "")
786 (const_string "DF")
787 ]
788 (const_string "XF")))])
789
790 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
791 ;; used to manage the reg stack popping would not be preserved.
792
793 (define_insn "*cmpfp_2_sf"
794 [(set (reg:CCFP 18)
795 (compare:CCFP
796 (match_operand:SF 0 "register_operand" "f")
797 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
798 "TARGET_80387"
799 "* return output_fp_compare (insn, operands, 0, 0);"
800 [(set_attr "type" "fcmp")
801 (set_attr "mode" "SF")])
802
803 (define_insn "*cmpfp_2_sf_1"
804 [(set (match_operand:HI 0 "register_operand" "=a")
805 (unspec:HI
806 [(compare:CCFP
807 (match_operand:SF 1 "register_operand" "f")
808 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
809 UNSPEC_FNSTSW))]
810 "TARGET_80387"
811 "* return output_fp_compare (insn, operands, 2, 0);"
812 [(set_attr "type" "fcmp")
813 (set_attr "mode" "SF")])
814
815 (define_insn "*cmpfp_2_df"
816 [(set (reg:CCFP 18)
817 (compare:CCFP
818 (match_operand:DF 0 "register_operand" "f")
819 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
820 "TARGET_80387"
821 "* return output_fp_compare (insn, operands, 0, 0);"
822 [(set_attr "type" "fcmp")
823 (set_attr "mode" "DF")])
824
825 (define_insn "*cmpfp_2_df_1"
826 [(set (match_operand:HI 0 "register_operand" "=a")
827 (unspec:HI
828 [(compare:CCFP
829 (match_operand:DF 1 "register_operand" "f")
830 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
831 UNSPEC_FNSTSW))]
832 "TARGET_80387"
833 "* return output_fp_compare (insn, operands, 2, 0);"
834 [(set_attr "type" "multi")
835 (set_attr "mode" "DF")])
836
837 (define_insn "*cmpfp_2_xf"
838 [(set (reg:CCFP 18)
839 (compare:CCFP
840 (match_operand:XF 0 "register_operand" "f")
841 (match_operand:XF 1 "register_operand" "f")))]
842 "TARGET_80387"
843 "* return output_fp_compare (insn, operands, 0, 0);"
844 [(set_attr "type" "fcmp")
845 (set_attr "mode" "XF")])
846
847 (define_insn "*cmpfp_2_xf_1"
848 [(set (match_operand:HI 0 "register_operand" "=a")
849 (unspec:HI
850 [(compare:CCFP
851 (match_operand:XF 1 "register_operand" "f")
852 (match_operand:XF 2 "register_operand" "f"))]
853 UNSPEC_FNSTSW))]
854 "TARGET_80387"
855 "* return output_fp_compare (insn, operands, 2, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2u"
860 [(set (reg:CCFPU 18)
861 (compare:CCFPU
862 (match_operand 0 "register_operand" "f")
863 (match_operand 1 "register_operand" "f")))]
864 "TARGET_80387
865 && FLOAT_MODE_P (GET_MODE (operands[0]))
866 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
867 "* return output_fp_compare (insn, operands, 0, 1);"
868 [(set_attr "type" "fcmp")
869 (set (attr "mode")
870 (cond [(match_operand:SF 1 "" "")
871 (const_string "SF")
872 (match_operand:DF 1 "" "")
873 (const_string "DF")
874 ]
875 (const_string "XF")))])
876
877 (define_insn "*cmpfp_2u_1"
878 [(set (match_operand:HI 0 "register_operand" "=a")
879 (unspec:HI
880 [(compare:CCFPU
881 (match_operand 1 "register_operand" "f")
882 (match_operand 2 "register_operand" "f"))]
883 UNSPEC_FNSTSW))]
884 "TARGET_80387
885 && FLOAT_MODE_P (GET_MODE (operands[1]))
886 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
887 "* return output_fp_compare (insn, operands, 2, 1);"
888 [(set_attr "type" "multi")
889 (set (attr "mode")
890 (cond [(match_operand:SF 1 "" "")
891 (const_string "SF")
892 (match_operand:DF 1 "" "")
893 (const_string "DF")
894 ]
895 (const_string "XF")))])
896
897 ;; Patterns to match the SImode-in-memory ficom instructions.
898 ;;
899 ;; %%% Play games with accepting gp registers, as otherwise we have to
900 ;; force them to memory during rtl generation, which is no good. We
901 ;; can get rid of this once we teach reload to do memory input reloads
902 ;; via pushes.
903
904 (define_insn "*ficom_1"
905 [(set (reg:CCFP 18)
906 (compare:CCFP
907 (match_operand 0 "register_operand" "f,f")
908 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
909 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
910 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
911 "#")
912
913 ;; Split the not-really-implemented gp register case into a
914 ;; push-op-pop sequence.
915 ;;
916 ;; %%% This is most efficient, but am I gonna get in trouble
917 ;; for separating cc0_setter and cc0_user?
918
919 (define_split
920 [(set (reg:CCFP 18)
921 (compare:CCFP
922 (match_operand:SF 0 "register_operand" "")
923 (float (match_operand:SI 1 "register_operand" ""))))]
924 "0 && TARGET_80387 && reload_completed"
925 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
926 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
927 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
928 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
929 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
930 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
931
932 ;; FP compares, step 2
933 ;; Move the fpsw to ax.
934
935 (define_insn "*x86_fnstsw_1"
936 [(set (match_operand:HI 0 "register_operand" "=a")
937 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
938 "TARGET_80387"
939 "fnstsw\t%0"
940 [(set_attr "length" "2")
941 (set_attr "mode" "SI")
942 (set_attr "unit" "i387")
943 (set_attr "ppro_uops" "few")])
944
945 ;; FP compares, step 3
946 ;; Get ax into flags, general case.
947
948 (define_insn "x86_sahf_1"
949 [(set (reg:CC 17)
950 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
951 "!TARGET_64BIT"
952 "sahf"
953 [(set_attr "length" "1")
954 (set_attr "athlon_decode" "vector")
955 (set_attr "mode" "SI")
956 (set_attr "ppro_uops" "one")])
957
958 ;; Pentium Pro can do steps 1 through 3 in one go.
959
960 (define_insn "*cmpfp_i"
961 [(set (reg:CCFP 17)
962 (compare:CCFP (match_operand 0 "register_operand" "f")
963 (match_operand 1 "register_operand" "f")))]
964 "TARGET_80387 && TARGET_CMOVE
965 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966 && FLOAT_MODE_P (GET_MODE (operands[0]))
967 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
968 "* return output_fp_compare (insn, operands, 1, 0);"
969 [(set_attr "type" "fcmp")
970 (set (attr "mode")
971 (cond [(match_operand:SF 1 "" "")
972 (const_string "SF")
973 (match_operand:DF 1 "" "")
974 (const_string "DF")
975 ]
976 (const_string "XF")))
977 (set_attr "athlon_decode" "vector")])
978
979 (define_insn "*cmpfp_i_sse"
980 [(set (reg:CCFP 17)
981 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
982 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
983 "TARGET_80387
984 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
985 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
986 "* return output_fp_compare (insn, operands, 1, 0);"
987 [(set_attr "type" "fcmp,ssecomi")
988 (set (attr "mode")
989 (if_then_else (match_operand:SF 1 "" "")
990 (const_string "SF")
991 (const_string "DF")))
992 (set_attr "athlon_decode" "vector")])
993
994 (define_insn "*cmpfp_i_sse_only"
995 [(set (reg:CCFP 17)
996 (compare:CCFP (match_operand 0 "register_operand" "x")
997 (match_operand 1 "nonimmediate_operand" "xm")))]
998 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "ssecomi")
1002 (set (attr "mode")
1003 (if_then_else (match_operand:SF 1 "" "")
1004 (const_string "SF")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")])
1007
1008 (define_insn "*cmpfp_iu"
1009 [(set (reg:CCFPU 17)
1010 (compare:CCFPU (match_operand 0 "register_operand" "f")
1011 (match_operand 1 "register_operand" "f")))]
1012 "TARGET_80387 && TARGET_CMOVE
1013 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1014 && FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 1);"
1017 [(set_attr "type" "fcmp")
1018 (set (attr "mode")
1019 (cond [(match_operand:SF 1 "" "")
1020 (const_string "SF")
1021 (match_operand:DF 1 "" "")
1022 (const_string "DF")
1023 ]
1024 (const_string "XF")))
1025 (set_attr "athlon_decode" "vector")])
1026
1027 (define_insn "*cmpfp_iu_sse"
1028 [(set (reg:CCFPU 17)
1029 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1030 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1031 "TARGET_80387
1032 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1033 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034 "* return output_fp_compare (insn, operands, 1, 1);"
1035 [(set_attr "type" "fcmp,ssecomi")
1036 (set (attr "mode")
1037 (if_then_else (match_operand:SF 1 "" "")
1038 (const_string "SF")
1039 (const_string "DF")))
1040 (set_attr "athlon_decode" "vector")])
1041
1042 (define_insn "*cmpfp_iu_sse_only"
1043 [(set (reg:CCFPU 17)
1044 (compare:CCFPU (match_operand 0 "register_operand" "x")
1045 (match_operand 1 "nonimmediate_operand" "xm")))]
1046 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048 "* return output_fp_compare (insn, operands, 1, 1);"
1049 [(set_attr "type" "ssecomi")
1050 (set (attr "mode")
1051 (if_then_else (match_operand:SF 1 "" "")
1052 (const_string "SF")
1053 (const_string "DF")))
1054 (set_attr "athlon_decode" "vector")])
1055 \f
1056 ;; Move instructions.
1057
1058 ;; General case of fullword move.
1059
1060 (define_expand "movsi"
1061 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1062 (match_operand:SI 1 "general_operand" ""))]
1063 ""
1064 "ix86_expand_move (SImode, operands); DONE;")
1065
1066 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1067 ;; general_operand.
1068 ;;
1069 ;; %%% We don't use a post-inc memory reference because x86 is not a
1070 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1071 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1072 ;; targets without our curiosities, and it is just as easy to represent
1073 ;; this differently.
1074
1075 (define_insn "*pushsi2"
1076 [(set (match_operand:SI 0 "push_operand" "=<")
1077 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1078 "!TARGET_64BIT"
1079 "push{l}\t%1"
1080 [(set_attr "type" "push")
1081 (set_attr "mode" "SI")])
1082
1083 ;; For 64BIT abi we always round up to 8 bytes.
1084 (define_insn "*pushsi2_rex64"
1085 [(set (match_operand:SI 0 "push_operand" "=X")
1086 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1087 "TARGET_64BIT"
1088 "push{q}\t%q1"
1089 [(set_attr "type" "push")
1090 (set_attr "mode" "SI")])
1091
1092 (define_insn "*pushsi2_prologue"
1093 [(set (match_operand:SI 0 "push_operand" "=<")
1094 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1095 (clobber (mem:BLK (scratch)))]
1096 "!TARGET_64BIT"
1097 "push{l}\t%1"
1098 [(set_attr "type" "push")
1099 (set_attr "mode" "SI")])
1100
1101 (define_insn "*popsi1_epilogue"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103 (mem:SI (reg:SI 7)))
1104 (set (reg:SI 7)
1105 (plus:SI (reg:SI 7) (const_int 4)))
1106 (clobber (mem:BLK (scratch)))]
1107 "!TARGET_64BIT"
1108 "pop{l}\t%0"
1109 [(set_attr "type" "pop")
1110 (set_attr "mode" "SI")])
1111
1112 (define_insn "popsi1"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI 7)))
1115 (set (reg:SI 7)
1116 (plus:SI (reg:SI 7) (const_int 4)))]
1117 "!TARGET_64BIT"
1118 "pop{l}\t%0"
1119 [(set_attr "type" "pop")
1120 (set_attr "mode" "SI")])
1121
1122 (define_insn "*movsi_xor"
1123 [(set (match_operand:SI 0 "register_operand" "=r")
1124 (match_operand:SI 1 "const0_operand" "i"))
1125 (clobber (reg:CC 17))]
1126 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1127 "xor{l}\t{%0, %0|%0, %0}"
1128 [(set_attr "type" "alu1")
1129 (set_attr "mode" "SI")
1130 (set_attr "length_immediate" "0")])
1131
1132 (define_insn "*movsi_or"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (match_operand:SI 1 "immediate_operand" "i"))
1135 (clobber (reg:CC 17))]
1136 "reload_completed
1137 && operands[1] == constm1_rtx
1138 && (TARGET_PENTIUM || optimize_size)"
1139 {
1140 operands[1] = constm1_rtx;
1141 return "or{l}\t{%1, %0|%0, %1}";
1142 }
1143 [(set_attr "type" "alu1")
1144 (set_attr "mode" "SI")
1145 (set_attr "length_immediate" "1")])
1146
1147 (define_insn "*movsi_1"
1148 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1149 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1150 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1151 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1152 {
1153 switch (get_attr_type (insn))
1154 {
1155 case TYPE_SSEMOV:
1156 if (get_attr_mode (insn) == MODE_TI)
1157 return "movdqa\t{%1, %0|%0, %1}";
1158 return "movd\t{%1, %0|%0, %1}";
1159
1160 case TYPE_MMXMOV:
1161 if (get_attr_mode (insn) == MODE_DI)
1162 return "movq\t{%1, %0|%0, %1}";
1163 return "movd\t{%1, %0|%0, %1}";
1164
1165 case TYPE_LEA:
1166 return "lea{l}\t{%1, %0|%0, %1}";
1167
1168 default:
1169 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1170 abort();
1171 return "mov{l}\t{%1, %0|%0, %1}";
1172 }
1173 }
1174 [(set (attr "type")
1175 (cond [(eq_attr "alternative" "2,3,4")
1176 (const_string "mmxmov")
1177 (eq_attr "alternative" "5,6,7")
1178 (const_string "ssemov")
1179 (and (ne (symbol_ref "flag_pic") (const_int 0))
1180 (match_operand:SI 1 "symbolic_operand" ""))
1181 (const_string "lea")
1182 ]
1183 (const_string "imov")))
1184 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1185
1186 (define_insn "*movsi_1_nointernunit"
1187 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1188 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1189 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1190 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1191 {
1192 switch (get_attr_type (insn))
1193 {
1194 case TYPE_SSEMOV:
1195 if (get_attr_mode (insn) == MODE_TI)
1196 return "movdqa\t{%1, %0|%0, %1}";
1197 return "movd\t{%1, %0|%0, %1}";
1198
1199 case TYPE_MMXMOV:
1200 if (get_attr_mode (insn) == MODE_DI)
1201 return "movq\t{%1, %0|%0, %1}";
1202 return "movd\t{%1, %0|%0, %1}";
1203
1204 case TYPE_LEA:
1205 return "lea{l}\t{%1, %0|%0, %1}";
1206
1207 default:
1208 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1209 abort();
1210 return "mov{l}\t{%1, %0|%0, %1}";
1211 }
1212 }
1213 [(set (attr "type")
1214 (cond [(eq_attr "alternative" "2,3,4")
1215 (const_string "mmxmov")
1216 (eq_attr "alternative" "5,6,7")
1217 (const_string "ssemov")
1218 (and (ne (symbol_ref "flag_pic") (const_int 0))
1219 (match_operand:SI 1 "symbolic_operand" ""))
1220 (const_string "lea")
1221 ]
1222 (const_string "imov")))
1223 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1224
1225 ;; Stores and loads of ax to arbitrary constant address.
1226 ;; We fake an second form of instruction to force reload to load address
1227 ;; into register when rax is not available
1228 (define_insn "*movabssi_1_rex64"
1229 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1230 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1231 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1232 "@
1233 movabs{l}\t{%1, %P0|%P0, %1}
1234 mov{l}\t{%1, %a0|%a0, %1}"
1235 [(set_attr "type" "imov")
1236 (set_attr "modrm" "0,*")
1237 (set_attr "length_address" "8,0")
1238 (set_attr "length_immediate" "0,*")
1239 (set_attr "memory" "store")
1240 (set_attr "mode" "SI")])
1241
1242 (define_insn "*movabssi_2_rex64"
1243 [(set (match_operand:SI 0 "register_operand" "=a,r")
1244 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1245 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1246 "@
1247 movabs{l}\t{%P1, %0|%0, %P1}
1248 mov{l}\t{%a1, %0|%0, %a1}"
1249 [(set_attr "type" "imov")
1250 (set_attr "modrm" "0,*")
1251 (set_attr "length_address" "8,0")
1252 (set_attr "length_immediate" "0")
1253 (set_attr "memory" "load")
1254 (set_attr "mode" "SI")])
1255
1256 (define_insn "*swapsi"
1257 [(set (match_operand:SI 0 "register_operand" "+r")
1258 (match_operand:SI 1 "register_operand" "+r"))
1259 (set (match_dup 1)
1260 (match_dup 0))]
1261 ""
1262 "xchg{l}\t%1, %0"
1263 [(set_attr "type" "imov")
1264 (set_attr "pent_pair" "np")
1265 (set_attr "athlon_decode" "vector")
1266 (set_attr "mode" "SI")
1267 (set_attr "modrm" "0")
1268 (set_attr "ppro_uops" "few")])
1269
1270 (define_expand "movhi"
1271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272 (match_operand:HI 1 "general_operand" ""))]
1273 ""
1274 "ix86_expand_move (HImode, operands); DONE;")
1275
1276 (define_insn "*pushhi2"
1277 [(set (match_operand:HI 0 "push_operand" "=<,<")
1278 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1279 "!TARGET_64BIT"
1280 "@
1281 push{w}\t{|WORD PTR }%1
1282 push{w}\t%1"
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "HI")])
1285
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290 "TARGET_64BIT"
1291 "push{q}\t%q1"
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "QI")])
1294
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1299 {
1300 switch (get_attr_type (insn))
1301 {
1302 case TYPE_IMOVX:
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1306 default:
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1309 else
1310 return "mov{w}\t{%1, %0|%0, %1}";
1311 }
1312 }
1313 [(set (attr "type")
1314 (cond [(and (eq_attr "alternative" "0")
1315 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1316 (const_int 0))
1317 (eq (symbol_ref "TARGET_HIMODE_MATH")
1318 (const_int 0))))
1319 (const_string "imov")
1320 (and (eq_attr "alternative" "1,2")
1321 (match_operand:HI 1 "aligned_operand" ""))
1322 (const_string "imov")
1323 (and (ne (symbol_ref "TARGET_MOVX")
1324 (const_int 0))
1325 (eq_attr "alternative" "0,2"))
1326 (const_string "imovx")
1327 ]
1328 (const_string "imov")))
1329 (set (attr "mode")
1330 (cond [(eq_attr "type" "imovx")
1331 (const_string "SI")
1332 (and (eq_attr "alternative" "1,2")
1333 (match_operand:HI 1 "aligned_operand" ""))
1334 (const_string "SI")
1335 (and (eq_attr "alternative" "0")
1336 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1337 (const_int 0))
1338 (eq (symbol_ref "TARGET_HIMODE_MATH")
1339 (const_int 0))))
1340 (const_string "SI")
1341 ]
1342 (const_string "HI")))])
1343
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1351 "@
1352 movabs{w}\t{%1, %P0|%P0, %1}
1353 mov{w}\t{%1, %a0|%a0, %1}"
1354 [(set_attr "type" "imov")
1355 (set_attr "modrm" "0,*")
1356 (set_attr "length_address" "8,0")
1357 (set_attr "length_immediate" "0,*")
1358 (set_attr "memory" "store")
1359 (set_attr "mode" "HI")])
1360
1361 (define_insn "*movabshi_2_rex64"
1362 [(set (match_operand:HI 0 "register_operand" "=a,r")
1363 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1365 "@
1366 movabs{w}\t{%P1, %0|%0, %P1}
1367 mov{w}\t{%a1, %0|%0, %a1}"
1368 [(set_attr "type" "imov")
1369 (set_attr "modrm" "0,*")
1370 (set_attr "length_address" "8,0")
1371 (set_attr "length_immediate" "0")
1372 (set_attr "memory" "load")
1373 (set_attr "mode" "HI")])
1374
1375 (define_insn "*swaphi_1"
1376 [(set (match_operand:HI 0 "register_operand" "+r")
1377 (match_operand:HI 1 "register_operand" "+r"))
1378 (set (match_dup 1)
1379 (match_dup 0))]
1380 "TARGET_PARTIAL_REG_STALL"
1381 "xchg{w}\t%1, %0"
1382 [(set_attr "type" "imov")
1383 (set_attr "pent_pair" "np")
1384 (set_attr "mode" "HI")
1385 (set_attr "modrm" "0")
1386 (set_attr "ppro_uops" "few")])
1387
1388 (define_insn "*swaphi_2"
1389 [(set (match_operand:HI 0 "register_operand" "+r")
1390 (match_operand:HI 1 "register_operand" "+r"))
1391 (set (match_dup 1)
1392 (match_dup 0))]
1393 "! TARGET_PARTIAL_REG_STALL"
1394 "xchg{l}\t%k1, %k0"
1395 [(set_attr "type" "imov")
1396 (set_attr "pent_pair" "np")
1397 (set_attr "mode" "SI")
1398 (set_attr "modrm" "0")
1399 (set_attr "ppro_uops" "few")])
1400
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1405 {
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1409 })
1410
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1419
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC 17))]
1424 "reload_completed
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1430
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1434 ""
1435 "ix86_expand_move (QImode, operands); DONE;")
1436
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1440
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X,X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1444 "!TARGET_64BIT"
1445 "@
1446 push{w}\t{|word ptr }%1
1447 push{w}\t%w1"
1448 [(set_attr "type" "push")
1449 (set_attr "mode" "HI")])
1450
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453 [(set (match_operand:QI 0 "push_operand" "=X")
1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455 "TARGET_64BIT"
1456 "push{q}\t%q1"
1457 [(set_attr "type" "push")
1458 (set_attr "mode" "QI")])
1459
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; instruction).
1466 ;;
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there. Then we use movzx.
1470 (define_insn "*movqi_1"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1473 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 {
1475 switch (get_attr_type (insn))
1476 {
1477 case TYPE_IMOVX:
1478 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1479 abort ();
1480 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481 default:
1482 if (get_attr_mode (insn) == MODE_SI)
1483 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484 else
1485 return "mov{b}\t{%1, %0|%0, %1}";
1486 }
1487 }
1488 [(set (attr "type")
1489 (cond [(and (eq_attr "alternative" "3")
1490 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1491 (const_int 0))
1492 (eq (symbol_ref "TARGET_QIMODE_MATH")
1493 (const_int 0))))
1494 (const_string "imov")
1495 (eq_attr "alternative" "3,5")
1496 (const_string "imovx")
1497 (and (ne (symbol_ref "TARGET_MOVX")
1498 (const_int 0))
1499 (eq_attr "alternative" "2"))
1500 (const_string "imovx")
1501 ]
1502 (const_string "imov")))
1503 (set (attr "mode")
1504 (cond [(eq_attr "alternative" "3,4,5")
1505 (const_string "SI")
1506 (eq_attr "alternative" "6")
1507 (const_string "QI")
1508 (eq_attr "type" "imovx")
1509 (const_string "SI")
1510 (and (eq_attr "type" "imov")
1511 (and (eq_attr "alternative" "0,1,2")
1512 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513 (const_int 0))))
1514 (const_string "SI")
1515 ;; Avoid partial register stalls when not using QImode arithmetic
1516 (and (eq_attr "type" "imov")
1517 (and (eq_attr "alternative" "0,1,2")
1518 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1519 (const_int 0))
1520 (eq (symbol_ref "TARGET_QIMODE_MATH")
1521 (const_int 0)))))
1522 (const_string "SI")
1523 ]
1524 (const_string "QI")))])
1525
1526 (define_expand "reload_outqi"
1527 [(parallel [(match_operand:QI 0 "" "=m")
1528 (match_operand:QI 1 "register_operand" "r")
1529 (match_operand:QI 2 "register_operand" "=&q")])]
1530 ""
1531 {
1532 rtx op0, op1, op2;
1533 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1534
1535 if (reg_overlap_mentioned_p (op2, op0))
1536 abort ();
1537 if (! q_regs_operand (op1, QImode))
1538 {
1539 emit_insn (gen_movqi (op2, op1));
1540 op1 = op2;
1541 }
1542 emit_insn (gen_movqi (op0, op1));
1543 DONE;
1544 })
1545
1546 (define_insn "*swapqi"
1547 [(set (match_operand:QI 0 "register_operand" "+r")
1548 (match_operand:QI 1 "register_operand" "+r"))
1549 (set (match_dup 1)
1550 (match_dup 0))]
1551 ""
1552 "xchg{b}\t%1, %0"
1553 [(set_attr "type" "imov")
1554 (set_attr "pent_pair" "np")
1555 (set_attr "mode" "QI")
1556 (set_attr "modrm" "0")
1557 (set_attr "ppro_uops" "few")])
1558
1559 (define_expand "movstrictqi"
1560 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1561 (match_operand:QI 1 "general_operand" ""))]
1562 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1563 {
1564 /* Don't generate memory->memory moves, go through a register. */
1565 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1566 operands[1] = force_reg (QImode, operands[1]);
1567 })
1568
1569 (define_insn "*movstrictqi_1"
1570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1571 (match_operand:QI 1 "general_operand" "*qn,m"))]
1572 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1574 "mov{b}\t{%1, %0|%0, %1}"
1575 [(set_attr "type" "imov")
1576 (set_attr "mode" "QI")])
1577
1578 (define_insn "*movstrictqi_xor"
1579 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1580 (match_operand:QI 1 "const0_operand" "i"))
1581 (clobber (reg:CC 17))]
1582 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1583 "xor{b}\t{%0, %0|%0, %0}"
1584 [(set_attr "type" "alu1")
1585 (set_attr "mode" "QI")
1586 (set_attr "length_immediate" "0")])
1587
1588 (define_insn "*movsi_extv_1"
1589 [(set (match_operand:SI 0 "register_operand" "=R")
1590 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1591 (const_int 8)
1592 (const_int 8)))]
1593 ""
1594 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1595 [(set_attr "type" "imovx")
1596 (set_attr "mode" "SI")])
1597
1598 (define_insn "*movhi_extv_1"
1599 [(set (match_operand:HI 0 "register_operand" "=R")
1600 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1601 (const_int 8)
1602 (const_int 8)))]
1603 ""
1604 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1605 [(set_attr "type" "imovx")
1606 (set_attr "mode" "SI")])
1607
1608 (define_insn "*movqi_extv_1"
1609 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1610 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1611 (const_int 8)
1612 (const_int 8)))]
1613 "!TARGET_64BIT"
1614 {
1615 switch (get_attr_type (insn))
1616 {
1617 case TYPE_IMOVX:
1618 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1619 default:
1620 return "mov{b}\t{%h1, %0|%0, %h1}";
1621 }
1622 }
1623 [(set (attr "type")
1624 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1625 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1626 (ne (symbol_ref "TARGET_MOVX")
1627 (const_int 0))))
1628 (const_string "imovx")
1629 (const_string "imov")))
1630 (set (attr "mode")
1631 (if_then_else (eq_attr "type" "imovx")
1632 (const_string "SI")
1633 (const_string "QI")))])
1634
1635 (define_insn "*movqi_extv_1_rex64"
1636 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1637 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1638 (const_int 8)
1639 (const_int 8)))]
1640 "TARGET_64BIT"
1641 {
1642 switch (get_attr_type (insn))
1643 {
1644 case TYPE_IMOVX:
1645 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1646 default:
1647 return "mov{b}\t{%h1, %0|%0, %h1}";
1648 }
1649 }
1650 [(set (attr "type")
1651 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1652 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1653 (ne (symbol_ref "TARGET_MOVX")
1654 (const_int 0))))
1655 (const_string "imovx")
1656 (const_string "imov")))
1657 (set (attr "mode")
1658 (if_then_else (eq_attr "type" "imovx")
1659 (const_string "SI")
1660 (const_string "QI")))])
1661
1662 ;; Stores and loads of ax to arbitrary constant address.
1663 ;; We fake an second form of instruction to force reload to load address
1664 ;; into register when rax is not available
1665 (define_insn "*movabsqi_1_rex64"
1666 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1667 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1668 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1669 "@
1670 movabs{b}\t{%1, %P0|%P0, %1}
1671 mov{b}\t{%1, %a0|%a0, %1}"
1672 [(set_attr "type" "imov")
1673 (set_attr "modrm" "0,*")
1674 (set_attr "length_address" "8,0")
1675 (set_attr "length_immediate" "0,*")
1676 (set_attr "memory" "store")
1677 (set_attr "mode" "QI")])
1678
1679 (define_insn "*movabsqi_2_rex64"
1680 [(set (match_operand:QI 0 "register_operand" "=a,r")
1681 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1682 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1683 "@
1684 movabs{b}\t{%P1, %0|%0, %P1}
1685 mov{b}\t{%a1, %0|%0, %a1}"
1686 [(set_attr "type" "imov")
1687 (set_attr "modrm" "0,*")
1688 (set_attr "length_address" "8,0")
1689 (set_attr "length_immediate" "0")
1690 (set_attr "memory" "load")
1691 (set_attr "mode" "QI")])
1692
1693 (define_insn "*movsi_extzv_1"
1694 [(set (match_operand:SI 0 "register_operand" "=R")
1695 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1696 (const_int 8)
1697 (const_int 8)))]
1698 ""
1699 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1700 [(set_attr "type" "imovx")
1701 (set_attr "mode" "SI")])
1702
1703 (define_insn "*movqi_extzv_2"
1704 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1705 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1706 (const_int 8)
1707 (const_int 8)) 0))]
1708 "!TARGET_64BIT"
1709 {
1710 switch (get_attr_type (insn))
1711 {
1712 case TYPE_IMOVX:
1713 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1714 default:
1715 return "mov{b}\t{%h1, %0|%0, %h1}";
1716 }
1717 }
1718 [(set (attr "type")
1719 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1720 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1721 (ne (symbol_ref "TARGET_MOVX")
1722 (const_int 0))))
1723 (const_string "imovx")
1724 (const_string "imov")))
1725 (set (attr "mode")
1726 (if_then_else (eq_attr "type" "imovx")
1727 (const_string "SI")
1728 (const_string "QI")))])
1729
1730 (define_insn "*movqi_extzv_2_rex64"
1731 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733 (const_int 8)
1734 (const_int 8)) 0))]
1735 "TARGET_64BIT"
1736 {
1737 switch (get_attr_type (insn))
1738 {
1739 case TYPE_IMOVX:
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741 default:
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1743 }
1744 }
1745 [(set (attr "type")
1746 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747 (ne (symbol_ref "TARGET_MOVX")
1748 (const_int 0)))
1749 (const_string "imovx")
1750 (const_string "imov")))
1751 (set (attr "mode")
1752 (if_then_else (eq_attr "type" "imovx")
1753 (const_string "SI")
1754 (const_string "QI")))])
1755
1756 (define_insn "movsi_insv_1"
1757 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1758 (const_int 8)
1759 (const_int 8))
1760 (match_operand:SI 1 "general_operand" "Qmn"))]
1761 "!TARGET_64BIT"
1762 "mov{b}\t{%b1, %h0|%h0, %b1}"
1763 [(set_attr "type" "imov")
1764 (set_attr "mode" "QI")])
1765
1766 (define_insn "*movsi_insv_1_rex64"
1767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1768 (const_int 8)
1769 (const_int 8))
1770 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1771 "TARGET_64BIT"
1772 "mov{b}\t{%b1, %h0|%h0, %b1}"
1773 [(set_attr "type" "imov")
1774 (set_attr "mode" "QI")])
1775
1776 (define_insn "*movqi_insv_2"
1777 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778 (const_int 8)
1779 (const_int 8))
1780 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1781 (const_int 8))
1782 (const_int 255)))]
1783 ""
1784 "mov{b}\t{%h1, %h0|%h0, %h1}"
1785 [(set_attr "type" "imov")
1786 (set_attr "mode" "QI")])
1787
1788 (define_expand "movdi"
1789 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1790 (match_operand:DI 1 "general_operand" ""))]
1791 ""
1792 "ix86_expand_move (DImode, operands); DONE;")
1793
1794 (define_insn "*pushdi"
1795 [(set (match_operand:DI 0 "push_operand" "=<")
1796 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1797 "!TARGET_64BIT"
1798 "#")
1799
1800 (define_insn "pushdi2_rex64"
1801 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1802 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1803 "TARGET_64BIT"
1804 "@
1805 push{q}\t%1
1806 #"
1807 [(set_attr "type" "push,multi")
1808 (set_attr "mode" "DI")])
1809
1810 ;; Convert impossible pushes of immediate to existing instructions.
1811 ;; First try to get scratch register and go through it. In case this
1812 ;; fails, push sign extended lower part first and then overwrite
1813 ;; upper part by 32bit move.
1814 (define_peephole2
1815 [(match_scratch:DI 2 "r")
1816 (set (match_operand:DI 0 "push_operand" "")
1817 (match_operand:DI 1 "immediate_operand" ""))]
1818 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1819 && !x86_64_immediate_operand (operands[1], DImode)"
1820 [(set (match_dup 2) (match_dup 1))
1821 (set (match_dup 0) (match_dup 2))]
1822 "")
1823
1824 ;; We need to define this as both peepholer and splitter for case
1825 ;; peephole2 pass is not run.
1826 (define_peephole2
1827 [(set (match_operand:DI 0 "push_operand" "")
1828 (match_operand:DI 1 "immediate_operand" ""))]
1829 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1831 [(set (match_dup 0) (match_dup 1))
1832 (set (match_dup 2) (match_dup 3))]
1833 "split_di (operands + 1, 1, operands + 2, operands + 3);
1834 operands[1] = gen_lowpart (DImode, operands[2]);
1835 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1836 GEN_INT (4)));
1837 ")
1838
1839 (define_split
1840 [(set (match_operand:DI 0 "push_operand" "")
1841 (match_operand:DI 1 "immediate_operand" ""))]
1842 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1843 && !symbolic_operand (operands[1], DImode)
1844 && !x86_64_immediate_operand (operands[1], DImode)"
1845 [(set (match_dup 0) (match_dup 1))
1846 (set (match_dup 2) (match_dup 3))]
1847 "split_di (operands + 1, 1, operands + 2, operands + 3);
1848 operands[1] = gen_lowpart (DImode, operands[2]);
1849 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1850 GEN_INT (4)));
1851 ")
1852
1853 (define_insn "*pushdi2_prologue_rex64"
1854 [(set (match_operand:DI 0 "push_operand" "=<")
1855 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1856 (clobber (mem:BLK (scratch)))]
1857 "TARGET_64BIT"
1858 "push{q}\t%1"
1859 [(set_attr "type" "push")
1860 (set_attr "mode" "DI")])
1861
1862 (define_insn "*popdi1_epilogue_rex64"
1863 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1864 (mem:DI (reg:DI 7)))
1865 (set (reg:DI 7)
1866 (plus:DI (reg:DI 7) (const_int 8)))
1867 (clobber (mem:BLK (scratch)))]
1868 "TARGET_64BIT"
1869 "pop{q}\t%0"
1870 [(set_attr "type" "pop")
1871 (set_attr "mode" "DI")])
1872
1873 (define_insn "popdi1"
1874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1875 (mem:DI (reg:DI 7)))
1876 (set (reg:DI 7)
1877 (plus:DI (reg:DI 7) (const_int 8)))]
1878 "TARGET_64BIT"
1879 "pop{q}\t%0"
1880 [(set_attr "type" "pop")
1881 (set_attr "mode" "DI")])
1882
1883 (define_insn "*movdi_xor_rex64"
1884 [(set (match_operand:DI 0 "register_operand" "=r")
1885 (match_operand:DI 1 "const0_operand" "i"))
1886 (clobber (reg:CC 17))]
1887 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1888 && reload_completed"
1889 "xor{l}\t{%k0, %k0|%k0, %k0}"
1890 [(set_attr "type" "alu1")
1891 (set_attr "mode" "SI")
1892 (set_attr "length_immediate" "0")])
1893
1894 (define_insn "*movdi_or_rex64"
1895 [(set (match_operand:DI 0 "register_operand" "=r")
1896 (match_operand:DI 1 "const_int_operand" "i"))
1897 (clobber (reg:CC 17))]
1898 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1899 && reload_completed
1900 && operands[1] == constm1_rtx"
1901 {
1902 operands[1] = constm1_rtx;
1903 return "or{q}\t{%1, %0|%0, %1}";
1904 }
1905 [(set_attr "type" "alu1")
1906 (set_attr "mode" "DI")
1907 (set_attr "length_immediate" "1")])
1908
1909 (define_insn "*movdi_2"
1910 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1911 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1912 "!TARGET_64BIT
1913 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1914 "@
1915 #
1916 #
1917 movq\t{%1, %0|%0, %1}
1918 movq\t{%1, %0|%0, %1}
1919 movq\t{%1, %0|%0, %1}
1920 movdqa\t{%1, %0|%0, %1}
1921 movq\t{%1, %0|%0, %1}"
1922 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1923 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1924
1925 (define_split
1926 [(set (match_operand:DI 0 "push_operand" "")
1927 (match_operand:DI 1 "general_operand" ""))]
1928 "!TARGET_64BIT && reload_completed
1929 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1930 [(const_int 0)]
1931 "ix86_split_long_move (operands); DONE;")
1932
1933 ;; %%% This multiword shite has got to go.
1934 (define_split
1935 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1936 (match_operand:DI 1 "general_operand" ""))]
1937 "!TARGET_64BIT && reload_completed
1938 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1939 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1940 [(const_int 0)]
1941 "ix86_split_long_move (operands); DONE;")
1942
1943 (define_insn "*movdi_1_rex64"
1944 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1945 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1946 "TARGET_64BIT
1947 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1948 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1949 {
1950 switch (get_attr_type (insn))
1951 {
1952 case TYPE_SSEMOV:
1953 if (get_attr_mode (insn) == MODE_TI)
1954 return "movdqa\t{%1, %0|%0, %1}";
1955 /* FALLTHRU */
1956 case TYPE_MMXMOV:
1957 /* Moves from and into integer register is done using movd opcode with
1958 REX prefix. */
1959 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1960 return "movd\t{%1, %0|%0, %1}";
1961 return "movq\t{%1, %0|%0, %1}";
1962 case TYPE_MULTI:
1963 return "#";
1964 case TYPE_LEA:
1965 return "lea{q}\t{%a1, %0|%0, %a1}";
1966 default:
1967 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1968 abort ();
1969 if (get_attr_mode (insn) == MODE_SI)
1970 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1971 else if (which_alternative == 2)
1972 return "movabs{q}\t{%1, %0|%0, %1}";
1973 else
1974 return "mov{q}\t{%1, %0|%0, %1}";
1975 }
1976 }
1977 [(set (attr "type")
1978 (cond [(eq_attr "alternative" "5,6,7")
1979 (const_string "mmxmov")
1980 (eq_attr "alternative" "8,9,10")
1981 (const_string "ssemov")
1982 (eq_attr "alternative" "4")
1983 (const_string "multi")
1984 (and (ne (symbol_ref "flag_pic") (const_int 0))
1985 (match_operand:DI 1 "symbolic_operand" ""))
1986 (const_string "lea")
1987 ]
1988 (const_string "imov")))
1989 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1990 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1991 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1992
1993 (define_insn "*movdi_1_rex64_nointerunit"
1994 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1995 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1996 "TARGET_64BIT
1997 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
1998 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1999 {
2000 switch (get_attr_type (insn))
2001 {
2002 case TYPE_SSEMOV:
2003 if (get_attr_mode (insn) == MODE_TI)
2004 return "movdqa\t{%1, %0|%0, %1}";
2005 /* FALLTHRU */
2006 case TYPE_MMXMOV:
2007 return "movq\t{%1, %0|%0, %1}";
2008 case TYPE_MULTI:
2009 return "#";
2010 case TYPE_LEA:
2011 return "lea{q}\t{%a1, %0|%0, %a1}";
2012 default:
2013 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2014 abort ();
2015 if (get_attr_mode (insn) == MODE_SI)
2016 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2017 else if (which_alternative == 2)
2018 return "movabs{q}\t{%1, %0|%0, %1}";
2019 else
2020 return "mov{q}\t{%1, %0|%0, %1}";
2021 }
2022 }
2023 [(set (attr "type")
2024 (cond [(eq_attr "alternative" "5,6,7")
2025 (const_string "mmxmov")
2026 (eq_attr "alternative" "8,9,10")
2027 (const_string "ssemov")
2028 (eq_attr "alternative" "4")
2029 (const_string "multi")
2030 (and (ne (symbol_ref "flag_pic") (const_int 0))
2031 (match_operand:DI 1 "symbolic_operand" ""))
2032 (const_string "lea")
2033 ]
2034 (const_string "imov")))
2035 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2036 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2037 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2038
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2046 "@
2047 movabs{q}\t{%1, %P0|%P0, %1}
2048 mov{q}\t{%1, %a0|%a0, %1}"
2049 [(set_attr "type" "imov")
2050 (set_attr "modrm" "0,*")
2051 (set_attr "length_address" "8,0")
2052 (set_attr "length_immediate" "0,*")
2053 (set_attr "memory" "store")
2054 (set_attr "mode" "DI")])
2055
2056 (define_insn "*movabsdi_2_rex64"
2057 [(set (match_operand:DI 0 "register_operand" "=a,r")
2058 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2060 "@
2061 movabs{q}\t{%P1, %0|%0, %P1}
2062 mov{q}\t{%a1, %0|%0, %a1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "modrm" "0,*")
2065 (set_attr "length_address" "8,0")
2066 (set_attr "length_immediate" "0")
2067 (set_attr "memory" "load")
2068 (set_attr "mode" "DI")])
2069
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2073 (define_peephole2
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))]
2081 "")
2082
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 (define_peephole2
2086 [(set (match_operand:DI 0 "memory_operand" "")
2087 (match_operand:DI 1 "immediate_operand" ""))]
2088 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2089 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2090 [(set (match_dup 2) (match_dup 3))
2091 (set (match_dup 4) (match_dup 5))]
2092 "split_di (operands, 2, operands + 2, operands + 4);")
2093
2094 (define_split
2095 [(set (match_operand:DI 0 "memory_operand" "")
2096 (match_operand:DI 1 "immediate_operand" ""))]
2097 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 2) (match_dup 3))
2101 (set (match_dup 4) (match_dup 5))]
2102 "split_di (operands, 2, operands + 2, operands + 4);")
2103
2104 (define_insn "*swapdi_rex64"
2105 [(set (match_operand:DI 0 "register_operand" "+r")
2106 (match_operand:DI 1 "register_operand" "+r"))
2107 (set (match_dup 1)
2108 (match_dup 0))]
2109 "TARGET_64BIT"
2110 "xchg{q}\t%1, %0"
2111 [(set_attr "type" "imov")
2112 (set_attr "pent_pair" "np")
2113 (set_attr "athlon_decode" "vector")
2114 (set_attr "mode" "DI")
2115 (set_attr "modrm" "0")
2116 (set_attr "ppro_uops" "few")])
2117
2118
2119 (define_expand "movsf"
2120 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2121 (match_operand:SF 1 "general_operand" ""))]
2122 ""
2123 "ix86_expand_move (SFmode, operands); DONE;")
2124
2125 (define_insn "*pushsf"
2126 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2127 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2128 "!TARGET_64BIT"
2129 {
2130 switch (which_alternative)
2131 {
2132 case 1:
2133 return "push{l}\t%1";
2134
2135 default:
2136 /* This insn should be already split before reg-stack. */
2137 abort ();
2138 }
2139 }
2140 [(set_attr "type" "multi,push,multi")
2141 (set_attr "mode" "SF,SI,SF")])
2142
2143 (define_insn "*pushsf_rex64"
2144 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2145 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2146 "TARGET_64BIT"
2147 {
2148 switch (which_alternative)
2149 {
2150 case 1:
2151 return "push{q}\t%q1";
2152
2153 default:
2154 /* This insn should be already split before reg-stack. */
2155 abort ();
2156 }
2157 }
2158 [(set_attr "type" "multi,push,multi")
2159 (set_attr "mode" "SF,DI,SF")])
2160
2161 (define_split
2162 [(set (match_operand:SF 0 "push_operand" "")
2163 (match_operand:SF 1 "memory_operand" ""))]
2164 "reload_completed
2165 && GET_CODE (operands[1]) == MEM
2166 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2167 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2168 [(set (match_dup 0)
2169 (match_dup 1))]
2170 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2171
2172
2173 ;; %%% Kill this when call knows how to work this out.
2174 (define_split
2175 [(set (match_operand:SF 0 "push_operand" "")
2176 (match_operand:SF 1 "any_fp_register_operand" ""))]
2177 "!TARGET_64BIT"
2178 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2179 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2180
2181 (define_split
2182 [(set (match_operand:SF 0 "push_operand" "")
2183 (match_operand:SF 1 "any_fp_register_operand" ""))]
2184 "TARGET_64BIT"
2185 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2186 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2187
2188 (define_insn "*movsf_1"
2189 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2190 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2191 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2192 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2193 && (reload_in_progress || reload_completed
2194 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2195 || GET_CODE (operands[1]) != CONST_DOUBLE
2196 || memory_operand (operands[0], SFmode))"
2197 {
2198 switch (which_alternative)
2199 {
2200 case 0:
2201 if (REG_P (operands[1])
2202 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2203 return "fstp\t%y0";
2204 else if (STACK_TOP_P (operands[0]))
2205 return "fld%z1\t%y1";
2206 else
2207 return "fst\t%y0";
2208
2209 case 1:
2210 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2211 return "fstp%z0\t%y0";
2212 else
2213 return "fst%z0\t%y0";
2214
2215 case 2:
2216 return standard_80387_constant_opcode (operands[1]);
2217
2218 case 3:
2219 case 4:
2220 return "mov{l}\t{%1, %0|%0, %1}";
2221 case 5:
2222 if (get_attr_mode (insn) == MODE_TI)
2223 return "pxor\t%0, %0";
2224 else
2225 return "xorps\t%0, %0";
2226 case 6:
2227 if (get_attr_mode (insn) == MODE_V4SF)
2228 return "movaps\t{%1, %0|%0, %1}";
2229 else
2230 return "movss\t{%1, %0|%0, %1}";
2231 case 7:
2232 case 8:
2233 return "movss\t{%1, %0|%0, %1}";
2234
2235 case 9:
2236 case 10:
2237 return "movd\t{%1, %0|%0, %1}";
2238
2239 case 11:
2240 return "movq\t{%1, %0|%0, %1}";
2241
2242 default:
2243 abort();
2244 }
2245 }
2246 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2247 (set (attr "mode")
2248 (cond [(eq_attr "alternative" "3,4,9,10")
2249 (const_string "SI")
2250 (eq_attr "alternative" "5")
2251 (if_then_else
2252 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2253 (const_int 0))
2254 (ne (symbol_ref "TARGET_SSE2")
2255 (const_int 0)))
2256 (eq (symbol_ref "optimize_size")
2257 (const_int 0)))
2258 (const_string "TI")
2259 (const_string "V4SF"))
2260 /* For architectures resolving dependencies on
2261 whole SSE registers use APS move to break dependency
2262 chains, otherwise use short move to avoid extra work.
2263
2264 Do the same for architectures resolving dependencies on
2265 the parts. While in DF mode it is better to always handle
2266 just register parts, the SF mode is different due to lack
2267 of instructions to load just part of the register. It is
2268 better to maintain the whole registers in single format
2269 to avoid problems on using packed logical operations. */
2270 (eq_attr "alternative" "6")
2271 (if_then_else
2272 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2273 (const_int 0))
2274 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2275 (const_int 0)))
2276 (const_string "V4SF")
2277 (const_string "SF"))
2278 (eq_attr "alternative" "11")
2279 (const_string "DI")]
2280 (const_string "SF")))])
2281
2282 (define_insn "*movsf_1_nointerunit"
2283 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2284 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2285 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2286 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2287 && (reload_in_progress || reload_completed
2288 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2289 || GET_CODE (operands[1]) != CONST_DOUBLE
2290 || memory_operand (operands[0], SFmode))"
2291 {
2292 switch (which_alternative)
2293 {
2294 case 0:
2295 if (REG_P (operands[1])
2296 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2297 {
2298 if (REGNO (operands[0]) == FIRST_STACK_REG
2299 && TARGET_USE_FFREEP)
2300 return "ffreep\t%y0";
2301 return "fstp\t%y0";
2302 }
2303 else if (STACK_TOP_P (operands[0]))
2304 return "fld%z1\t%y1";
2305 else
2306 return "fst\t%y0";
2307
2308 case 1:
2309 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2310 return "fstp%z0\t%y0";
2311 else
2312 return "fst%z0\t%y0";
2313
2314 case 2:
2315 return standard_80387_constant_opcode (operands[1]);
2316
2317 case 3:
2318 case 4:
2319 return "mov{l}\t{%1, %0|%0, %1}";
2320 case 5:
2321 if (get_attr_mode (insn) == MODE_TI)
2322 return "pxor\t%0, %0";
2323 else
2324 return "xorps\t%0, %0";
2325 case 6:
2326 if (get_attr_mode (insn) == MODE_V4SF)
2327 return "movaps\t{%1, %0|%0, %1}";
2328 else
2329 return "movss\t{%1, %0|%0, %1}";
2330 case 7:
2331 case 8:
2332 return "movss\t{%1, %0|%0, %1}";
2333
2334 case 9:
2335 case 10:
2336 return "movd\t{%1, %0|%0, %1}";
2337
2338 case 11:
2339 return "movq\t{%1, %0|%0, %1}";
2340
2341 default:
2342 abort();
2343 }
2344 }
2345 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2346 (set (attr "mode")
2347 (cond [(eq_attr "alternative" "3,4,9,10")
2348 (const_string "SI")
2349 (eq_attr "alternative" "5")
2350 (if_then_else
2351 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2352 (const_int 0))
2353 (ne (symbol_ref "TARGET_SSE2")
2354 (const_int 0)))
2355 (eq (symbol_ref "optimize_size")
2356 (const_int 0)))
2357 (const_string "TI")
2358 (const_string "V4SF"))
2359 /* For architectures resolving dependencies on
2360 whole SSE registers use APS move to break dependency
2361 chains, otherwise use short move to avoid extra work.
2362
2363 Do the same for architectures resolving dependencies on
2364 the parts. While in DF mode it is better to always handle
2365 just register parts, the SF mode is different due to lack
2366 of instructions to load just part of the register. It is
2367 better to maintain the whole registers in single format
2368 to avoid problems on using packed logical operations. */
2369 (eq_attr "alternative" "6")
2370 (if_then_else
2371 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2372 (const_int 0))
2373 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2374 (const_int 0)))
2375 (const_string "V4SF")
2376 (const_string "SF"))
2377 (eq_attr "alternative" "11")
2378 (const_string "DI")]
2379 (const_string "SF")))])
2380
2381 (define_insn "*swapsf"
2382 [(set (match_operand:SF 0 "register_operand" "+f")
2383 (match_operand:SF 1 "register_operand" "+f"))
2384 (set (match_dup 1)
2385 (match_dup 0))]
2386 "reload_completed || !TARGET_SSE"
2387 {
2388 if (STACK_TOP_P (operands[0]))
2389 return "fxch\t%1";
2390 else
2391 return "fxch\t%0";
2392 }
2393 [(set_attr "type" "fxch")
2394 (set_attr "mode" "SF")])
2395
2396 (define_expand "movdf"
2397 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2398 (match_operand:DF 1 "general_operand" ""))]
2399 ""
2400 "ix86_expand_move (DFmode, operands); DONE;")
2401
2402 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2403 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2404 ;; On the average, pushdf using integers can be still shorter. Allow this
2405 ;; pattern for optimize_size too.
2406
2407 (define_insn "*pushdf_nointeger"
2408 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2409 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2410 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2411 {
2412 /* This insn should be already split before reg-stack. */
2413 abort ();
2414 }
2415 [(set_attr "type" "multi")
2416 (set_attr "mode" "DF,SI,SI,DF")])
2417
2418 (define_insn "*pushdf_integer"
2419 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2420 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2421 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2422 {
2423 /* This insn should be already split before reg-stack. */
2424 abort ();
2425 }
2426 [(set_attr "type" "multi")
2427 (set_attr "mode" "DF,SI,DF")])
2428
2429 ;; %%% Kill this when call knows how to work this out.
2430 (define_split
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "any_fp_register_operand" ""))]
2433 "!TARGET_64BIT && reload_completed"
2434 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2435 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2436 "")
2437
2438 (define_split
2439 [(set (match_operand:DF 0 "push_operand" "")
2440 (match_operand:DF 1 "any_fp_register_operand" ""))]
2441 "TARGET_64BIT && reload_completed"
2442 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2443 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2444 "")
2445
2446 (define_split
2447 [(set (match_operand:DF 0 "push_operand" "")
2448 (match_operand:DF 1 "general_operand" ""))]
2449 "reload_completed"
2450 [(const_int 0)]
2451 "ix86_split_long_move (operands); DONE;")
2452
2453 ;; Moving is usually shorter when only FP registers are used. This separate
2454 ;; movdf pattern avoids the use of integer registers for FP operations
2455 ;; when optimizing for size.
2456
2457 (define_insn "*movdf_nointeger"
2458 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2459 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2460 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2461 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2462 && (reload_in_progress || reload_completed
2463 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2464 || GET_CODE (operands[1]) != CONST_DOUBLE
2465 || memory_operand (operands[0], DFmode))"
2466 {
2467 switch (which_alternative)
2468 {
2469 case 0:
2470 if (REG_P (operands[1])
2471 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2472 {
2473 if (REGNO (operands[0]) == FIRST_STACK_REG
2474 && TARGET_USE_FFREEP)
2475 return "ffreep\t%y0";
2476 return "fstp\t%y0";
2477 }
2478 else if (STACK_TOP_P (operands[0]))
2479 return "fld%z1\t%y1";
2480 else
2481 return "fst\t%y0";
2482
2483 case 1:
2484 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2485 return "fstp%z0\t%y0";
2486 else
2487 return "fst%z0\t%y0";
2488
2489 case 2:
2490 return standard_80387_constant_opcode (operands[1]);
2491
2492 case 3:
2493 case 4:
2494 return "#";
2495 case 5:
2496 switch (get_attr_mode (insn))
2497 {
2498 case MODE_V4SF:
2499 return "xorps\t%0, %0";
2500 case MODE_V2DF:
2501 return "xorpd\t%0, %0";
2502 case MODE_TI:
2503 return "pxor\t%0, %0";
2504 default:
2505 abort ();
2506 }
2507 case 6:
2508 switch (get_attr_mode (insn))
2509 {
2510 case MODE_V4SF:
2511 return "movaps\t{%1, %0|%0, %1}";
2512 case MODE_V2DF:
2513 return "movapd\t{%1, %0|%0, %1}";
2514 case MODE_DF:
2515 return "movsd\t{%1, %0|%0, %1}";
2516 default:
2517 abort ();
2518 }
2519 case 7:
2520 if (get_attr_mode (insn) == MODE_V2DF)
2521 return "movlpd\t{%1, %0|%0, %1}";
2522 else
2523 return "movsd\t{%1, %0|%0, %1}";
2524 case 8:
2525 return "movsd\t{%1, %0|%0, %1}";
2526
2527 default:
2528 abort();
2529 }
2530 }
2531 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2532 (set (attr "mode")
2533 (cond [(eq_attr "alternative" "3,4")
2534 (const_string "SI")
2535 /* xorps is one byte shorter. */
2536 (eq_attr "alternative" "5")
2537 (cond [(ne (symbol_ref "optimize_size")
2538 (const_int 0))
2539 (const_string "V4SF")
2540 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2541 (const_int 0))
2542 (const_string "TI")]
2543 (const_string "V2DF"))
2544 /* For architectures resolving dependencies on
2545 whole SSE registers use APD move to break dependency
2546 chains, otherwise use short move to avoid extra work.
2547
2548 movaps encodes one byte shorter. */
2549 (eq_attr "alternative" "6")
2550 (cond
2551 [(ne (symbol_ref "optimize_size")
2552 (const_int 0))
2553 (const_string "V4SF")
2554 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2555 (const_int 0))
2556 (const_string "V2DF")]
2557 (const_string "DF"))
2558 /* For architectures resolving dependencies on register
2559 parts we may avoid extra work to zero out upper part
2560 of register. */
2561 (eq_attr "alternative" "7")
2562 (if_then_else
2563 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2564 (const_int 0))
2565 (const_string "V2DF")
2566 (const_string "DF"))]
2567 (const_string "DF")))])
2568
2569 (define_insn "*movdf_integer"
2570 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2571 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2572 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2573 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2574 && (reload_in_progress || reload_completed
2575 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2576 || GET_CODE (operands[1]) != CONST_DOUBLE
2577 || memory_operand (operands[0], DFmode))"
2578 {
2579 switch (which_alternative)
2580 {
2581 case 0:
2582 if (REG_P (operands[1])
2583 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2584 {
2585 if (REGNO (operands[0]) == FIRST_STACK_REG
2586 && TARGET_USE_FFREEP)
2587 return "ffreep\t%y0";
2588 return "fstp\t%y0";
2589 }
2590 else if (STACK_TOP_P (operands[0]))
2591 return "fld%z1\t%y1";
2592 else
2593 return "fst\t%y0";
2594
2595 case 1:
2596 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2597 return "fstp%z0\t%y0";
2598 else
2599 return "fst%z0\t%y0";
2600
2601 case 2:
2602 return standard_80387_constant_opcode (operands[1]);
2603
2604 case 3:
2605 case 4:
2606 return "#";
2607
2608 case 5:
2609 switch (get_attr_mode (insn))
2610 {
2611 case MODE_V4SF:
2612 return "xorps\t%0, %0";
2613 case MODE_V2DF:
2614 return "xorpd\t%0, %0";
2615 case MODE_TI:
2616 return "pxor\t%0, %0";
2617 default:
2618 abort ();
2619 }
2620 case 6:
2621 switch (get_attr_mode (insn))
2622 {
2623 case MODE_V4SF:
2624 return "movaps\t{%1, %0|%0, %1}";
2625 case MODE_V2DF:
2626 return "movapd\t{%1, %0|%0, %1}";
2627 case MODE_DF:
2628 return "movsd\t{%1, %0|%0, %1}";
2629 default:
2630 abort ();
2631 }
2632 case 7:
2633 if (get_attr_mode (insn) == MODE_V2DF)
2634 return "movlpd\t{%1, %0|%0, %1}";
2635 else
2636 return "movsd\t{%1, %0|%0, %1}";
2637 case 8:
2638 return "movsd\t{%1, %0|%0, %1}";
2639
2640 default:
2641 abort();
2642 }
2643 }
2644 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2645 (set (attr "mode")
2646 (cond [(eq_attr "alternative" "3,4")
2647 (const_string "SI")
2648 /* xorps is one byte shorter. */
2649 (eq_attr "alternative" "5")
2650 (cond [(ne (symbol_ref "optimize_size")
2651 (const_int 0))
2652 (const_string "V4SF")
2653 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654 (const_int 0))
2655 (const_string "TI")]
2656 (const_string "V2DF"))
2657 /* For architectures resolving dependencies on
2658 whole SSE registers use APD move to break dependency
2659 chains, otherwise use short move to avoid extra work.
2660
2661 movaps encodes one byte shorter. */
2662 (eq_attr "alternative" "6")
2663 (cond
2664 [(ne (symbol_ref "optimize_size")
2665 (const_int 0))
2666 (const_string "V4SF")
2667 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668 (const_int 0))
2669 (const_string "V2DF")]
2670 (const_string "DF"))
2671 /* For architectures resolving dependencies on register
2672 parts we may avoid extra work to zero out upper part
2673 of register. */
2674 (eq_attr "alternative" "7")
2675 (if_then_else
2676 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2677 (const_int 0))
2678 (const_string "V2DF")
2679 (const_string "DF"))]
2680 (const_string "DF")))])
2681
2682 (define_split
2683 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684 (match_operand:DF 1 "general_operand" ""))]
2685 "reload_completed
2686 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687 && ! (ANY_FP_REG_P (operands[0]) ||
2688 (GET_CODE (operands[0]) == SUBREG
2689 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690 && ! (ANY_FP_REG_P (operands[1]) ||
2691 (GET_CODE (operands[1]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2693 [(const_int 0)]
2694 "ix86_split_long_move (operands); DONE;")
2695
2696 (define_insn "*swapdf"
2697 [(set (match_operand:DF 0 "register_operand" "+f")
2698 (match_operand:DF 1 "register_operand" "+f"))
2699 (set (match_dup 1)
2700 (match_dup 0))]
2701 "reload_completed || !TARGET_SSE2"
2702 {
2703 if (STACK_TOP_P (operands[0]))
2704 return "fxch\t%1";
2705 else
2706 return "fxch\t%0";
2707 }
2708 [(set_attr "type" "fxch")
2709 (set_attr "mode" "DF")])
2710
2711 (define_expand "movxf"
2712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713 (match_operand:XF 1 "general_operand" ""))]
2714 ""
2715 "ix86_expand_move (XFmode, operands); DONE;")
2716
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;; handled elsewhere).
2723
2724 (define_insn "*pushxf_nointeger"
2725 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727 "optimize_size"
2728 {
2729 /* This insn should be already split before reg-stack. */
2730 abort ();
2731 }
2732 [(set_attr "type" "multi")
2733 (set_attr "mode" "XF,SI,SI")])
2734
2735 (define_insn "*pushxf_integer"
2736 [(set (match_operand:XF 0 "push_operand" "=<,<")
2737 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2738 "!optimize_size"
2739 {
2740 /* This insn should be already split before reg-stack. */
2741 abort ();
2742 }
2743 [(set_attr "type" "multi")
2744 (set_attr "mode" "XF,SI")])
2745
2746 (define_split
2747 [(set (match_operand 0 "push_operand" "")
2748 (match_operand 1 "general_operand" ""))]
2749 "reload_completed
2750 && (GET_MODE (operands[0]) == XFmode
2751 || GET_MODE (operands[0]) == DFmode)
2752 && !ANY_FP_REG_P (operands[1])"
2753 [(const_int 0)]
2754 "ix86_split_long_move (operands); DONE;")
2755
2756 (define_split
2757 [(set (match_operand:XF 0 "push_operand" "")
2758 (match_operand:XF 1 "any_fp_register_operand" ""))]
2759 "!TARGET_64BIT"
2760 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2761 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2762 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2763
2764 (define_split
2765 [(set (match_operand:XF 0 "push_operand" "")
2766 (match_operand:XF 1 "any_fp_register_operand" ""))]
2767 "TARGET_64BIT"
2768 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2769 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2770 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2771
2772 ;; Do not use integer registers when optimizing for size
2773 (define_insn "*movxf_nointeger"
2774 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2775 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2776 "optimize_size
2777 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778 && (reload_in_progress || reload_completed
2779 || GET_CODE (operands[1]) != CONST_DOUBLE
2780 || memory_operand (operands[0], XFmode))"
2781 {
2782 switch (which_alternative)
2783 {
2784 case 0:
2785 if (REG_P (operands[1])
2786 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787 {
2788 if (REGNO (operands[0]) == FIRST_STACK_REG
2789 && TARGET_USE_FFREEP)
2790 return "ffreep\t%y0";
2791 return "fstp\t%y0";
2792 }
2793 else if (STACK_TOP_P (operands[0]))
2794 return "fld%z1\t%y1";
2795 else
2796 return "fst\t%y0";
2797
2798 case 1:
2799 /* There is no non-popping store to memory for XFmode. So if
2800 we need one, follow the store with a load. */
2801 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802 return "fstp%z0\t%y0\;fld%z0\t%y0";
2803 else
2804 return "fstp%z0\t%y0";
2805
2806 case 2:
2807 return standard_80387_constant_opcode (operands[1]);
2808
2809 case 3: case 4:
2810 return "#";
2811 }
2812 abort();
2813 }
2814 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2815 (set_attr "mode" "XF,XF,XF,SI,SI")])
2816
2817 (define_insn "*movxf_integer"
2818 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2819 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2820 "!optimize_size
2821 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2822 && (reload_in_progress || reload_completed
2823 || GET_CODE (operands[1]) != CONST_DOUBLE
2824 || memory_operand (operands[0], XFmode))"
2825 {
2826 switch (which_alternative)
2827 {
2828 case 0:
2829 if (REG_P (operands[1])
2830 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2831 {
2832 if (REGNO (operands[0]) == FIRST_STACK_REG
2833 && TARGET_USE_FFREEP)
2834 return "ffreep\t%y0";
2835 return "fstp\t%y0";
2836 }
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 return standard_80387_constant_opcode (operands[1]);
2852
2853 case 3: case 4:
2854 return "#";
2855 }
2856 abort();
2857 }
2858 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2859 (set_attr "mode" "XF,XF,XF,SI,SI")])
2860
2861 (define_split
2862 [(set (match_operand 0 "nonimmediate_operand" "")
2863 (match_operand 1 "general_operand" ""))]
2864 "reload_completed
2865 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2866 && GET_MODE (operands[0]) == XFmode
2867 && ! (ANY_FP_REG_P (operands[0]) ||
2868 (GET_CODE (operands[0]) == SUBREG
2869 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2870 && ! (ANY_FP_REG_P (operands[1]) ||
2871 (GET_CODE (operands[1]) == SUBREG
2872 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2873 [(const_int 0)]
2874 "ix86_split_long_move (operands); DONE;")
2875
2876 (define_split
2877 [(set (match_operand 0 "register_operand" "")
2878 (match_operand 1 "memory_operand" ""))]
2879 "reload_completed
2880 && GET_CODE (operands[1]) == MEM
2881 && (GET_MODE (operands[0]) == XFmode
2882 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2883 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2884 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
2885 && (!(SSE_REG_P (operands[0]) ||
2886 (GET_CODE (operands[0]) == SUBREG
2887 && SSE_REG_P (SUBREG_REG (operands[0]))))
2888 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
2889 && (!(FP_REG_P (operands[0]) ||
2890 (GET_CODE (operands[0]) == SUBREG
2891 && FP_REG_P (SUBREG_REG (operands[0]))))
2892 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
2893 [(set (match_dup 0)
2894 (match_dup 1))]
2895 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2896
2897 (define_insn "swapxf"
2898 [(set (match_operand:XF 0 "register_operand" "+f")
2899 (match_operand:XF 1 "register_operand" "+f"))
2900 (set (match_dup 1)
2901 (match_dup 0))]
2902 ""
2903 {
2904 if (STACK_TOP_P (operands[0]))
2905 return "fxch\t%1";
2906 else
2907 return "fxch\t%0";
2908 }
2909 [(set_attr "type" "fxch")
2910 (set_attr "mode" "XF")])
2911 \f
2912 ;; Zero extension instructions
2913
2914 (define_expand "zero_extendhisi2"
2915 [(set (match_operand:SI 0 "register_operand" "")
2916 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2917 ""
2918 {
2919 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2920 {
2921 operands[1] = force_reg (HImode, operands[1]);
2922 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2923 DONE;
2924 }
2925 })
2926
2927 (define_insn "zero_extendhisi2_and"
2928 [(set (match_operand:SI 0 "register_operand" "=r")
2929 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2930 (clobber (reg:CC 17))]
2931 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2932 "#"
2933 [(set_attr "type" "alu1")
2934 (set_attr "mode" "SI")])
2935
2936 (define_split
2937 [(set (match_operand:SI 0 "register_operand" "")
2938 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2939 (clobber (reg:CC 17))]
2940 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2941 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2942 (clobber (reg:CC 17))])]
2943 "")
2944
2945 (define_insn "*zero_extendhisi2_movzwl"
2946 [(set (match_operand:SI 0 "register_operand" "=r")
2947 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2948 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2949 "movz{wl|x}\t{%1, %0|%0, %1}"
2950 [(set_attr "type" "imovx")
2951 (set_attr "mode" "SI")])
2952
2953 (define_expand "zero_extendqihi2"
2954 [(parallel
2955 [(set (match_operand:HI 0 "register_operand" "")
2956 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2957 (clobber (reg:CC 17))])]
2958 ""
2959 "")
2960
2961 (define_insn "*zero_extendqihi2_and"
2962 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2963 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2964 (clobber (reg:CC 17))]
2965 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2966 "#"
2967 [(set_attr "type" "alu1")
2968 (set_attr "mode" "HI")])
2969
2970 (define_insn "*zero_extendqihi2_movzbw_and"
2971 [(set (match_operand:HI 0 "register_operand" "=r,r")
2972 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2973 (clobber (reg:CC 17))]
2974 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2975 "#"
2976 [(set_attr "type" "imovx,alu1")
2977 (set_attr "mode" "HI")])
2978
2979 (define_insn "*zero_extendqihi2_movzbw"
2980 [(set (match_operand:HI 0 "register_operand" "=r")
2981 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2982 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2983 "movz{bw|x}\t{%1, %0|%0, %1}"
2984 [(set_attr "type" "imovx")
2985 (set_attr "mode" "HI")])
2986
2987 ;; For the movzbw case strip only the clobber
2988 (define_split
2989 [(set (match_operand:HI 0 "register_operand" "")
2990 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2991 (clobber (reg:CC 17))]
2992 "reload_completed
2993 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
2994 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
2995 [(set (match_operand:HI 0 "register_operand" "")
2996 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
2997
2998 ;; When source and destination does not overlap, clear destination
2999 ;; first and then do the movb
3000 (define_split
3001 [(set (match_operand:HI 0 "register_operand" "")
3002 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3003 (clobber (reg:CC 17))]
3004 "reload_completed
3005 && ANY_QI_REG_P (operands[0])
3006 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3007 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3008 [(set (match_dup 0) (const_int 0))
3009 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3010 "operands[2] = gen_lowpart (QImode, operands[0]);")
3011
3012 ;; Rest is handled by single and.
3013 (define_split
3014 [(set (match_operand:HI 0 "register_operand" "")
3015 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3016 (clobber (reg:CC 17))]
3017 "reload_completed
3018 && true_regnum (operands[0]) == true_regnum (operands[1])"
3019 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3020 (clobber (reg:CC 17))])]
3021 "")
3022
3023 (define_expand "zero_extendqisi2"
3024 [(parallel
3025 [(set (match_operand:SI 0 "register_operand" "")
3026 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3027 (clobber (reg:CC 17))])]
3028 ""
3029 "")
3030
3031 (define_insn "*zero_extendqisi2_and"
3032 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3033 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3034 (clobber (reg:CC 17))]
3035 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3036 "#"
3037 [(set_attr "type" "alu1")
3038 (set_attr "mode" "SI")])
3039
3040 (define_insn "*zero_extendqisi2_movzbw_and"
3041 [(set (match_operand:SI 0 "register_operand" "=r,r")
3042 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3043 (clobber (reg:CC 17))]
3044 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3045 "#"
3046 [(set_attr "type" "imovx,alu1")
3047 (set_attr "mode" "SI")])
3048
3049 (define_insn "*zero_extendqisi2_movzbw"
3050 [(set (match_operand:SI 0 "register_operand" "=r")
3051 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3052 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3053 "movz{bl|x}\t{%1, %0|%0, %1}"
3054 [(set_attr "type" "imovx")
3055 (set_attr "mode" "SI")])
3056
3057 ;; For the movzbl case strip only the clobber
3058 (define_split
3059 [(set (match_operand:SI 0 "register_operand" "")
3060 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3061 (clobber (reg:CC 17))]
3062 "reload_completed
3063 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3064 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3065 [(set (match_dup 0)
3066 (zero_extend:SI (match_dup 1)))])
3067
3068 ;; When source and destination does not overlap, clear destination
3069 ;; first and then do the movb
3070 (define_split
3071 [(set (match_operand:SI 0 "register_operand" "")
3072 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3073 (clobber (reg:CC 17))]
3074 "reload_completed
3075 && ANY_QI_REG_P (operands[0])
3076 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3077 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3078 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3079 [(set (match_dup 0) (const_int 0))
3080 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3081 "operands[2] = gen_lowpart (QImode, operands[0]);")
3082
3083 ;; Rest is handled by single and.
3084 (define_split
3085 [(set (match_operand:SI 0 "register_operand" "")
3086 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3087 (clobber (reg:CC 17))]
3088 "reload_completed
3089 && true_regnum (operands[0]) == true_regnum (operands[1])"
3090 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3091 (clobber (reg:CC 17))])]
3092 "")
3093
3094 ;; %%% Kill me once multi-word ops are sane.
3095 (define_expand "zero_extendsidi2"
3096 [(set (match_operand:DI 0 "register_operand" "=r")
3097 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3098 ""
3099 "if (!TARGET_64BIT)
3100 {
3101 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3102 DONE;
3103 }
3104 ")
3105
3106 (define_insn "zero_extendsidi2_32"
3107 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3108 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3109 (clobber (reg:CC 17))]
3110 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3111 "@
3112 #
3113 #
3114 #
3115 movd\t{%1, %0|%0, %1}
3116 movd\t{%1, %0|%0, %1}"
3117 [(set_attr "mode" "SI,SI,SI,DI,TI")
3118 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3119
3120 (define_insn "*zero_extendsidi2_32_1"
3121 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3122 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3123 (clobber (reg:CC 17))]
3124 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3125 "@
3126 #
3127 #
3128 #
3129 movd\t{%1, %0|%0, %1}
3130 movd\t{%1, %0|%0, %1}"
3131 [(set_attr "mode" "SI,SI,SI,DI,TI")
3132 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3133
3134 (define_insn "zero_extendsidi2_rex64"
3135 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3136 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3137 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3138 "@
3139 mov\t{%k1, %k0|%k0, %k1}
3140 #
3141 movd\t{%1, %0|%0, %1}
3142 movd\t{%1, %0|%0, %1}"
3143 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3144 (set_attr "mode" "SI,DI,DI,TI")])
3145
3146 (define_insn "*zero_extendsidi2_rex64_1"
3147 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3148 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3149 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3150 "@
3151 mov\t{%k1, %k0|%k0, %k1}
3152 #
3153 movd\t{%1, %0|%0, %1}
3154 movd\t{%1, %0|%0, %1}"
3155 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3156 (set_attr "mode" "SI,DI,SI,SI")])
3157
3158 (define_split
3159 [(set (match_operand:DI 0 "memory_operand" "")
3160 (zero_extend:DI (match_dup 0)))]
3161 "TARGET_64BIT"
3162 [(set (match_dup 4) (const_int 0))]
3163 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3164
3165 (define_split
3166 [(set (match_operand:DI 0 "register_operand" "")
3167 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3168 (clobber (reg:CC 17))]
3169 "!TARGET_64BIT && reload_completed
3170 && true_regnum (operands[0]) == true_regnum (operands[1])"
3171 [(set (match_dup 4) (const_int 0))]
3172 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3173
3174 (define_split
3175 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3176 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3177 (clobber (reg:CC 17))]
3178 "!TARGET_64BIT && reload_completed
3179 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3180 [(set (match_dup 3) (match_dup 1))
3181 (set (match_dup 4) (const_int 0))]
3182 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3183
3184 (define_insn "zero_extendhidi2"
3185 [(set (match_operand:DI 0 "register_operand" "=r,r")
3186 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3187 "TARGET_64BIT"
3188 "@
3189 movz{wl|x}\t{%1, %k0|%k0, %1}
3190 movz{wq|x}\t{%1, %0|%0, %1}"
3191 [(set_attr "type" "imovx")
3192 (set_attr "mode" "SI,DI")])
3193
3194 (define_insn "zero_extendqidi2"
3195 [(set (match_operand:DI 0 "register_operand" "=r,r")
3196 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3197 "TARGET_64BIT"
3198 "@
3199 movz{bl|x}\t{%1, %k0|%k0, %1}
3200 movz{bq|x}\t{%1, %0|%0, %1}"
3201 [(set_attr "type" "imovx")
3202 (set_attr "mode" "SI,DI")])
3203 \f
3204 ;; Sign extension instructions
3205
3206 (define_expand "extendsidi2"
3207 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3208 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3209 (clobber (reg:CC 17))
3210 (clobber (match_scratch:SI 2 ""))])]
3211 ""
3212 {
3213 if (TARGET_64BIT)
3214 {
3215 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3216 DONE;
3217 }
3218 })
3219
3220 (define_insn "*extendsidi2_1"
3221 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3222 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3223 (clobber (reg:CC 17))
3224 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3225 "!TARGET_64BIT"
3226 "#")
3227
3228 (define_insn "extendsidi2_rex64"
3229 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3230 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3231 "TARGET_64BIT"
3232 "@
3233 {cltq|cdqe}
3234 movs{lq|x}\t{%1,%0|%0, %1}"
3235 [(set_attr "type" "imovx")
3236 (set_attr "mode" "DI")
3237 (set_attr "prefix_0f" "0")
3238 (set_attr "modrm" "0,1")])
3239
3240 (define_insn "extendhidi2"
3241 [(set (match_operand:DI 0 "register_operand" "=r")
3242 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "TARGET_64BIT"
3244 "movs{wq|x}\t{%1,%0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "DI")])
3247
3248 (define_insn "extendqidi2"
3249 [(set (match_operand:DI 0 "register_operand" "=r")
3250 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3251 "TARGET_64BIT"
3252 "movs{bq|x}\t{%1,%0|%0, %1}"
3253 [(set_attr "type" "imovx")
3254 (set_attr "mode" "DI")])
3255
3256 ;; Extend to memory case when source register does die.
3257 (define_split
3258 [(set (match_operand:DI 0 "memory_operand" "")
3259 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3260 (clobber (reg:CC 17))
3261 (clobber (match_operand:SI 2 "register_operand" ""))]
3262 "(reload_completed
3263 && dead_or_set_p (insn, operands[1])
3264 && !reg_mentioned_p (operands[1], operands[0]))"
3265 [(set (match_dup 3) (match_dup 1))
3266 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3267 (clobber (reg:CC 17))])
3268 (set (match_dup 4) (match_dup 1))]
3269 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3270
3271 ;; Extend to memory case when source register does not die.
3272 (define_split
3273 [(set (match_operand:DI 0 "memory_operand" "")
3274 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3275 (clobber (reg:CC 17))
3276 (clobber (match_operand:SI 2 "register_operand" ""))]
3277 "reload_completed"
3278 [(const_int 0)]
3279 {
3280 split_di (&operands[0], 1, &operands[3], &operands[4]);
3281
3282 emit_move_insn (operands[3], operands[1]);
3283
3284 /* Generate a cltd if possible and doing so it profitable. */
3285 if (true_regnum (operands[1]) == 0
3286 && true_regnum (operands[2]) == 1
3287 && (optimize_size || TARGET_USE_CLTD))
3288 {
3289 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3290 }
3291 else
3292 {
3293 emit_move_insn (operands[2], operands[1]);
3294 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3295 }
3296 emit_move_insn (operands[4], operands[2]);
3297 DONE;
3298 })
3299
3300 ;; Extend to register case. Optimize case where source and destination
3301 ;; registers match and cases where we can use cltd.
3302 (define_split
3303 [(set (match_operand:DI 0 "register_operand" "")
3304 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305 (clobber (reg:CC 17))
3306 (clobber (match_scratch:SI 2 ""))]
3307 "reload_completed"
3308 [(const_int 0)]
3309 {
3310 split_di (&operands[0], 1, &operands[3], &operands[4]);
3311
3312 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3313 emit_move_insn (operands[3], operands[1]);
3314
3315 /* Generate a cltd if possible and doing so it profitable. */
3316 if (true_regnum (operands[3]) == 0
3317 && (optimize_size || TARGET_USE_CLTD))
3318 {
3319 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3320 DONE;
3321 }
3322
3323 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3324 emit_move_insn (operands[4], operands[1]);
3325
3326 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3327 DONE;
3328 })
3329
3330 (define_insn "extendhisi2"
3331 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3332 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3333 ""
3334 {
3335 switch (get_attr_prefix_0f (insn))
3336 {
3337 case 0:
3338 return "{cwtl|cwde}";
3339 default:
3340 return "movs{wl|x}\t{%1,%0|%0, %1}";
3341 }
3342 }
3343 [(set_attr "type" "imovx")
3344 (set_attr "mode" "SI")
3345 (set (attr "prefix_0f")
3346 ;; movsx is short decodable while cwtl is vector decoded.
3347 (if_then_else (and (eq_attr "cpu" "!k6")
3348 (eq_attr "alternative" "0"))
3349 (const_string "0")
3350 (const_string "1")))
3351 (set (attr "modrm")
3352 (if_then_else (eq_attr "prefix_0f" "0")
3353 (const_string "0")
3354 (const_string "1")))])
3355
3356 (define_insn "*extendhisi2_zext"
3357 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3358 (zero_extend:DI
3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3360 "TARGET_64BIT"
3361 {
3362 switch (get_attr_prefix_0f (insn))
3363 {
3364 case 0:
3365 return "{cwtl|cwde}";
3366 default:
3367 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3368 }
3369 }
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")
3372 (set (attr "prefix_0f")
3373 ;; movsx is short decodable while cwtl is vector decoded.
3374 (if_then_else (and (eq_attr "cpu" "!k6")
3375 (eq_attr "alternative" "0"))
3376 (const_string "0")
3377 (const_string "1")))
3378 (set (attr "modrm")
3379 (if_then_else (eq_attr "prefix_0f" "0")
3380 (const_string "0")
3381 (const_string "1")))])
3382
3383 (define_insn "extendqihi2"
3384 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3385 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3386 ""
3387 {
3388 switch (get_attr_prefix_0f (insn))
3389 {
3390 case 0:
3391 return "{cbtw|cbw}";
3392 default:
3393 return "movs{bw|x}\t{%1,%0|%0, %1}";
3394 }
3395 }
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "HI")
3398 (set (attr "prefix_0f")
3399 ;; movsx is short decodable while cwtl is vector decoded.
3400 (if_then_else (and (eq_attr "cpu" "!k6")
3401 (eq_attr "alternative" "0"))
3402 (const_string "0")
3403 (const_string "1")))
3404 (set (attr "modrm")
3405 (if_then_else (eq_attr "prefix_0f" "0")
3406 (const_string "0")
3407 (const_string "1")))])
3408
3409 (define_insn "extendqisi2"
3410 [(set (match_operand:SI 0 "register_operand" "=r")
3411 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3412 ""
3413 "movs{bl|x}\t{%1,%0|%0, %1}"
3414 [(set_attr "type" "imovx")
3415 (set_attr "mode" "SI")])
3416
3417 (define_insn "*extendqisi2_zext"
3418 [(set (match_operand:DI 0 "register_operand" "=r")
3419 (zero_extend:DI
3420 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3421 "TARGET_64BIT"
3422 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3423 [(set_attr "type" "imovx")
3424 (set_attr "mode" "SI")])
3425 \f
3426 ;; Conversions between float and double.
3427
3428 ;; These are all no-ops in the model used for the 80387. So just
3429 ;; emit moves.
3430
3431 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3432 (define_insn "*dummy_extendsfdf2"
3433 [(set (match_operand:DF 0 "push_operand" "=<")
3434 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3435 "0"
3436 "#")
3437
3438 (define_split
3439 [(set (match_operand:DF 0 "push_operand" "")
3440 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3441 "!TARGET_64BIT"
3442 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3443 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3444
3445 (define_split
3446 [(set (match_operand:DF 0 "push_operand" "")
3447 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448 "TARGET_64BIT"
3449 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3450 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3451
3452 (define_insn "*dummy_extendsfxf2"
3453 [(set (match_operand:XF 0 "push_operand" "=<")
3454 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3455 "0"
3456 "#")
3457
3458 (define_split
3459 [(set (match_operand:XF 0 "push_operand" "")
3460 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3461 ""
3462 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3463 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3464 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3465
3466 (define_split
3467 [(set (match_operand:XF 0 "push_operand" "")
3468 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3469 "TARGET_64BIT"
3470 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3471 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3472 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473
3474 (define_split
3475 [(set (match_operand:XF 0 "push_operand" "")
3476 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3477 ""
3478 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3479 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3480 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481
3482 (define_split
3483 [(set (match_operand:XF 0 "push_operand" "")
3484 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3485 "TARGET_64BIT"
3486 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3487 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3488 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489
3490 (define_expand "extendsfdf2"
3491 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3493 "TARGET_80387 || TARGET_SSE2"
3494 {
3495 /* ??? Needed for compress_float_constant since all fp constants
3496 are LEGITIMATE_CONSTANT_P. */
3497 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3498 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3499 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3500 operands[1] = force_reg (SFmode, operands[1]);
3501 })
3502
3503 (define_insn "*extendsfdf2_1"
3504 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3505 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3506 "(TARGET_80387 || TARGET_SSE2)
3507 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3508 {
3509 switch (which_alternative)
3510 {
3511 case 0:
3512 if (REG_P (operands[1])
3513 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3514 return "fstp\t%y0";
3515 else if (STACK_TOP_P (operands[0]))
3516 return "fld%z1\t%y1";
3517 else
3518 return "fst\t%y0";
3519
3520 case 1:
3521 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3522 return "fstp%z0\t%y0";
3523
3524 else
3525 return "fst%z0\t%y0";
3526 case 2:
3527 return "cvtss2sd\t{%1, %0|%0, %1}";
3528
3529 default:
3530 abort ();
3531 }
3532 }
3533 [(set_attr "type" "fmov,fmov,ssecvt")
3534 (set_attr "mode" "SF,XF,DF")])
3535
3536 (define_insn "*extendsfdf2_1_sse_only"
3537 [(set (match_operand:DF 0 "register_operand" "=Y")
3538 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3539 "!TARGET_80387 && TARGET_SSE2
3540 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3541 "cvtss2sd\t{%1, %0|%0, %1}"
3542 [(set_attr "type" "ssecvt")
3543 (set_attr "mode" "DF")])
3544
3545 (define_expand "extendsfxf2"
3546 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3547 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3548 "TARGET_80387"
3549 {
3550 /* ??? Needed for compress_float_constant since all fp constants
3551 are LEGITIMATE_CONSTANT_P. */
3552 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3553 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3554 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3555 operands[1] = force_reg (SFmode, operands[1]);
3556 })
3557
3558 (define_insn "*extendsfxf2_1"
3559 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3560 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3561 "TARGET_80387
3562 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3563 {
3564 switch (which_alternative)
3565 {
3566 case 0:
3567 if (REG_P (operands[1])
3568 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3569 return "fstp\t%y0";
3570 else if (STACK_TOP_P (operands[0]))
3571 return "fld%z1\t%y1";
3572 else
3573 return "fst\t%y0";
3574
3575 case 1:
3576 /* There is no non-popping store to memory for XFmode. So if
3577 we need one, follow the store with a load. */
3578 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3579 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3580 else
3581 return "fstp%z0\t%y0";
3582
3583 default:
3584 abort ();
3585 }
3586 }
3587 [(set_attr "type" "fmov")
3588 (set_attr "mode" "SF,XF")])
3589
3590 (define_expand "extenddfxf2"
3591 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3592 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3593 "TARGET_80387"
3594 {
3595 /* ??? Needed for compress_float_constant since all fp constants
3596 are LEGITIMATE_CONSTANT_P. */
3597 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3598 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3599 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3600 operands[1] = force_reg (DFmode, operands[1]);
3601 })
3602
3603 (define_insn "*extenddfxf2_1"
3604 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3605 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3606 "TARGET_80387
3607 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608 {
3609 switch (which_alternative)
3610 {
3611 case 0:
3612 if (REG_P (operands[1])
3613 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614 return "fstp\t%y0";
3615 else if (STACK_TOP_P (operands[0]))
3616 return "fld%z1\t%y1";
3617 else
3618 return "fst\t%y0";
3619
3620 case 1:
3621 /* There is no non-popping store to memory for XFmode. So if
3622 we need one, follow the store with a load. */
3623 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3624 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3625 else
3626 return "fstp%z0\t%y0";
3627
3628 default:
3629 abort ();
3630 }
3631 }
3632 [(set_attr "type" "fmov")
3633 (set_attr "mode" "DF,XF")])
3634
3635 ;; %%% This seems bad bad news.
3636 ;; This cannot output into an f-reg because there is no way to be sure
3637 ;; of truncating in that case. Otherwise this is just like a simple move
3638 ;; insn. So we pretend we can output to a reg in order to get better
3639 ;; register preferencing, but we really use a stack slot.
3640
3641 (define_expand "truncdfsf2"
3642 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3643 (float_truncate:SF
3644 (match_operand:DF 1 "register_operand" "")))
3645 (clobber (match_dup 2))])]
3646 "TARGET_80387 || TARGET_SSE2"
3647 "
3648 if (TARGET_80387)
3649 operands[2] = assign_386_stack_local (SFmode, 0);
3650 else
3651 {
3652 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3653 DONE;
3654 }
3655 ")
3656
3657 (define_insn "*truncdfsf2_1"
3658 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3659 (float_truncate:SF
3660 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3661 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3662 "TARGET_80387 && !TARGET_SSE2"
3663 {
3664 switch (which_alternative)
3665 {
3666 case 0:
3667 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668 return "fstp%z0\t%y0";
3669 else
3670 return "fst%z0\t%y0";
3671 default:
3672 abort ();
3673 }
3674 }
3675 [(set_attr "type" "fmov,multi,multi,multi")
3676 (set_attr "mode" "SF,SF,SF,SF")])
3677
3678 (define_insn "*truncdfsf2_1_sse"
3679 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3680 (float_truncate:SF
3681 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3682 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3683 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3684 {
3685 switch (which_alternative)
3686 {
3687 case 0:
3688 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689 return "fstp%z0\t%y0";
3690 else
3691 return "fst%z0\t%y0";
3692 case 4:
3693 return "#";
3694 default:
3695 abort ();
3696 }
3697 }
3698 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3699 (set_attr "mode" "SF,SF,SF,SF,DF")])
3700
3701 (define_insn "*truncdfsf2_1_sse_nooverlap"
3702 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3703 (float_truncate:SF
3704 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3705 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3706 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3707 {
3708 switch (which_alternative)
3709 {
3710 case 0:
3711 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0";
3713 else
3714 return "fst%z0\t%y0";
3715 case 4:
3716 return "#";
3717 default:
3718 abort ();
3719 }
3720 }
3721 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3722 (set_attr "mode" "SF,SF,SF,SF,DF")])
3723
3724 (define_insn "*truncdfsf2_2"
3725 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3726 (float_truncate:SF
3727 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3728 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3730 {
3731 switch (which_alternative)
3732 {
3733 case 0:
3734 case 1:
3735 return "cvtsd2ss\t{%1, %0|%0, %1}";
3736 case 2:
3737 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738 return "fstp%z0\t%y0";
3739 else
3740 return "fst%z0\t%y0";
3741 default:
3742 abort ();
3743 }
3744 }
3745 [(set_attr "type" "ssecvt,ssecvt,fmov")
3746 (set_attr "athlon_decode" "vector,double,*")
3747 (set_attr "mode" "SF,SF,SF")])
3748
3749 (define_insn "*truncdfsf2_2_nooverlap"
3750 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3751 (float_truncate:SF
3752 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3753 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3754 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3755 {
3756 switch (which_alternative)
3757 {
3758 case 0:
3759 return "#";
3760 case 1:
3761 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3762 return "fstp%z0\t%y0";
3763 else
3764 return "fst%z0\t%y0";
3765 default:
3766 abort ();
3767 }
3768 }
3769 [(set_attr "type" "ssecvt,fmov")
3770 (set_attr "mode" "DF,SF")])
3771
3772 (define_insn "*truncdfsf2_3"
3773 [(set (match_operand:SF 0 "memory_operand" "=m")
3774 (float_truncate:SF
3775 (match_operand:DF 1 "register_operand" "f")))]
3776 "TARGET_80387"
3777 {
3778 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779 return "fstp%z0\t%y0";
3780 else
3781 return "fst%z0\t%y0";
3782 }
3783 [(set_attr "type" "fmov")
3784 (set_attr "mode" "SF")])
3785
3786 (define_insn "truncdfsf2_sse_only"
3787 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3788 (float_truncate:SF
3789 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3790 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3791 "cvtsd2ss\t{%1, %0|%0, %1}"
3792 [(set_attr "type" "ssecvt")
3793 (set_attr "athlon_decode" "vector,double")
3794 (set_attr "mode" "SF")])
3795
3796 (define_insn "*truncdfsf2_sse_only_nooverlap"
3797 [(set (match_operand:SF 0 "register_operand" "=&Y")
3798 (float_truncate:SF
3799 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3800 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3801 "#"
3802 [(set_attr "type" "ssecvt")
3803 (set_attr "mode" "DF")])
3804
3805 (define_split
3806 [(set (match_operand:SF 0 "memory_operand" "")
3807 (float_truncate:SF
3808 (match_operand:DF 1 "register_operand" "")))
3809 (clobber (match_operand:SF 2 "memory_operand" ""))]
3810 "TARGET_80387"
3811 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3812 "")
3813
3814 ; Avoid possible reformatting penalty on the destination by first
3815 ; zeroing it out
3816 (define_split
3817 [(set (match_operand:SF 0 "register_operand" "")
3818 (float_truncate:SF
3819 (match_operand:DF 1 "nonimmediate_operand" "")))
3820 (clobber (match_operand 2 "" ""))]
3821 "TARGET_80387 && reload_completed
3822 && SSE_REG_P (operands[0])
3823 && !STACK_REG_P (operands[1])"
3824 [(const_int 0)]
3825 {
3826 rtx src, dest;
3827 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3828 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3829 else
3830 {
3831 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3832 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3833 /* simplify_gen_subreg refuses to widen memory references. */
3834 if (GET_CODE (src) == SUBREG)
3835 alter_subreg (&src);
3836 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3837 abort ();
3838 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3839 emit_insn (gen_cvtsd2ss (dest, dest, src));
3840 }
3841 DONE;
3842 })
3843
3844 (define_split
3845 [(set (match_operand:SF 0 "register_operand" "")
3846 (float_truncate:SF
3847 (match_operand:DF 1 "nonimmediate_operand" "")))]
3848 "TARGET_80387 && reload_completed
3849 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3850 [(const_int 0)]
3851 {
3852 rtx src, dest;
3853 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3854 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3855 /* simplify_gen_subreg refuses to widen memory references. */
3856 if (GET_CODE (src) == SUBREG)
3857 alter_subreg (&src);
3858 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3859 abort ();
3860 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3861 emit_insn (gen_cvtsd2ss (dest, dest, src));
3862 DONE;
3863 })
3864
3865 (define_split
3866 [(set (match_operand:SF 0 "register_operand" "")
3867 (float_truncate:SF
3868 (match_operand:DF 1 "fp_register_operand" "")))
3869 (clobber (match_operand:SF 2 "memory_operand" ""))]
3870 "TARGET_80387 && reload_completed"
3871 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3872 (set (match_dup 0) (match_dup 2))]
3873 "")
3874
3875 (define_expand "truncxfsf2"
3876 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3877 (float_truncate:SF
3878 (match_operand:XF 1 "register_operand" "")))
3879 (clobber (match_dup 2))])]
3880 "TARGET_80387"
3881 "operands[2] = assign_386_stack_local (SFmode, 0);")
3882
3883 (define_insn "*truncxfsf2_1"
3884 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3885 (float_truncate:SF
3886 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3887 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3888 "TARGET_80387"
3889 {
3890 switch (which_alternative)
3891 {
3892 case 0:
3893 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3894 return "fstp%z0\t%y0";
3895 else
3896 return "fst%z0\t%y0";
3897 default:
3898 abort();
3899 }
3900 }
3901 [(set_attr "type" "fmov,multi,multi,multi")
3902 (set_attr "mode" "SF")])
3903
3904 (define_insn "*truncxfsf2_2"
3905 [(set (match_operand:SF 0 "memory_operand" "=m")
3906 (float_truncate:SF
3907 (match_operand:XF 1 "register_operand" "f")))]
3908 "TARGET_80387"
3909 {
3910 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3911 return "fstp%z0\t%y0";
3912 else
3913 return "fst%z0\t%y0";
3914 }
3915 [(set_attr "type" "fmov")
3916 (set_attr "mode" "SF")])
3917
3918 (define_split
3919 [(set (match_operand:SF 0 "memory_operand" "")
3920 (float_truncate:SF
3921 (match_operand:XF 1 "register_operand" "")))
3922 (clobber (match_operand:SF 2 "memory_operand" ""))]
3923 "TARGET_80387"
3924 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3925 "")
3926
3927 (define_split
3928 [(set (match_operand:SF 0 "register_operand" "")
3929 (float_truncate:SF
3930 (match_operand:XF 1 "register_operand" "")))
3931 (clobber (match_operand:SF 2 "memory_operand" ""))]
3932 "TARGET_80387 && reload_completed"
3933 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3934 (set (match_dup 0) (match_dup 2))]
3935 "")
3936
3937 (define_expand "truncxfdf2"
3938 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3939 (float_truncate:DF
3940 (match_operand:XF 1 "register_operand" "")))
3941 (clobber (match_dup 2))])]
3942 "TARGET_80387"
3943 "operands[2] = assign_386_stack_local (DFmode, 0);")
3944
3945 (define_insn "*truncxfdf2_1"
3946 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3947 (float_truncate:DF
3948 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3949 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3950 "TARGET_80387"
3951 {
3952 switch (which_alternative)
3953 {
3954 case 0:
3955 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956 return "fstp%z0\t%y0";
3957 else
3958 return "fst%z0\t%y0";
3959 default:
3960 abort();
3961 }
3962 abort ();
3963 }
3964 [(set_attr "type" "fmov,multi,multi,multi")
3965 (set_attr "mode" "DF")])
3966
3967 (define_insn "*truncxfdf2_2"
3968 [(set (match_operand:DF 0 "memory_operand" "=m")
3969 (float_truncate:DF
3970 (match_operand:XF 1 "register_operand" "f")))]
3971 "TARGET_80387"
3972 {
3973 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974 return "fstp%z0\t%y0";
3975 else
3976 return "fst%z0\t%y0";
3977 }
3978 [(set_attr "type" "fmov")
3979 (set_attr "mode" "DF")])
3980
3981 (define_split
3982 [(set (match_operand:DF 0 "memory_operand" "")
3983 (float_truncate:DF
3984 (match_operand:XF 1 "register_operand" "")))
3985 (clobber (match_operand:DF 2 "memory_operand" ""))]
3986 "TARGET_80387"
3987 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3988 "")
3989
3990 (define_split
3991 [(set (match_operand:DF 0 "register_operand" "")
3992 (float_truncate:DF
3993 (match_operand:XF 1 "register_operand" "")))
3994 (clobber (match_operand:DF 2 "memory_operand" ""))]
3995 "TARGET_80387 && reload_completed"
3996 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3997 (set (match_dup 0) (match_dup 2))]
3998 "")
3999
4000 \f
4001 ;; %%% Break up all these bad boys.
4002
4003 ;; Signed conversion to DImode.
4004
4005 (define_expand "fix_truncxfdi2"
4006 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4007 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4008 "TARGET_80387"
4009 "")
4010
4011 (define_expand "fix_truncdfdi2"
4012 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4013 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4014 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4015 {
4016 if (TARGET_64BIT && TARGET_SSE2)
4017 {
4018 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4019 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4020 if (out != operands[0])
4021 emit_move_insn (operands[0], out);
4022 DONE;
4023 }
4024 })
4025
4026 (define_expand "fix_truncsfdi2"
4027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4029 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4030 {
4031 if (TARGET_SSE && TARGET_64BIT)
4032 {
4033 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4034 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4035 if (out != operands[0])
4036 emit_move_insn (operands[0], out);
4037 DONE;
4038 }
4039 })
4040
4041 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4042 ;; of the machinery.
4043 (define_insn_and_split "*fix_truncdi_1"
4044 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4045 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4046 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4047 && !reload_completed && !reload_in_progress
4048 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4049 "#"
4050 "&& 1"
4051 [(const_int 0)]
4052 {
4053 ix86_optimize_mode_switching = 1;
4054 operands[2] = assign_386_stack_local (HImode, 1);
4055 operands[3] = assign_386_stack_local (HImode, 2);
4056 if (memory_operand (operands[0], VOIDmode))
4057 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4058 operands[2], operands[3]));
4059 else
4060 {
4061 operands[4] = assign_386_stack_local (DImode, 0);
4062 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4063 operands[2], operands[3],
4064 operands[4]));
4065 }
4066 DONE;
4067 }
4068 [(set_attr "type" "fistp")
4069 (set_attr "mode" "DI")])
4070
4071 (define_insn "fix_truncdi_nomemory"
4072 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4073 (fix:DI (match_operand 1 "register_operand" "f,f")))
4074 (use (match_operand:HI 2 "memory_operand" "m,m"))
4075 (use (match_operand:HI 3 "memory_operand" "m,m"))
4076 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4077 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4078 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4079 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4080 "#"
4081 [(set_attr "type" "fistp")
4082 (set_attr "mode" "DI")])
4083
4084 (define_insn "fix_truncdi_memory"
4085 [(set (match_operand:DI 0 "memory_operand" "=m")
4086 (fix:DI (match_operand 1 "register_operand" "f")))
4087 (use (match_operand:HI 2 "memory_operand" "m"))
4088 (use (match_operand:HI 3 "memory_operand" "m"))
4089 (clobber (match_scratch:DF 4 "=&1f"))]
4090 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4091 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4092 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4093 [(set_attr "type" "fistp")
4094 (set_attr "mode" "DI")])
4095
4096 (define_split
4097 [(set (match_operand:DI 0 "register_operand" "")
4098 (fix:DI (match_operand 1 "register_operand" "")))
4099 (use (match_operand:HI 2 "memory_operand" ""))
4100 (use (match_operand:HI 3 "memory_operand" ""))
4101 (clobber (match_operand:DI 4 "memory_operand" ""))
4102 (clobber (match_scratch 5 ""))]
4103 "reload_completed"
4104 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4105 (use (match_dup 2))
4106 (use (match_dup 3))
4107 (clobber (match_dup 5))])
4108 (set (match_dup 0) (match_dup 4))]
4109 "")
4110
4111 (define_split
4112 [(set (match_operand:DI 0 "memory_operand" "")
4113 (fix:DI (match_operand 1 "register_operand" "")))
4114 (use (match_operand:HI 2 "memory_operand" ""))
4115 (use (match_operand:HI 3 "memory_operand" ""))
4116 (clobber (match_operand:DI 4 "memory_operand" ""))
4117 (clobber (match_scratch 5 ""))]
4118 "reload_completed"
4119 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4120 (use (match_dup 2))
4121 (use (match_dup 3))
4122 (clobber (match_dup 5))])]
4123 "")
4124
4125 ;; When SSE available, it is always faster to use it!
4126 (define_insn "fix_truncsfdi_sse"
4127 [(set (match_operand:DI 0 "register_operand" "=r,r")
4128 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4129 "TARGET_64BIT && TARGET_SSE"
4130 "cvttss2si{q}\t{%1, %0|%0, %1}"
4131 [(set_attr "type" "sseicvt")
4132 (set_attr "mode" "SF")
4133 (set_attr "athlon_decode" "double,vector")])
4134
4135 ;; Avoid vector decoded form of the instruction.
4136 (define_peephole2
4137 [(match_scratch:SF 2 "x")
4138 (set (match_operand:DI 0 "register_operand" "")
4139 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4140 "TARGET_K8 && !optimize_size"
4141 [(set (match_dup 2) (match_dup 1))
4142 (set (match_dup 0) (fix:DI (match_dup 2)))]
4143 "")
4144
4145 (define_insn "fix_truncdfdi_sse"
4146 [(set (match_operand:DI 0 "register_operand" "=r,r")
4147 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4148 "TARGET_64BIT && TARGET_SSE2"
4149 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4150 [(set_attr "type" "sseicvt,sseicvt")
4151 (set_attr "mode" "DF")
4152 (set_attr "athlon_decode" "double,vector")])
4153
4154 ;; Avoid vector decoded form of the instruction.
4155 (define_peephole2
4156 [(match_scratch:DF 2 "Y")
4157 (set (match_operand:DI 0 "register_operand" "")
4158 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4159 "TARGET_K8 && !optimize_size"
4160 [(set (match_dup 2) (match_dup 1))
4161 (set (match_dup 0) (fix:DI (match_dup 2)))]
4162 "")
4163
4164 ;; Signed conversion to SImode.
4165
4166 (define_expand "fix_truncxfsi2"
4167 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4168 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4169 "TARGET_80387"
4170 "")
4171
4172 (define_expand "fix_truncdfsi2"
4173 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4174 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4175 "TARGET_80387 || TARGET_SSE2"
4176 {
4177 if (TARGET_SSE2)
4178 {
4179 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4180 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4181 if (out != operands[0])
4182 emit_move_insn (operands[0], out);
4183 DONE;
4184 }
4185 })
4186
4187 (define_expand "fix_truncsfsi2"
4188 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4189 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4190 "TARGET_80387 || TARGET_SSE"
4191 {
4192 if (TARGET_SSE)
4193 {
4194 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4195 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4196 if (out != operands[0])
4197 emit_move_insn (operands[0], out);
4198 DONE;
4199 }
4200 })
4201
4202 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4203 ;; of the machinery.
4204 (define_insn_and_split "*fix_truncsi_1"
4205 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4206 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4207 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4208 && !reload_completed && !reload_in_progress
4209 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4210 "#"
4211 "&& 1"
4212 [(const_int 0)]
4213 {
4214 ix86_optimize_mode_switching = 1;
4215 operands[2] = assign_386_stack_local (HImode, 1);
4216 operands[3] = assign_386_stack_local (HImode, 2);
4217 if (memory_operand (operands[0], VOIDmode))
4218 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4219 operands[2], operands[3]));
4220 else
4221 {
4222 operands[4] = assign_386_stack_local (SImode, 0);
4223 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4224 operands[2], operands[3],
4225 operands[4]));
4226 }
4227 DONE;
4228 }
4229 [(set_attr "type" "fistp")
4230 (set_attr "mode" "SI")])
4231
4232 (define_insn "fix_truncsi_nomemory"
4233 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4234 (fix:SI (match_operand 1 "register_operand" "f,f")))
4235 (use (match_operand:HI 2 "memory_operand" "m,m"))
4236 (use (match_operand:HI 3 "memory_operand" "m,m"))
4237 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4238 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4239 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4240 "#"
4241 [(set_attr "type" "fistp")
4242 (set_attr "mode" "SI")])
4243
4244 (define_insn "fix_truncsi_memory"
4245 [(set (match_operand:SI 0 "memory_operand" "=m")
4246 (fix:SI (match_operand 1 "register_operand" "f")))
4247 (use (match_operand:HI 2 "memory_operand" "m"))
4248 (use (match_operand:HI 3 "memory_operand" "m"))]
4249 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4250 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4251 "* return output_fix_trunc (insn, operands);"
4252 [(set_attr "type" "fistp")
4253 (set_attr "mode" "SI")])
4254
4255 ;; When SSE available, it is always faster to use it!
4256 (define_insn "fix_truncsfsi_sse"
4257 [(set (match_operand:SI 0 "register_operand" "=r,r")
4258 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4259 "TARGET_SSE"
4260 "cvttss2si\t{%1, %0|%0, %1}"
4261 [(set_attr "type" "sseicvt")
4262 (set_attr "mode" "DF")
4263 (set_attr "athlon_decode" "double,vector")])
4264
4265 ;; Avoid vector decoded form of the instruction.
4266 (define_peephole2
4267 [(match_scratch:SF 2 "x")
4268 (set (match_operand:SI 0 "register_operand" "")
4269 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4270 "TARGET_K8 && !optimize_size"
4271 [(set (match_dup 2) (match_dup 1))
4272 (set (match_dup 0) (fix:SI (match_dup 2)))]
4273 "")
4274
4275 (define_insn "fix_truncdfsi_sse"
4276 [(set (match_operand:SI 0 "register_operand" "=r,r")
4277 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4278 "TARGET_SSE2"
4279 "cvttsd2si\t{%1, %0|%0, %1}"
4280 [(set_attr "type" "sseicvt")
4281 (set_attr "mode" "DF")
4282 (set_attr "athlon_decode" "double,vector")])
4283
4284 ;; Avoid vector decoded form of the instruction.
4285 (define_peephole2
4286 [(match_scratch:DF 2 "Y")
4287 (set (match_operand:SI 0 "register_operand" "")
4288 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4289 "TARGET_K8 && !optimize_size"
4290 [(set (match_dup 2) (match_dup 1))
4291 (set (match_dup 0) (fix:SI (match_dup 2)))]
4292 "")
4293
4294 (define_split
4295 [(set (match_operand:SI 0 "register_operand" "")
4296 (fix:SI (match_operand 1 "register_operand" "")))
4297 (use (match_operand:HI 2 "memory_operand" ""))
4298 (use (match_operand:HI 3 "memory_operand" ""))
4299 (clobber (match_operand:SI 4 "memory_operand" ""))]
4300 "reload_completed"
4301 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4302 (use (match_dup 2))
4303 (use (match_dup 3))])
4304 (set (match_dup 0) (match_dup 4))]
4305 "")
4306
4307 (define_split
4308 [(set (match_operand:SI 0 "memory_operand" "")
4309 (fix:SI (match_operand 1 "register_operand" "")))
4310 (use (match_operand:HI 2 "memory_operand" ""))
4311 (use (match_operand:HI 3 "memory_operand" ""))
4312 (clobber (match_operand:SI 4 "memory_operand" ""))]
4313 "reload_completed"
4314 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4315 (use (match_dup 2))
4316 (use (match_dup 3))])]
4317 "")
4318
4319 ;; Signed conversion to HImode.
4320
4321 (define_expand "fix_truncxfhi2"
4322 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4323 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4324 "TARGET_80387"
4325 "")
4326
4327 (define_expand "fix_truncdfhi2"
4328 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4329 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4330 "TARGET_80387 && !TARGET_SSE2"
4331 "")
4332
4333 (define_expand "fix_truncsfhi2"
4334 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4335 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4336 "TARGET_80387 && !TARGET_SSE"
4337 "")
4338
4339 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4340 ;; of the machinery.
4341 (define_insn_and_split "*fix_trunchi_1"
4342 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4343 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4344 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4345 && !reload_completed && !reload_in_progress
4346 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4347 "#"
4348 ""
4349 [(const_int 0)]
4350 {
4351 ix86_optimize_mode_switching = 1;
4352 operands[2] = assign_386_stack_local (HImode, 1);
4353 operands[3] = assign_386_stack_local (HImode, 2);
4354 if (memory_operand (operands[0], VOIDmode))
4355 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4356 operands[2], operands[3]));
4357 else
4358 {
4359 operands[4] = assign_386_stack_local (HImode, 0);
4360 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4361 operands[2], operands[3],
4362 operands[4]));
4363 }
4364 DONE;
4365 }
4366 [(set_attr "type" "fistp")
4367 (set_attr "mode" "HI")])
4368
4369 (define_insn "fix_trunchi_nomemory"
4370 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4371 (fix:HI (match_operand 1 "register_operand" "f,f")))
4372 (use (match_operand:HI 2 "memory_operand" "m,m"))
4373 (use (match_operand:HI 3 "memory_operand" "m,m"))
4374 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4375 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4376 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4377 "#"
4378 [(set_attr "type" "fistp")
4379 (set_attr "mode" "HI")])
4380
4381 (define_insn "fix_trunchi_memory"
4382 [(set (match_operand:HI 0 "memory_operand" "=m")
4383 (fix:HI (match_operand 1 "register_operand" "f")))
4384 (use (match_operand:HI 2 "memory_operand" "m"))
4385 (use (match_operand:HI 3 "memory_operand" "m"))]
4386 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388 "* return output_fix_trunc (insn, operands);"
4389 [(set_attr "type" "fistp")
4390 (set_attr "mode" "HI")])
4391
4392 (define_split
4393 [(set (match_operand:HI 0 "memory_operand" "")
4394 (fix:HI (match_operand 1 "register_operand" "")))
4395 (use (match_operand:HI 2 "memory_operand" ""))
4396 (use (match_operand:HI 3 "memory_operand" ""))
4397 (clobber (match_operand:HI 4 "memory_operand" ""))]
4398 "reload_completed"
4399 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4400 (use (match_dup 2))
4401 (use (match_dup 3))])]
4402 "")
4403
4404 (define_split
4405 [(set (match_operand:HI 0 "register_operand" "")
4406 (fix:HI (match_operand 1 "register_operand" "")))
4407 (use (match_operand:HI 2 "memory_operand" ""))
4408 (use (match_operand:HI 3 "memory_operand" ""))
4409 (clobber (match_operand:HI 4 "memory_operand" ""))]
4410 "reload_completed"
4411 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4412 (use (match_dup 2))
4413 (use (match_dup 3))
4414 (clobber (match_dup 4))])
4415 (set (match_dup 0) (match_dup 4))]
4416 "")
4417
4418 ;; %% Not used yet.
4419 (define_insn "x86_fnstcw_1"
4420 [(set (match_operand:HI 0 "memory_operand" "=m")
4421 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4422 "TARGET_80387"
4423 "fnstcw\t%0"
4424 [(set_attr "length" "2")
4425 (set_attr "mode" "HI")
4426 (set_attr "unit" "i387")
4427 (set_attr "ppro_uops" "few")])
4428
4429 (define_insn "x86_fldcw_1"
4430 [(set (reg:HI 18)
4431 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4432 "TARGET_80387"
4433 "fldcw\t%0"
4434 [(set_attr "length" "2")
4435 (set_attr "mode" "HI")
4436 (set_attr "unit" "i387")
4437 (set_attr "athlon_decode" "vector")
4438 (set_attr "ppro_uops" "few")])
4439 \f
4440 ;; Conversion between fixed point and floating point.
4441
4442 ;; Even though we only accept memory inputs, the backend _really_
4443 ;; wants to be able to do this between registers.
4444
4445 (define_expand "floathisf2"
4446 [(set (match_operand:SF 0 "register_operand" "")
4447 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4448 "TARGET_SSE || TARGET_80387"
4449 {
4450 if (TARGET_SSE && TARGET_SSE_MATH)
4451 {
4452 emit_insn (gen_floatsisf2 (operands[0],
4453 convert_to_mode (SImode, operands[1], 0)));
4454 DONE;
4455 }
4456 })
4457
4458 (define_insn "*floathisf2_1"
4459 [(set (match_operand:SF 0 "register_operand" "=f,f")
4460 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4461 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4462 "@
4463 fild%z1\t%1
4464 #"
4465 [(set_attr "type" "fmov,multi")
4466 (set_attr "mode" "SF")
4467 (set_attr "fp_int_src" "true")])
4468
4469 (define_expand "floatsisf2"
4470 [(set (match_operand:SF 0 "register_operand" "")
4471 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4472 "TARGET_SSE || TARGET_80387"
4473 "")
4474
4475 (define_insn "*floatsisf2_i387"
4476 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4477 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4478 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4479 "@
4480 fild%z1\t%1
4481 #
4482 cvtsi2ss\t{%1, %0|%0, %1}
4483 cvtsi2ss\t{%1, %0|%0, %1}"
4484 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4485 (set_attr "mode" "SF")
4486 (set_attr "athlon_decode" "*,*,vector,double")
4487 (set_attr "fp_int_src" "true")])
4488
4489 (define_insn "*floatsisf2_sse"
4490 [(set (match_operand:SF 0 "register_operand" "=x,x")
4491 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4492 "TARGET_SSE"
4493 "cvtsi2ss\t{%1, %0|%0, %1}"
4494 [(set_attr "type" "sseicvt")
4495 (set_attr "mode" "SF")
4496 (set_attr "athlon_decode" "vector,double")
4497 (set_attr "fp_int_src" "true")])
4498
4499 ; Avoid possible reformatting penalty on the destination by first
4500 ; zeroing it out
4501 (define_split
4502 [(set (match_operand:SF 0 "register_operand" "")
4503 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4504 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4505 && SSE_REG_P (operands[0])"
4506 [(const_int 0)]
4507 {
4508 rtx dest;
4509 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4510 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4511 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4512 DONE;
4513 })
4514
4515 (define_expand "floatdisf2"
4516 [(set (match_operand:SF 0 "register_operand" "")
4517 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4518 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4519 "")
4520
4521 (define_insn "*floatdisf2_i387_only"
4522 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4523 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4524 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4525 "@
4526 fild%z1\t%1
4527 #"
4528 [(set_attr "type" "fmov,multi")
4529 (set_attr "mode" "SF")
4530 (set_attr "fp_int_src" "true")])
4531
4532 (define_insn "*floatdisf2_i387"
4533 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4534 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4535 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4536 "@
4537 fild%z1\t%1
4538 #
4539 cvtsi2ss{q}\t{%1, %0|%0, %1}
4540 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4541 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4542 (set_attr "mode" "SF")
4543 (set_attr "athlon_decode" "*,*,vector,double")
4544 (set_attr "fp_int_src" "true")])
4545
4546 (define_insn "*floatdisf2_sse"
4547 [(set (match_operand:SF 0 "register_operand" "=x,x")
4548 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4549 "TARGET_64BIT && TARGET_SSE"
4550 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4551 [(set_attr "type" "sseicvt")
4552 (set_attr "mode" "SF")
4553 (set_attr "athlon_decode" "vector,double")
4554 (set_attr "fp_int_src" "true")])
4555
4556 ; Avoid possible reformatting penalty on the destination by first
4557 ; zeroing it out
4558 (define_split
4559 [(set (match_operand:SF 0 "register_operand" "")
4560 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4561 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4562 && SSE_REG_P (operands[0])"
4563 [(const_int 0)]
4564 {
4565 rtx dest;
4566 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4567 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4568 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4569 DONE;
4570 })
4571
4572 (define_expand "floathidf2"
4573 [(set (match_operand:DF 0 "register_operand" "")
4574 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4575 "TARGET_SSE2 || TARGET_80387"
4576 {
4577 if (TARGET_SSE && TARGET_SSE_MATH)
4578 {
4579 emit_insn (gen_floatsidf2 (operands[0],
4580 convert_to_mode (SImode, operands[1], 0)));
4581 DONE;
4582 }
4583 })
4584
4585 (define_insn "*floathidf2_1"
4586 [(set (match_operand:DF 0 "register_operand" "=f,f")
4587 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4588 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4589 "@
4590 fild%z1\t%1
4591 #"
4592 [(set_attr "type" "fmov,multi")
4593 (set_attr "mode" "DF")
4594 (set_attr "fp_int_src" "true")])
4595
4596 (define_expand "floatsidf2"
4597 [(set (match_operand:DF 0 "register_operand" "")
4598 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4599 "TARGET_80387 || TARGET_SSE2"
4600 "")
4601
4602 (define_insn "*floatsidf2_i387"
4603 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4604 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4605 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4606 "@
4607 fild%z1\t%1
4608 #
4609 cvtsi2sd\t{%1, %0|%0, %1}
4610 cvtsi2sd\t{%1, %0|%0, %1}"
4611 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4612 (set_attr "mode" "DF")
4613 (set_attr "athlon_decode" "*,*,double,direct")
4614 (set_attr "fp_int_src" "true")])
4615
4616 (define_insn "*floatsidf2_sse"
4617 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4618 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4619 "TARGET_SSE2"
4620 "cvtsi2sd\t{%1, %0|%0, %1}"
4621 [(set_attr "type" "sseicvt")
4622 (set_attr "mode" "DF")
4623 (set_attr "athlon_decode" "double,direct")
4624 (set_attr "fp_int_src" "true")])
4625
4626 (define_expand "floatdidf2"
4627 [(set (match_operand:DF 0 "register_operand" "")
4628 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4629 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4630 "")
4631
4632 (define_insn "*floatdidf2_i387_only"
4633 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4634 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4635 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4636 "@
4637 fild%z1\t%1
4638 #"
4639 [(set_attr "type" "fmov,multi")
4640 (set_attr "mode" "DF")
4641 (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "*floatdidf2_i387"
4644 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4645 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4646 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4647 "@
4648 fild%z1\t%1
4649 #
4650 cvtsi2sd{q}\t{%1, %0|%0, %1}
4651 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4652 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4653 (set_attr "mode" "DF")
4654 (set_attr "athlon_decode" "*,*,double,direct")
4655 (set_attr "fp_int_src" "true")])
4656
4657 (define_insn "*floatdidf2_sse"
4658 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4659 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4660 "TARGET_SSE2"
4661 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662 [(set_attr "type" "sseicvt")
4663 (set_attr "mode" "DF")
4664 (set_attr "athlon_decode" "double,direct")
4665 (set_attr "fp_int_src" "true")])
4666
4667 (define_insn "floathixf2"
4668 [(set (match_operand:XF 0 "register_operand" "=f,f")
4669 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4670 "TARGET_80387"
4671 "@
4672 fild%z1\t%1
4673 #"
4674 [(set_attr "type" "fmov,multi")
4675 (set_attr "mode" "XF")
4676 (set_attr "fp_int_src" "true")])
4677
4678 (define_insn "floatsixf2"
4679 [(set (match_operand:XF 0 "register_operand" "=f,f")
4680 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4681 "TARGET_80387"
4682 "@
4683 fild%z1\t%1
4684 #"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "XF")
4687 (set_attr "fp_int_src" "true")])
4688
4689 (define_insn "floatdixf2"
4690 [(set (match_operand:XF 0 "register_operand" "=f,f")
4691 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4692 "TARGET_80387"
4693 "@
4694 fild%z1\t%1
4695 #"
4696 [(set_attr "type" "fmov,multi")
4697 (set_attr "mode" "XF")
4698 (set_attr "fp_int_src" "true")])
4699
4700 ;; %%% Kill these when reload knows how to do it.
4701 (define_split
4702 [(set (match_operand 0 "fp_register_operand" "")
4703 (float (match_operand 1 "register_operand" "")))]
4704 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4705 [(const_int 0)]
4706 {
4707 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4708 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4709 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4710 ix86_free_from_memory (GET_MODE (operands[1]));
4711 DONE;
4712 })
4713
4714 (define_expand "floatunssisf2"
4715 [(use (match_operand:SF 0 "register_operand" ""))
4716 (use (match_operand:SI 1 "register_operand" ""))]
4717 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4718 "x86_emit_floatuns (operands); DONE;")
4719
4720 (define_expand "floatunsdisf2"
4721 [(use (match_operand:SF 0 "register_operand" ""))
4722 (use (match_operand:DI 1 "register_operand" ""))]
4723 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4724 "x86_emit_floatuns (operands); DONE;")
4725
4726 (define_expand "floatunsdidf2"
4727 [(use (match_operand:DF 0 "register_operand" ""))
4728 (use (match_operand:DI 1 "register_operand" ""))]
4729 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4730 "x86_emit_floatuns (operands); DONE;")
4731 \f
4732 ;; Add instructions
4733
4734 ;; %%% splits for addsidi3
4735 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4736 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4737 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4738
4739 (define_expand "adddi3"
4740 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4741 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4742 (match_operand:DI 2 "x86_64_general_operand" "")))
4743 (clobber (reg:CC 17))]
4744 ""
4745 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4746
4747 (define_insn "*adddi3_1"
4748 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4749 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4750 (match_operand:DI 2 "general_operand" "roiF,riF")))
4751 (clobber (reg:CC 17))]
4752 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4753 "#")
4754
4755 (define_split
4756 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4757 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4758 (match_operand:DI 2 "general_operand" "")))
4759 (clobber (reg:CC 17))]
4760 "!TARGET_64BIT && reload_completed"
4761 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4762 UNSPEC_ADD_CARRY))
4763 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4764 (parallel [(set (match_dup 3)
4765 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4766 (match_dup 4))
4767 (match_dup 5)))
4768 (clobber (reg:CC 17))])]
4769 "split_di (operands+0, 1, operands+0, operands+3);
4770 split_di (operands+1, 1, operands+1, operands+4);
4771 split_di (operands+2, 1, operands+2, operands+5);")
4772
4773 (define_insn "adddi3_carry_rex64"
4774 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4775 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4776 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4777 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4778 (clobber (reg:CC 17))]
4779 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4780 "adc{q}\t{%2, %0|%0, %2}"
4781 [(set_attr "type" "alu")
4782 (set_attr "pent_pair" "pu")
4783 (set_attr "mode" "DI")
4784 (set_attr "ppro_uops" "few")])
4785
4786 (define_insn "*adddi3_cc_rex64"
4787 [(set (reg:CC 17)
4788 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4789 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4790 UNSPEC_ADD_CARRY))
4791 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4792 (plus:DI (match_dup 1) (match_dup 2)))]
4793 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794 "add{q}\t{%2, %0|%0, %2}"
4795 [(set_attr "type" "alu")
4796 (set_attr "mode" "DI")])
4797
4798 (define_insn "addqi3_carry"
4799 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4800 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4801 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4802 (match_operand:QI 2 "general_operand" "qi,qm")))
4803 (clobber (reg:CC 17))]
4804 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4805 "adc{b}\t{%2, %0|%0, %2}"
4806 [(set_attr "type" "alu")
4807 (set_attr "pent_pair" "pu")
4808 (set_attr "mode" "QI")
4809 (set_attr "ppro_uops" "few")])
4810
4811 (define_insn "addhi3_carry"
4812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4813 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4814 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4815 (match_operand:HI 2 "general_operand" "ri,rm")))
4816 (clobber (reg:CC 17))]
4817 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4818 "adc{w}\t{%2, %0|%0, %2}"
4819 [(set_attr "type" "alu")
4820 (set_attr "pent_pair" "pu")
4821 (set_attr "mode" "HI")
4822 (set_attr "ppro_uops" "few")])
4823
4824 (define_insn "addsi3_carry"
4825 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4826 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4827 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4828 (match_operand:SI 2 "general_operand" "ri,rm")))
4829 (clobber (reg:CC 17))]
4830 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4831 "adc{l}\t{%2, %0|%0, %2}"
4832 [(set_attr "type" "alu")
4833 (set_attr "pent_pair" "pu")
4834 (set_attr "mode" "SI")
4835 (set_attr "ppro_uops" "few")])
4836
4837 (define_insn "*addsi3_carry_zext"
4838 [(set (match_operand:DI 0 "register_operand" "=r")
4839 (zero_extend:DI
4840 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4841 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4842 (match_operand:SI 2 "general_operand" "rim"))))
4843 (clobber (reg:CC 17))]
4844 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4845 "adc{l}\t{%2, %k0|%k0, %2}"
4846 [(set_attr "type" "alu")
4847 (set_attr "pent_pair" "pu")
4848 (set_attr "mode" "SI")
4849 (set_attr "ppro_uops" "few")])
4850
4851 (define_insn "*addsi3_cc"
4852 [(set (reg:CC 17)
4853 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4854 (match_operand:SI 2 "general_operand" "ri,rm")]
4855 UNSPEC_ADD_CARRY))
4856 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4857 (plus:SI (match_dup 1) (match_dup 2)))]
4858 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4859 "add{l}\t{%2, %0|%0, %2}"
4860 [(set_attr "type" "alu")
4861 (set_attr "mode" "SI")])
4862
4863 (define_insn "addqi3_cc"
4864 [(set (reg:CC 17)
4865 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4866 (match_operand:QI 2 "general_operand" "qi,qm")]
4867 UNSPEC_ADD_CARRY))
4868 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4869 (plus:QI (match_dup 1) (match_dup 2)))]
4870 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4871 "add{b}\t{%2, %0|%0, %2}"
4872 [(set_attr "type" "alu")
4873 (set_attr "mode" "QI")])
4874
4875 (define_expand "addsi3"
4876 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4877 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4878 (match_operand:SI 2 "general_operand" "")))
4879 (clobber (reg:CC 17))])]
4880 ""
4881 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4882
4883 (define_insn "*lea_1"
4884 [(set (match_operand:SI 0 "register_operand" "=r")
4885 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4886 "!TARGET_64BIT"
4887 "lea{l}\t{%a1, %0|%0, %a1}"
4888 [(set_attr "type" "lea")
4889 (set_attr "mode" "SI")])
4890
4891 (define_insn "*lea_1_rex64"
4892 [(set (match_operand:SI 0 "register_operand" "=r")
4893 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4894 "TARGET_64BIT"
4895 "lea{l}\t{%a1, %0|%0, %a1}"
4896 [(set_attr "type" "lea")
4897 (set_attr "mode" "SI")])
4898
4899 (define_insn "*lea_1_zext"
4900 [(set (match_operand:DI 0 "register_operand" "=r")
4901 (zero_extend:DI
4902 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4903 "TARGET_64BIT"
4904 "lea{l}\t{%a1, %k0|%k0, %a1}"
4905 [(set_attr "type" "lea")
4906 (set_attr "mode" "SI")])
4907
4908 (define_insn "*lea_2_rex64"
4909 [(set (match_operand:DI 0 "register_operand" "=r")
4910 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4911 "TARGET_64BIT"
4912 "lea{q}\t{%a1, %0|%0, %a1}"
4913 [(set_attr "type" "lea")
4914 (set_attr "mode" "DI")])
4915
4916 ;; The lea patterns for non-Pmodes needs to be matched by several
4917 ;; insns converted to real lea by splitters.
4918
4919 (define_insn_and_split "*lea_general_1"
4920 [(set (match_operand 0 "register_operand" "=r")
4921 (plus (plus (match_operand 1 "index_register_operand" "r")
4922 (match_operand 2 "register_operand" "r"))
4923 (match_operand 3 "immediate_operand" "i")))]
4924 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4925 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4926 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4927 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4928 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4929 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4930 || GET_MODE (operands[3]) == VOIDmode)"
4931 "#"
4932 "&& reload_completed"
4933 [(const_int 0)]
4934 {
4935 rtx pat;
4936 operands[0] = gen_lowpart (SImode, operands[0]);
4937 operands[1] = gen_lowpart (Pmode, operands[1]);
4938 operands[2] = gen_lowpart (Pmode, operands[2]);
4939 operands[3] = gen_lowpart (Pmode, operands[3]);
4940 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4941 operands[3]);
4942 if (Pmode != SImode)
4943 pat = gen_rtx_SUBREG (SImode, pat, 0);
4944 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4945 DONE;
4946 }
4947 [(set_attr "type" "lea")
4948 (set_attr "mode" "SI")])
4949
4950 (define_insn_and_split "*lea_general_1_zext"
4951 [(set (match_operand:DI 0 "register_operand" "=r")
4952 (zero_extend:DI
4953 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
4954 (match_operand:SI 2 "register_operand" "r"))
4955 (match_operand:SI 3 "immediate_operand" "i"))))]
4956 "TARGET_64BIT"
4957 "#"
4958 "&& reload_completed"
4959 [(set (match_dup 0)
4960 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4961 (match_dup 2))
4962 (match_dup 3)) 0)))]
4963 {
4964 operands[1] = gen_lowpart (Pmode, operands[1]);
4965 operands[2] = gen_lowpart (Pmode, operands[2]);
4966 operands[3] = gen_lowpart (Pmode, operands[3]);
4967 }
4968 [(set_attr "type" "lea")
4969 (set_attr "mode" "SI")])
4970
4971 (define_insn_and_split "*lea_general_2"
4972 [(set (match_operand 0 "register_operand" "=r")
4973 (plus (mult (match_operand 1 "index_register_operand" "r")
4974 (match_operand 2 "const248_operand" "i"))
4975 (match_operand 3 "nonmemory_operand" "ri")))]
4976 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4977 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4978 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4979 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4980 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4981 || GET_MODE (operands[3]) == VOIDmode)"
4982 "#"
4983 "&& reload_completed"
4984 [(const_int 0)]
4985 {
4986 rtx pat;
4987 operands[0] = gen_lowpart (SImode, operands[0]);
4988 operands[1] = gen_lowpart (Pmode, operands[1]);
4989 operands[3] = gen_lowpart (Pmode, operands[3]);
4990 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4991 operands[3]);
4992 if (Pmode != SImode)
4993 pat = gen_rtx_SUBREG (SImode, pat, 0);
4994 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4995 DONE;
4996 }
4997 [(set_attr "type" "lea")
4998 (set_attr "mode" "SI")])
4999
5000 (define_insn_and_split "*lea_general_2_zext"
5001 [(set (match_operand:DI 0 "register_operand" "=r")
5002 (zero_extend:DI
5003 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5004 (match_operand:SI 2 "const248_operand" "n"))
5005 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5006 "TARGET_64BIT"
5007 "#"
5008 "&& reload_completed"
5009 [(set (match_dup 0)
5010 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5011 (match_dup 2))
5012 (match_dup 3)) 0)))]
5013 {
5014 operands[1] = gen_lowpart (Pmode, operands[1]);
5015 operands[3] = gen_lowpart (Pmode, operands[3]);
5016 }
5017 [(set_attr "type" "lea")
5018 (set_attr "mode" "SI")])
5019
5020 (define_insn_and_split "*lea_general_3"
5021 [(set (match_operand 0 "register_operand" "=r")
5022 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5023 (match_operand 2 "const248_operand" "i"))
5024 (match_operand 3 "register_operand" "r"))
5025 (match_operand 4 "immediate_operand" "i")))]
5026 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5027 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5028 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5029 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5030 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5031 "#"
5032 "&& reload_completed"
5033 [(const_int 0)]
5034 {
5035 rtx pat;
5036 operands[0] = gen_lowpart (SImode, operands[0]);
5037 operands[1] = gen_lowpart (Pmode, operands[1]);
5038 operands[3] = gen_lowpart (Pmode, operands[3]);
5039 operands[4] = gen_lowpart (Pmode, operands[4]);
5040 pat = gen_rtx_PLUS (Pmode,
5041 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5042 operands[2]),
5043 operands[3]),
5044 operands[4]);
5045 if (Pmode != SImode)
5046 pat = gen_rtx_SUBREG (SImode, pat, 0);
5047 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5048 DONE;
5049 }
5050 [(set_attr "type" "lea")
5051 (set_attr "mode" "SI")])
5052
5053 (define_insn_and_split "*lea_general_3_zext"
5054 [(set (match_operand:DI 0 "register_operand" "=r")
5055 (zero_extend:DI
5056 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5057 (match_operand:SI 2 "const248_operand" "n"))
5058 (match_operand:SI 3 "register_operand" "r"))
5059 (match_operand:SI 4 "immediate_operand" "i"))))]
5060 "TARGET_64BIT"
5061 "#"
5062 "&& reload_completed"
5063 [(set (match_dup 0)
5064 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5065 (match_dup 2))
5066 (match_dup 3))
5067 (match_dup 4)) 0)))]
5068 {
5069 operands[1] = gen_lowpart (Pmode, operands[1]);
5070 operands[3] = gen_lowpart (Pmode, operands[3]);
5071 operands[4] = gen_lowpart (Pmode, operands[4]);
5072 }
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5075
5076 (define_insn "*adddi_1_rex64"
5077 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5078 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5079 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5080 (clobber (reg:CC 17))]
5081 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5082 {
5083 switch (get_attr_type (insn))
5084 {
5085 case TYPE_LEA:
5086 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5087 return "lea{q}\t{%a2, %0|%0, %a2}";
5088
5089 case TYPE_INCDEC:
5090 if (! rtx_equal_p (operands[0], operands[1]))
5091 abort ();
5092 if (operands[2] == const1_rtx)
5093 return "inc{q}\t%0";
5094 else if (operands[2] == constm1_rtx)
5095 return "dec{q}\t%0";
5096 else
5097 abort ();
5098
5099 default:
5100 if (! rtx_equal_p (operands[0], operands[1]))
5101 abort ();
5102
5103 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5104 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5105 if (GET_CODE (operands[2]) == CONST_INT
5106 /* Avoid overflows. */
5107 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5108 && (INTVAL (operands[2]) == 128
5109 || (INTVAL (operands[2]) < 0
5110 && INTVAL (operands[2]) != -128)))
5111 {
5112 operands[2] = GEN_INT (-INTVAL (operands[2]));
5113 return "sub{q}\t{%2, %0|%0, %2}";
5114 }
5115 return "add{q}\t{%2, %0|%0, %2}";
5116 }
5117 }
5118 [(set (attr "type")
5119 (cond [(eq_attr "alternative" "2")
5120 (const_string "lea")
5121 ; Current assemblers are broken and do not allow @GOTOFF in
5122 ; ought but a memory context.
5123 (match_operand:DI 2 "pic_symbolic_operand" "")
5124 (const_string "lea")
5125 (match_operand:DI 2 "incdec_operand" "")
5126 (const_string "incdec")
5127 ]
5128 (const_string "alu")))
5129 (set_attr "mode" "DI")])
5130
5131 ;; Convert lea to the lea pattern to avoid flags dependency.
5132 (define_split
5133 [(set (match_operand:DI 0 "register_operand" "")
5134 (plus:DI (match_operand:DI 1 "register_operand" "")
5135 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5136 (clobber (reg:CC 17))]
5137 "TARGET_64BIT && reload_completed
5138 && true_regnum (operands[0]) != true_regnum (operands[1])"
5139 [(set (match_dup 0)
5140 (plus:DI (match_dup 1)
5141 (match_dup 2)))]
5142 "")
5143
5144 (define_insn "*adddi_2_rex64"
5145 [(set (reg 17)
5146 (compare
5147 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5148 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5149 (const_int 0)))
5150 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5151 (plus:DI (match_dup 1) (match_dup 2)))]
5152 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5153 && ix86_binary_operator_ok (PLUS, DImode, operands)
5154 /* Current assemblers are broken and do not allow @GOTOFF in
5155 ought but a memory context. */
5156 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5157 {
5158 switch (get_attr_type (insn))
5159 {
5160 case TYPE_INCDEC:
5161 if (! rtx_equal_p (operands[0], operands[1]))
5162 abort ();
5163 if (operands[2] == const1_rtx)
5164 return "inc{q}\t%0";
5165 else if (operands[2] == constm1_rtx)
5166 return "dec{q}\t%0";
5167 else
5168 abort ();
5169
5170 default:
5171 if (! rtx_equal_p (operands[0], operands[1]))
5172 abort ();
5173 /* ???? We ought to handle there the 32bit case too
5174 - do we need new constraint? */
5175 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5177 if (GET_CODE (operands[2]) == CONST_INT
5178 /* Avoid overflows. */
5179 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180 && (INTVAL (operands[2]) == 128
5181 || (INTVAL (operands[2]) < 0
5182 && INTVAL (operands[2]) != -128)))
5183 {
5184 operands[2] = GEN_INT (-INTVAL (operands[2]));
5185 return "sub{q}\t{%2, %0|%0, %2}";
5186 }
5187 return "add{q}\t{%2, %0|%0, %2}";
5188 }
5189 }
5190 [(set (attr "type")
5191 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192 (const_string "incdec")
5193 (const_string "alu")))
5194 (set_attr "mode" "DI")])
5195
5196 (define_insn "*adddi_3_rex64"
5197 [(set (reg 17)
5198 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5199 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5200 (clobber (match_scratch:DI 0 "=r"))]
5201 "TARGET_64BIT
5202 && ix86_match_ccmode (insn, CCZmode)
5203 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5204 /* Current assemblers are broken and do not allow @GOTOFF in
5205 ought but a memory context. */
5206 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5207 {
5208 switch (get_attr_type (insn))
5209 {
5210 case TYPE_INCDEC:
5211 if (! rtx_equal_p (operands[0], operands[1]))
5212 abort ();
5213 if (operands[2] == const1_rtx)
5214 return "inc{q}\t%0";
5215 else if (operands[2] == constm1_rtx)
5216 return "dec{q}\t%0";
5217 else
5218 abort ();
5219
5220 default:
5221 if (! rtx_equal_p (operands[0], operands[1]))
5222 abort ();
5223 /* ???? We ought to handle there the 32bit case too
5224 - do we need new constraint? */
5225 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5227 if (GET_CODE (operands[2]) == CONST_INT
5228 /* Avoid overflows. */
5229 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230 && (INTVAL (operands[2]) == 128
5231 || (INTVAL (operands[2]) < 0
5232 && INTVAL (operands[2]) != -128)))
5233 {
5234 operands[2] = GEN_INT (-INTVAL (operands[2]));
5235 return "sub{q}\t{%2, %0|%0, %2}";
5236 }
5237 return "add{q}\t{%2, %0|%0, %2}";
5238 }
5239 }
5240 [(set (attr "type")
5241 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242 (const_string "incdec")
5243 (const_string "alu")))
5244 (set_attr "mode" "DI")])
5245
5246 ; For comparisons against 1, -1 and 128, we may generate better code
5247 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5248 ; is matched then. We can't accept general immediate, because for
5249 ; case of overflows, the result is messed up.
5250 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5251 ; when negated.
5252 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5253 ; only for comparisons not depending on it.
5254 (define_insn "*adddi_4_rex64"
5255 [(set (reg 17)
5256 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5257 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5258 (clobber (match_scratch:DI 0 "=rm"))]
5259 "TARGET_64BIT
5260 && ix86_match_ccmode (insn, CCGCmode)"
5261 {
5262 switch (get_attr_type (insn))
5263 {
5264 case TYPE_INCDEC:
5265 if (operands[2] == constm1_rtx)
5266 return "inc{q}\t%0";
5267 else if (operands[2] == const1_rtx)
5268 return "dec{q}\t%0";
5269 else
5270 abort();
5271
5272 default:
5273 if (! rtx_equal_p (operands[0], operands[1]))
5274 abort ();
5275 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5276 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5277 if ((INTVAL (operands[2]) == -128
5278 || (INTVAL (operands[2]) > 0
5279 && INTVAL (operands[2]) != 128))
5280 /* Avoid overflows. */
5281 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5282 return "sub{q}\t{%2, %0|%0, %2}";
5283 operands[2] = GEN_INT (-INTVAL (operands[2]));
5284 return "add{q}\t{%2, %0|%0, %2}";
5285 }
5286 }
5287 [(set (attr "type")
5288 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5289 (const_string "incdec")
5290 (const_string "alu")))
5291 (set_attr "mode" "DI")])
5292
5293 (define_insn "*adddi_5_rex64"
5294 [(set (reg 17)
5295 (compare
5296 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5297 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5298 (const_int 0)))
5299 (clobber (match_scratch:DI 0 "=r"))]
5300 "TARGET_64BIT
5301 && ix86_match_ccmode (insn, CCGOCmode)
5302 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5303 /* Current assemblers are broken and do not allow @GOTOFF in
5304 ought but a memory context. */
5305 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5306 {
5307 switch (get_attr_type (insn))
5308 {
5309 case TYPE_INCDEC:
5310 if (! rtx_equal_p (operands[0], operands[1]))
5311 abort ();
5312 if (operands[2] == const1_rtx)
5313 return "inc{q}\t%0";
5314 else if (operands[2] == constm1_rtx)
5315 return "dec{q}\t%0";
5316 else
5317 abort();
5318
5319 default:
5320 if (! rtx_equal_p (operands[0], operands[1]))
5321 abort ();
5322 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5324 if (GET_CODE (operands[2]) == CONST_INT
5325 /* Avoid overflows. */
5326 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327 && (INTVAL (operands[2]) == 128
5328 || (INTVAL (operands[2]) < 0
5329 && INTVAL (operands[2]) != -128)))
5330 {
5331 operands[2] = GEN_INT (-INTVAL (operands[2]));
5332 return "sub{q}\t{%2, %0|%0, %2}";
5333 }
5334 return "add{q}\t{%2, %0|%0, %2}";
5335 }
5336 }
5337 [(set (attr "type")
5338 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339 (const_string "incdec")
5340 (const_string "alu")))
5341 (set_attr "mode" "DI")])
5342
5343
5344 (define_insn "*addsi_1"
5345 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5348 (clobber (reg:CC 17))]
5349 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5350 {
5351 switch (get_attr_type (insn))
5352 {
5353 case TYPE_LEA:
5354 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355 return "lea{l}\t{%a2, %0|%0, %a2}";
5356
5357 case TYPE_INCDEC:
5358 if (! rtx_equal_p (operands[0], operands[1]))
5359 abort ();
5360 if (operands[2] == const1_rtx)
5361 return "inc{l}\t%0";
5362 else if (operands[2] == constm1_rtx)
5363 return "dec{l}\t%0";
5364 else
5365 abort();
5366
5367 default:
5368 if (! rtx_equal_p (operands[0], operands[1]))
5369 abort ();
5370
5371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5373 if (GET_CODE (operands[2]) == CONST_INT
5374 && (INTVAL (operands[2]) == 128
5375 || (INTVAL (operands[2]) < 0
5376 && INTVAL (operands[2]) != -128)))
5377 {
5378 operands[2] = GEN_INT (-INTVAL (operands[2]));
5379 return "sub{l}\t{%2, %0|%0, %2}";
5380 }
5381 return "add{l}\t{%2, %0|%0, %2}";
5382 }
5383 }
5384 [(set (attr "type")
5385 (cond [(eq_attr "alternative" "2")
5386 (const_string "lea")
5387 ; Current assemblers are broken and do not allow @GOTOFF in
5388 ; ought but a memory context.
5389 (match_operand:SI 2 "pic_symbolic_operand" "")
5390 (const_string "lea")
5391 (match_operand:SI 2 "incdec_operand" "")
5392 (const_string "incdec")
5393 ]
5394 (const_string "alu")))
5395 (set_attr "mode" "SI")])
5396
5397 ;; Convert lea to the lea pattern to avoid flags dependency.
5398 (define_split
5399 [(set (match_operand 0 "register_operand" "")
5400 (plus (match_operand 1 "register_operand" "")
5401 (match_operand 2 "nonmemory_operand" "")))
5402 (clobber (reg:CC 17))]
5403 "reload_completed
5404 && true_regnum (operands[0]) != true_regnum (operands[1])"
5405 [(const_int 0)]
5406 {
5407 rtx pat;
5408 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5409 may confuse gen_lowpart. */
5410 if (GET_MODE (operands[0]) != Pmode)
5411 {
5412 operands[1] = gen_lowpart (Pmode, operands[1]);
5413 operands[2] = gen_lowpart (Pmode, operands[2]);
5414 }
5415 operands[0] = gen_lowpart (SImode, operands[0]);
5416 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5417 if (Pmode != SImode)
5418 pat = gen_rtx_SUBREG (SImode, pat, 0);
5419 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5420 DONE;
5421 })
5422
5423 ;; It may seem that nonimmediate operand is proper one for operand 1.
5424 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5425 ;; we take care in ix86_binary_operator_ok to not allow two memory
5426 ;; operands so proper swapping will be done in reload. This allow
5427 ;; patterns constructed from addsi_1 to match.
5428 (define_insn "addsi_1_zext"
5429 [(set (match_operand:DI 0 "register_operand" "=r,r")
5430 (zero_extend:DI
5431 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5432 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5433 (clobber (reg:CC 17))]
5434 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5435 {
5436 switch (get_attr_type (insn))
5437 {
5438 case TYPE_LEA:
5439 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5441
5442 case TYPE_INCDEC:
5443 if (operands[2] == const1_rtx)
5444 return "inc{l}\t%k0";
5445 else if (operands[2] == constm1_rtx)
5446 return "dec{l}\t%k0";
5447 else
5448 abort();
5449
5450 default:
5451 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5453 if (GET_CODE (operands[2]) == CONST_INT
5454 && (INTVAL (operands[2]) == 128
5455 || (INTVAL (operands[2]) < 0
5456 && INTVAL (operands[2]) != -128)))
5457 {
5458 operands[2] = GEN_INT (-INTVAL (operands[2]));
5459 return "sub{l}\t{%2, %k0|%k0, %2}";
5460 }
5461 return "add{l}\t{%2, %k0|%k0, %2}";
5462 }
5463 }
5464 [(set (attr "type")
5465 (cond [(eq_attr "alternative" "1")
5466 (const_string "lea")
5467 ; Current assemblers are broken and do not allow @GOTOFF in
5468 ; ought but a memory context.
5469 (match_operand:SI 2 "pic_symbolic_operand" "")
5470 (const_string "lea")
5471 (match_operand:SI 2 "incdec_operand" "")
5472 (const_string "incdec")
5473 ]
5474 (const_string "alu")))
5475 (set_attr "mode" "SI")])
5476
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5478 (define_split
5479 [(set (match_operand:DI 0 "register_operand" "")
5480 (zero_extend:DI
5481 (plus:SI (match_operand:SI 1 "register_operand" "")
5482 (match_operand:SI 2 "nonmemory_operand" ""))))
5483 (clobber (reg:CC 17))]
5484 "TARGET_64BIT && reload_completed
5485 && true_regnum (operands[0]) != true_regnum (operands[1])"
5486 [(set (match_dup 0)
5487 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5488 {
5489 operands[1] = gen_lowpart (Pmode, operands[1]);
5490 operands[2] = gen_lowpart (Pmode, operands[2]);
5491 })
5492
5493 (define_insn "*addsi_2"
5494 [(set (reg 17)
5495 (compare
5496 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497 (match_operand:SI 2 "general_operand" "rmni,rni"))
5498 (const_int 0)))
5499 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500 (plus:SI (match_dup 1) (match_dup 2)))]
5501 "ix86_match_ccmode (insn, CCGOCmode)
5502 && ix86_binary_operator_ok (PLUS, SImode, operands)
5503 /* Current assemblers are broken and do not allow @GOTOFF in
5504 ought but a memory context. */
5505 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507 switch (get_attr_type (insn))
5508 {
5509 case TYPE_INCDEC:
5510 if (! rtx_equal_p (operands[0], operands[1]))
5511 abort ();
5512 if (operands[2] == const1_rtx)
5513 return "inc{l}\t%0";
5514 else if (operands[2] == constm1_rtx)
5515 return "dec{l}\t%0";
5516 else
5517 abort();
5518
5519 default:
5520 if (! rtx_equal_p (operands[0], operands[1]))
5521 abort ();
5522 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5523 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5524 if (GET_CODE (operands[2]) == CONST_INT
5525 && (INTVAL (operands[2]) == 128
5526 || (INTVAL (operands[2]) < 0
5527 && INTVAL (operands[2]) != -128)))
5528 {
5529 operands[2] = GEN_INT (-INTVAL (operands[2]));
5530 return "sub{l}\t{%2, %0|%0, %2}";
5531 }
5532 return "add{l}\t{%2, %0|%0, %2}";
5533 }
5534 }
5535 [(set (attr "type")
5536 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5537 (const_string "incdec")
5538 (const_string "alu")))
5539 (set_attr "mode" "SI")])
5540
5541 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5542 (define_insn "*addsi_2_zext"
5543 [(set (reg 17)
5544 (compare
5545 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5546 (match_operand:SI 2 "general_operand" "rmni"))
5547 (const_int 0)))
5548 (set (match_operand:DI 0 "register_operand" "=r")
5549 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5550 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5551 && ix86_binary_operator_ok (PLUS, SImode, operands)
5552 /* Current assemblers are broken and do not allow @GOTOFF in
5553 ought but a memory context. */
5554 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556 switch (get_attr_type (insn))
5557 {
5558 case TYPE_INCDEC:
5559 if (operands[2] == const1_rtx)
5560 return "inc{l}\t%k0";
5561 else if (operands[2] == constm1_rtx)
5562 return "dec{l}\t%k0";
5563 else
5564 abort();
5565
5566 default:
5567 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5569 if (GET_CODE (operands[2]) == CONST_INT
5570 && (INTVAL (operands[2]) == 128
5571 || (INTVAL (operands[2]) < 0
5572 && INTVAL (operands[2]) != -128)))
5573 {
5574 operands[2] = GEN_INT (-INTVAL (operands[2]));
5575 return "sub{l}\t{%2, %k0|%k0, %2}";
5576 }
5577 return "add{l}\t{%2, %k0|%k0, %2}";
5578 }
5579 }
5580 [(set (attr "type")
5581 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582 (const_string "incdec")
5583 (const_string "alu")))
5584 (set_attr "mode" "SI")])
5585
5586 (define_insn "*addsi_3"
5587 [(set (reg 17)
5588 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590 (clobber (match_scratch:SI 0 "=r"))]
5591 "ix86_match_ccmode (insn, CCZmode)
5592 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593 /* Current assemblers are broken and do not allow @GOTOFF in
5594 ought but a memory context. */
5595 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596 {
5597 switch (get_attr_type (insn))
5598 {
5599 case TYPE_INCDEC:
5600 if (! rtx_equal_p (operands[0], operands[1]))
5601 abort ();
5602 if (operands[2] == const1_rtx)
5603 return "inc{l}\t%0";
5604 else if (operands[2] == constm1_rtx)
5605 return "dec{l}\t%0";
5606 else
5607 abort();
5608
5609 default:
5610 if (! rtx_equal_p (operands[0], operands[1]))
5611 abort ();
5612 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5613 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5614 if (GET_CODE (operands[2]) == CONST_INT
5615 && (INTVAL (operands[2]) == 128
5616 || (INTVAL (operands[2]) < 0
5617 && INTVAL (operands[2]) != -128)))
5618 {
5619 operands[2] = GEN_INT (-INTVAL (operands[2]));
5620 return "sub{l}\t{%2, %0|%0, %2}";
5621 }
5622 return "add{l}\t{%2, %0|%0, %2}";
5623 }
5624 }
5625 [(set (attr "type")
5626 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5627 (const_string "incdec")
5628 (const_string "alu")))
5629 (set_attr "mode" "SI")])
5630
5631 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5632 (define_insn "*addsi_3_zext"
5633 [(set (reg 17)
5634 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5635 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5636 (set (match_operand:DI 0 "register_operand" "=r")
5637 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5639 && ix86_binary_operator_ok (PLUS, SImode, operands)
5640 /* Current assemblers are broken and do not allow @GOTOFF in
5641 ought but a memory context. */
5642 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643 {
5644 switch (get_attr_type (insn))
5645 {
5646 case TYPE_INCDEC:
5647 if (operands[2] == const1_rtx)
5648 return "inc{l}\t%k0";
5649 else if (operands[2] == constm1_rtx)
5650 return "dec{l}\t%k0";
5651 else
5652 abort();
5653
5654 default:
5655 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5657 if (GET_CODE (operands[2]) == CONST_INT
5658 && (INTVAL (operands[2]) == 128
5659 || (INTVAL (operands[2]) < 0
5660 && INTVAL (operands[2]) != -128)))
5661 {
5662 operands[2] = GEN_INT (-INTVAL (operands[2]));
5663 return "sub{l}\t{%2, %k0|%k0, %2}";
5664 }
5665 return "add{l}\t{%2, %k0|%k0, %2}";
5666 }
5667 }
5668 [(set (attr "type")
5669 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670 (const_string "incdec")
5671 (const_string "alu")))
5672 (set_attr "mode" "SI")])
5673
5674 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5676 ; is matched then. We can't accept general immediate, because for
5677 ; case of overflows, the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5679 ; when negated.
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683 [(set (reg 17)
5684 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685 (match_operand:SI 2 "const_int_operand" "n")))
5686 (clobber (match_scratch:SI 0 "=rm"))]
5687 "ix86_match_ccmode (insn, CCGCmode)
5688 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5689 {
5690 switch (get_attr_type (insn))
5691 {
5692 case TYPE_INCDEC:
5693 if (operands[2] == constm1_rtx)
5694 return "inc{l}\t%0";
5695 else if (operands[2] == const1_rtx)
5696 return "dec{l}\t%0";
5697 else
5698 abort();
5699
5700 default:
5701 if (! rtx_equal_p (operands[0], operands[1]))
5702 abort ();
5703 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5705 if ((INTVAL (operands[2]) == -128
5706 || (INTVAL (operands[2]) > 0
5707 && INTVAL (operands[2]) != 128)))
5708 return "sub{l}\t{%2, %0|%0, %2}";
5709 operands[2] = GEN_INT (-INTVAL (operands[2]));
5710 return "add{l}\t{%2, %0|%0, %2}";
5711 }
5712 }
5713 [(set (attr "type")
5714 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715 (const_string "incdec")
5716 (const_string "alu")))
5717 (set_attr "mode" "SI")])
5718
5719 (define_insn "*addsi_5"
5720 [(set (reg 17)
5721 (compare
5722 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723 (match_operand:SI 2 "general_operand" "rmni"))
5724 (const_int 0)))
5725 (clobber (match_scratch:SI 0 "=r"))]
5726 "ix86_match_ccmode (insn, CCGOCmode)
5727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728 /* Current assemblers are broken and do not allow @GOTOFF in
5729 ought but a memory context. */
5730 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 {
5732 switch (get_attr_type (insn))
5733 {
5734 case TYPE_INCDEC:
5735 if (! rtx_equal_p (operands[0], operands[1]))
5736 abort ();
5737 if (operands[2] == const1_rtx)
5738 return "inc{l}\t%0";
5739 else if (operands[2] == constm1_rtx)
5740 return "dec{l}\t%0";
5741 else
5742 abort();
5743
5744 default:
5745 if (! rtx_equal_p (operands[0], operands[1]))
5746 abort ();
5747 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5748 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5749 if (GET_CODE (operands[2]) == CONST_INT
5750 && (INTVAL (operands[2]) == 128
5751 || (INTVAL (operands[2]) < 0
5752 && INTVAL (operands[2]) != -128)))
5753 {
5754 operands[2] = GEN_INT (-INTVAL (operands[2]));
5755 return "sub{l}\t{%2, %0|%0, %2}";
5756 }
5757 return "add{l}\t{%2, %0|%0, %2}";
5758 }
5759 }
5760 [(set (attr "type")
5761 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762 (const_string "incdec")
5763 (const_string "alu")))
5764 (set_attr "mode" "SI")])
5765
5766 (define_expand "addhi3"
5767 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5768 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5769 (match_operand:HI 2 "general_operand" "")))
5770 (clobber (reg:CC 17))])]
5771 "TARGET_HIMODE_MATH"
5772 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5773
5774 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5775 ;; type optimizations enabled by define-splits. This is not important
5776 ;; for PII, and in fact harmful because of partial register stalls.
5777
5778 (define_insn "*addhi_1_lea"
5779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5780 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5781 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5782 (clobber (reg:CC 17))]
5783 "!TARGET_PARTIAL_REG_STALL
5784 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 {
5786 switch (get_attr_type (insn))
5787 {
5788 case TYPE_LEA:
5789 return "#";
5790 case TYPE_INCDEC:
5791 if (operands[2] == const1_rtx)
5792 return "inc{w}\t%0";
5793 else if (operands[2] == constm1_rtx)
5794 return "dec{w}\t%0";
5795 abort();
5796
5797 default:
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (GET_CODE (operands[2]) == CONST_INT
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5804 {
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{w}\t{%2, %0|%0, %2}";
5807 }
5808 return "add{w}\t{%2, %0|%0, %2}";
5809 }
5810 }
5811 [(set (attr "type")
5812 (if_then_else (eq_attr "alternative" "2")
5813 (const_string "lea")
5814 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5815 (const_string "incdec")
5816 (const_string "alu"))))
5817 (set_attr "mode" "HI,HI,SI")])
5818
5819 (define_insn "*addhi_1"
5820 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5821 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5822 (match_operand:HI 2 "general_operand" "ri,rm")))
5823 (clobber (reg:CC 17))]
5824 "TARGET_PARTIAL_REG_STALL
5825 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826 {
5827 switch (get_attr_type (insn))
5828 {
5829 case TYPE_INCDEC:
5830 if (operands[2] == const1_rtx)
5831 return "inc{w}\t%0";
5832 else if (operands[2] == constm1_rtx)
5833 return "dec{w}\t%0";
5834 abort();
5835
5836 default:
5837 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5838 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5839 if (GET_CODE (operands[2]) == CONST_INT
5840 && (INTVAL (operands[2]) == 128
5841 || (INTVAL (operands[2]) < 0
5842 && INTVAL (operands[2]) != -128)))
5843 {
5844 operands[2] = GEN_INT (-INTVAL (operands[2]));
5845 return "sub{w}\t{%2, %0|%0, %2}";
5846 }
5847 return "add{w}\t{%2, %0|%0, %2}";
5848 }
5849 }
5850 [(set (attr "type")
5851 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5852 (const_string "incdec")
5853 (const_string "alu")))
5854 (set_attr "mode" "HI")])
5855
5856 (define_insn "*addhi_2"
5857 [(set (reg 17)
5858 (compare
5859 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5860 (match_operand:HI 2 "general_operand" "rmni,rni"))
5861 (const_int 0)))
5862 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5863 (plus:HI (match_dup 1) (match_dup 2)))]
5864 "ix86_match_ccmode (insn, CCGOCmode)
5865 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5866 {
5867 switch (get_attr_type (insn))
5868 {
5869 case TYPE_INCDEC:
5870 if (operands[2] == const1_rtx)
5871 return "inc{w}\t%0";
5872 else if (operands[2] == constm1_rtx)
5873 return "dec{w}\t%0";
5874 abort();
5875
5876 default:
5877 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5878 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5879 if (GET_CODE (operands[2]) == CONST_INT
5880 && (INTVAL (operands[2]) == 128
5881 || (INTVAL (operands[2]) < 0
5882 && INTVAL (operands[2]) != -128)))
5883 {
5884 operands[2] = GEN_INT (-INTVAL (operands[2]));
5885 return "sub{w}\t{%2, %0|%0, %2}";
5886 }
5887 return "add{w}\t{%2, %0|%0, %2}";
5888 }
5889 }
5890 [(set (attr "type")
5891 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5892 (const_string "incdec")
5893 (const_string "alu")))
5894 (set_attr "mode" "HI")])
5895
5896 (define_insn "*addhi_3"
5897 [(set (reg 17)
5898 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5899 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5900 (clobber (match_scratch:HI 0 "=r"))]
5901 "ix86_match_ccmode (insn, CCZmode)
5902 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5903 {
5904 switch (get_attr_type (insn))
5905 {
5906 case TYPE_INCDEC:
5907 if (operands[2] == const1_rtx)
5908 return "inc{w}\t%0";
5909 else if (operands[2] == constm1_rtx)
5910 return "dec{w}\t%0";
5911 abort();
5912
5913 default:
5914 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5916 if (GET_CODE (operands[2]) == CONST_INT
5917 && (INTVAL (operands[2]) == 128
5918 || (INTVAL (operands[2]) < 0
5919 && INTVAL (operands[2]) != -128)))
5920 {
5921 operands[2] = GEN_INT (-INTVAL (operands[2]));
5922 return "sub{w}\t{%2, %0|%0, %2}";
5923 }
5924 return "add{w}\t{%2, %0|%0, %2}";
5925 }
5926 }
5927 [(set (attr "type")
5928 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5929 (const_string "incdec")
5930 (const_string "alu")))
5931 (set_attr "mode" "HI")])
5932
5933 ; See comments above addsi_3_imm for details.
5934 (define_insn "*addhi_4"
5935 [(set (reg 17)
5936 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5937 (match_operand:HI 2 "const_int_operand" "n")))
5938 (clobber (match_scratch:HI 0 "=rm"))]
5939 "ix86_match_ccmode (insn, CCGCmode)
5940 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5941 {
5942 switch (get_attr_type (insn))
5943 {
5944 case TYPE_INCDEC:
5945 if (operands[2] == constm1_rtx)
5946 return "inc{w}\t%0";
5947 else if (operands[2] == const1_rtx)
5948 return "dec{w}\t%0";
5949 else
5950 abort();
5951
5952 default:
5953 if (! rtx_equal_p (operands[0], operands[1]))
5954 abort ();
5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5957 if ((INTVAL (operands[2]) == -128
5958 || (INTVAL (operands[2]) > 0
5959 && INTVAL (operands[2]) != 128)))
5960 return "sub{w}\t{%2, %0|%0, %2}";
5961 operands[2] = GEN_INT (-INTVAL (operands[2]));
5962 return "add{w}\t{%2, %0|%0, %2}";
5963 }
5964 }
5965 [(set (attr "type")
5966 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5967 (const_string "incdec")
5968 (const_string "alu")))
5969 (set_attr "mode" "SI")])
5970
5971
5972 (define_insn "*addhi_5"
5973 [(set (reg 17)
5974 (compare
5975 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5976 (match_operand:HI 2 "general_operand" "rmni"))
5977 (const_int 0)))
5978 (clobber (match_scratch:HI 0 "=r"))]
5979 "ix86_match_ccmode (insn, CCGOCmode)
5980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5981 {
5982 switch (get_attr_type (insn))
5983 {
5984 case TYPE_INCDEC:
5985 if (operands[2] == const1_rtx)
5986 return "inc{w}\t%0";
5987 else if (operands[2] == constm1_rtx)
5988 return "dec{w}\t%0";
5989 abort();
5990
5991 default:
5992 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5993 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5994 if (GET_CODE (operands[2]) == CONST_INT
5995 && (INTVAL (operands[2]) == 128
5996 || (INTVAL (operands[2]) < 0
5997 && INTVAL (operands[2]) != -128)))
5998 {
5999 operands[2] = GEN_INT (-INTVAL (operands[2]));
6000 return "sub{w}\t{%2, %0|%0, %2}";
6001 }
6002 return "add{w}\t{%2, %0|%0, %2}";
6003 }
6004 }
6005 [(set (attr "type")
6006 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007 (const_string "incdec")
6008 (const_string "alu")))
6009 (set_attr "mode" "HI")])
6010
6011 (define_expand "addqi3"
6012 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6013 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6014 (match_operand:QI 2 "general_operand" "")))
6015 (clobber (reg:CC 17))])]
6016 "TARGET_QIMODE_MATH"
6017 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6018
6019 ;; %%% Potential partial reg stall on alternative 2. What to do?
6020 (define_insn "*addqi_1_lea"
6021 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6022 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6023 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6024 (clobber (reg:CC 17))]
6025 "!TARGET_PARTIAL_REG_STALL
6026 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6027 {
6028 int widen = (which_alternative == 2);
6029 switch (get_attr_type (insn))
6030 {
6031 case TYPE_LEA:
6032 return "#";
6033 case TYPE_INCDEC:
6034 if (operands[2] == const1_rtx)
6035 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6036 else if (operands[2] == constm1_rtx)
6037 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6038 abort();
6039
6040 default:
6041 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6042 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6043 if (GET_CODE (operands[2]) == CONST_INT
6044 && (INTVAL (operands[2]) == 128
6045 || (INTVAL (operands[2]) < 0
6046 && INTVAL (operands[2]) != -128)))
6047 {
6048 operands[2] = GEN_INT (-INTVAL (operands[2]));
6049 if (widen)
6050 return "sub{l}\t{%2, %k0|%k0, %2}";
6051 else
6052 return "sub{b}\t{%2, %0|%0, %2}";
6053 }
6054 if (widen)
6055 return "add{l}\t{%k2, %k0|%k0, %k2}";
6056 else
6057 return "add{b}\t{%2, %0|%0, %2}";
6058 }
6059 }
6060 [(set (attr "type")
6061 (if_then_else (eq_attr "alternative" "3")
6062 (const_string "lea")
6063 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu"))))
6066 (set_attr "mode" "QI,QI,SI,SI")])
6067
6068 (define_insn "*addqi_1"
6069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6070 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6071 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6072 (clobber (reg:CC 17))]
6073 "TARGET_PARTIAL_REG_STALL
6074 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6075 {
6076 int widen = (which_alternative == 2);
6077 switch (get_attr_type (insn))
6078 {
6079 case TYPE_INCDEC:
6080 if (operands[2] == const1_rtx)
6081 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6082 else if (operands[2] == constm1_rtx)
6083 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6084 abort();
6085
6086 default:
6087 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6088 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6089 if (GET_CODE (operands[2]) == CONST_INT
6090 && (INTVAL (operands[2]) == 128
6091 || (INTVAL (operands[2]) < 0
6092 && INTVAL (operands[2]) != -128)))
6093 {
6094 operands[2] = GEN_INT (-INTVAL (operands[2]));
6095 if (widen)
6096 return "sub{l}\t{%2, %k0|%k0, %2}";
6097 else
6098 return "sub{b}\t{%2, %0|%0, %2}";
6099 }
6100 if (widen)
6101 return "add{l}\t{%k2, %k0|%k0, %k2}";
6102 else
6103 return "add{b}\t{%2, %0|%0, %2}";
6104 }
6105 }
6106 [(set (attr "type")
6107 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108 (const_string "incdec")
6109 (const_string "alu")))
6110 (set_attr "mode" "QI,QI,SI")])
6111
6112 (define_insn "*addqi_1_slp"
6113 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6114 (plus:QI (match_dup 0)
6115 (match_operand:QI 1 "general_operand" "qn,qnm")))
6116 (clobber (reg:CC 17))]
6117 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6118 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6119 {
6120 switch (get_attr_type (insn))
6121 {
6122 case TYPE_INCDEC:
6123 if (operands[1] == const1_rtx)
6124 return "inc{b}\t%0";
6125 else if (operands[1] == constm1_rtx)
6126 return "dec{b}\t%0";
6127 abort();
6128
6129 default:
6130 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6131 if (GET_CODE (operands[1]) == CONST_INT
6132 && INTVAL (operands[1]) < 0)
6133 {
6134 operands[2] = GEN_INT (-INTVAL (operands[2]));
6135 return "sub{b}\t{%1, %0|%0, %1}";
6136 }
6137 return "add{b}\t{%1, %0|%0, %1}";
6138 }
6139 }
6140 [(set (attr "type")
6141 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6142 (const_string "incdec")
6143 (const_string "alu1")))
6144 (set_attr "mode" "QI")])
6145
6146 (define_insn "*addqi_2"
6147 [(set (reg 17)
6148 (compare
6149 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6150 (match_operand:QI 2 "general_operand" "qmni,qni"))
6151 (const_int 0)))
6152 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6153 (plus:QI (match_dup 1) (match_dup 2)))]
6154 "ix86_match_ccmode (insn, CCGOCmode)
6155 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6156 {
6157 switch (get_attr_type (insn))
6158 {
6159 case TYPE_INCDEC:
6160 if (operands[2] == const1_rtx)
6161 return "inc{b}\t%0";
6162 else if (operands[2] == constm1_rtx
6163 || (GET_CODE (operands[2]) == CONST_INT
6164 && INTVAL (operands[2]) == 255))
6165 return "dec{b}\t%0";
6166 abort();
6167
6168 default:
6169 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6170 if (GET_CODE (operands[2]) == CONST_INT
6171 && INTVAL (operands[2]) < 0)
6172 {
6173 operands[2] = GEN_INT (-INTVAL (operands[2]));
6174 return "sub{b}\t{%2, %0|%0, %2}";
6175 }
6176 return "add{b}\t{%2, %0|%0, %2}";
6177 }
6178 }
6179 [(set (attr "type")
6180 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set_attr "mode" "QI")])
6184
6185 (define_insn "*addqi_3"
6186 [(set (reg 17)
6187 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6188 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6189 (clobber (match_scratch:QI 0 "=q"))]
6190 "ix86_match_ccmode (insn, CCZmode)
6191 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6192 {
6193 switch (get_attr_type (insn))
6194 {
6195 case TYPE_INCDEC:
6196 if (operands[2] == const1_rtx)
6197 return "inc{b}\t%0";
6198 else if (operands[2] == constm1_rtx
6199 || (GET_CODE (operands[2]) == CONST_INT
6200 && INTVAL (operands[2]) == 255))
6201 return "dec{b}\t%0";
6202 abort();
6203
6204 default:
6205 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6206 if (GET_CODE (operands[2]) == CONST_INT
6207 && INTVAL (operands[2]) < 0)
6208 {
6209 operands[2] = GEN_INT (-INTVAL (operands[2]));
6210 return "sub{b}\t{%2, %0|%0, %2}";
6211 }
6212 return "add{b}\t{%2, %0|%0, %2}";
6213 }
6214 }
6215 [(set (attr "type")
6216 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6217 (const_string "incdec")
6218 (const_string "alu")))
6219 (set_attr "mode" "QI")])
6220
6221 ; See comments above addsi_3_imm for details.
6222 (define_insn "*addqi_4"
6223 [(set (reg 17)
6224 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6225 (match_operand:QI 2 "const_int_operand" "n")))
6226 (clobber (match_scratch:QI 0 "=qm"))]
6227 "ix86_match_ccmode (insn, CCGCmode)
6228 && (INTVAL (operands[2]) & 0xff) != 0x80"
6229 {
6230 switch (get_attr_type (insn))
6231 {
6232 case TYPE_INCDEC:
6233 if (operands[2] == constm1_rtx
6234 || (GET_CODE (operands[2]) == CONST_INT
6235 && INTVAL (operands[2]) == 255))
6236 return "inc{b}\t%0";
6237 else if (operands[2] == const1_rtx)
6238 return "dec{b}\t%0";
6239 else
6240 abort();
6241
6242 default:
6243 if (! rtx_equal_p (operands[0], operands[1]))
6244 abort ();
6245 if (INTVAL (operands[2]) < 0)
6246 {
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "add{b}\t{%2, %0|%0, %2}";
6249 }
6250 return "sub{b}\t{%2, %0|%0, %2}";
6251 }
6252 }
6253 [(set (attr "type")
6254 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255 (const_string "incdec")
6256 (const_string "alu")))
6257 (set_attr "mode" "QI")])
6258
6259
6260 (define_insn "*addqi_5"
6261 [(set (reg 17)
6262 (compare
6263 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6264 (match_operand:QI 2 "general_operand" "qmni"))
6265 (const_int 0)))
6266 (clobber (match_scratch:QI 0 "=q"))]
6267 "ix86_match_ccmode (insn, CCGOCmode)
6268 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6269 {
6270 switch (get_attr_type (insn))
6271 {
6272 case TYPE_INCDEC:
6273 if (operands[2] == const1_rtx)
6274 return "inc{b}\t%0";
6275 else if (operands[2] == constm1_rtx
6276 || (GET_CODE (operands[2]) == CONST_INT
6277 && INTVAL (operands[2]) == 255))
6278 return "dec{b}\t%0";
6279 abort();
6280
6281 default:
6282 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6283 if (GET_CODE (operands[2]) == CONST_INT
6284 && INTVAL (operands[2]) < 0)
6285 {
6286 operands[2] = GEN_INT (-INTVAL (operands[2]));
6287 return "sub{b}\t{%2, %0|%0, %2}";
6288 }
6289 return "add{b}\t{%2, %0|%0, %2}";
6290 }
6291 }
6292 [(set (attr "type")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "QI")])
6297
6298
6299 (define_insn "addqi_ext_1"
6300 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6301 (const_int 8)
6302 (const_int 8))
6303 (plus:SI
6304 (zero_extract:SI
6305 (match_operand 1 "ext_register_operand" "0")
6306 (const_int 8)
6307 (const_int 8))
6308 (match_operand:QI 2 "general_operand" "Qmn")))
6309 (clobber (reg:CC 17))]
6310 "!TARGET_64BIT"
6311 {
6312 switch (get_attr_type (insn))
6313 {
6314 case TYPE_INCDEC:
6315 if (operands[2] == const1_rtx)
6316 return "inc{b}\t%h0";
6317 else if (operands[2] == constm1_rtx
6318 || (GET_CODE (operands[2]) == CONST_INT
6319 && INTVAL (operands[2]) == 255))
6320 return "dec{b}\t%h0";
6321 abort();
6322
6323 default:
6324 return "add{b}\t{%2, %h0|%h0, %2}";
6325 }
6326 }
6327 [(set (attr "type")
6328 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6329 (const_string "incdec")
6330 (const_string "alu")))
6331 (set_attr "mode" "QI")])
6332
6333 (define_insn "*addqi_ext_1_rex64"
6334 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6335 (const_int 8)
6336 (const_int 8))
6337 (plus:SI
6338 (zero_extract:SI
6339 (match_operand 1 "ext_register_operand" "0")
6340 (const_int 8)
6341 (const_int 8))
6342 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6343 (clobber (reg:CC 17))]
6344 "TARGET_64BIT"
6345 {
6346 switch (get_attr_type (insn))
6347 {
6348 case TYPE_INCDEC:
6349 if (operands[2] == const1_rtx)
6350 return "inc{b}\t%h0";
6351 else if (operands[2] == constm1_rtx
6352 || (GET_CODE (operands[2]) == CONST_INT
6353 && INTVAL (operands[2]) == 255))
6354 return "dec{b}\t%h0";
6355 abort();
6356
6357 default:
6358 return "add{b}\t{%2, %h0|%h0, %2}";
6359 }
6360 }
6361 [(set (attr "type")
6362 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6363 (const_string "incdec")
6364 (const_string "alu")))
6365 (set_attr "mode" "QI")])
6366
6367 (define_insn "*addqi_ext_2"
6368 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6369 (const_int 8)
6370 (const_int 8))
6371 (plus:SI
6372 (zero_extract:SI
6373 (match_operand 1 "ext_register_operand" "%0")
6374 (const_int 8)
6375 (const_int 8))
6376 (zero_extract:SI
6377 (match_operand 2 "ext_register_operand" "Q")
6378 (const_int 8)
6379 (const_int 8))))
6380 (clobber (reg:CC 17))]
6381 ""
6382 "add{b}\t{%h2, %h0|%h0, %h2}"
6383 [(set_attr "type" "alu")
6384 (set_attr "mode" "QI")])
6385
6386 ;; The patterns that match these are at the end of this file.
6387
6388 (define_expand "addxf3"
6389 [(set (match_operand:XF 0 "register_operand" "")
6390 (plus:XF (match_operand:XF 1 "register_operand" "")
6391 (match_operand:XF 2 "register_operand" "")))]
6392 "TARGET_80387"
6393 "")
6394
6395 (define_expand "adddf3"
6396 [(set (match_operand:DF 0 "register_operand" "")
6397 (plus:DF (match_operand:DF 1 "register_operand" "")
6398 (match_operand:DF 2 "nonimmediate_operand" "")))]
6399 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6400 "")
6401
6402 (define_expand "addsf3"
6403 [(set (match_operand:SF 0 "register_operand" "")
6404 (plus:SF (match_operand:SF 1 "register_operand" "")
6405 (match_operand:SF 2 "nonimmediate_operand" "")))]
6406 "TARGET_80387 || TARGET_SSE_MATH"
6407 "")
6408 \f
6409 ;; Subtract instructions
6410
6411 ;; %%% splits for subsidi3
6412
6413 (define_expand "subdi3"
6414 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6415 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6416 (match_operand:DI 2 "x86_64_general_operand" "")))
6417 (clobber (reg:CC 17))])]
6418 ""
6419 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6420
6421 (define_insn "*subdi3_1"
6422 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6423 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6424 (match_operand:DI 2 "general_operand" "roiF,riF")))
6425 (clobber (reg:CC 17))]
6426 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6427 "#")
6428
6429 (define_split
6430 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6431 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6432 (match_operand:DI 2 "general_operand" "")))
6433 (clobber (reg:CC 17))]
6434 "!TARGET_64BIT && reload_completed"
6435 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6436 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6437 (parallel [(set (match_dup 3)
6438 (minus:SI (match_dup 4)
6439 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6440 (match_dup 5))))
6441 (clobber (reg:CC 17))])]
6442 "split_di (operands+0, 1, operands+0, operands+3);
6443 split_di (operands+1, 1, operands+1, operands+4);
6444 split_di (operands+2, 1, operands+2, operands+5);")
6445
6446 (define_insn "subdi3_carry_rex64"
6447 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6448 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6449 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6450 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6451 (clobber (reg:CC 17))]
6452 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6453 "sbb{q}\t{%2, %0|%0, %2}"
6454 [(set_attr "type" "alu")
6455 (set_attr "pent_pair" "pu")
6456 (set_attr "ppro_uops" "few")
6457 (set_attr "mode" "DI")])
6458
6459 (define_insn "*subdi_1_rex64"
6460 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6461 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6462 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6463 (clobber (reg:CC 17))]
6464 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6465 "sub{q}\t{%2, %0|%0, %2}"
6466 [(set_attr "type" "alu")
6467 (set_attr "mode" "DI")])
6468
6469 (define_insn "*subdi_2_rex64"
6470 [(set (reg 17)
6471 (compare
6472 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6474 (const_int 0)))
6475 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6476 (minus:DI (match_dup 1) (match_dup 2)))]
6477 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6478 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6479 "sub{q}\t{%2, %0|%0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "mode" "DI")])
6482
6483 (define_insn "*subdi_3_rex63"
6484 [(set (reg 17)
6485 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6487 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6488 (minus:DI (match_dup 1) (match_dup 2)))]
6489 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6490 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6491 "sub{q}\t{%2, %0|%0, %2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "DI")])
6494
6495 (define_insn "subqi3_carry"
6496 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6497 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6498 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6499 (match_operand:QI 2 "general_operand" "qi,qm"))))
6500 (clobber (reg:CC 17))]
6501 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6502 "sbb{b}\t{%2, %0|%0, %2}"
6503 [(set_attr "type" "alu")
6504 (set_attr "pent_pair" "pu")
6505 (set_attr "ppro_uops" "few")
6506 (set_attr "mode" "QI")])
6507
6508 (define_insn "subhi3_carry"
6509 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6510 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6511 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6512 (match_operand:HI 2 "general_operand" "ri,rm"))))
6513 (clobber (reg:CC 17))]
6514 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6515 "sbb{w}\t{%2, %0|%0, %2}"
6516 [(set_attr "type" "alu")
6517 (set_attr "pent_pair" "pu")
6518 (set_attr "ppro_uops" "few")
6519 (set_attr "mode" "HI")])
6520
6521 (define_insn "subsi3_carry"
6522 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6523 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6524 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6525 (match_operand:SI 2 "general_operand" "ri,rm"))))
6526 (clobber (reg:CC 17))]
6527 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6528 "sbb{l}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "pent_pair" "pu")
6531 (set_attr "ppro_uops" "few")
6532 (set_attr "mode" "SI")])
6533
6534 (define_insn "subsi3_carry_zext"
6535 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6536 (zero_extend:DI
6537 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6538 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6539 (match_operand:SI 2 "general_operand" "ri,rm")))))
6540 (clobber (reg:CC 17))]
6541 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6542 "sbb{l}\t{%2, %k0|%k0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "pent_pair" "pu")
6545 (set_attr "ppro_uops" "few")
6546 (set_attr "mode" "SI")])
6547
6548 (define_expand "subsi3"
6549 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6550 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6551 (match_operand:SI 2 "general_operand" "")))
6552 (clobber (reg:CC 17))])]
6553 ""
6554 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6555
6556 (define_insn "*subsi_1"
6557 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6558 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6559 (match_operand:SI 2 "general_operand" "ri,rm")))
6560 (clobber (reg:CC 17))]
6561 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6562 "sub{l}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "mode" "SI")])
6565
6566 (define_insn "*subsi_1_zext"
6567 [(set (match_operand:DI 0 "register_operand" "=r")
6568 (zero_extend:DI
6569 (minus:SI (match_operand:SI 1 "register_operand" "0")
6570 (match_operand:SI 2 "general_operand" "rim"))))
6571 (clobber (reg:CC 17))]
6572 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573 "sub{l}\t{%2, %k0|%k0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "mode" "SI")])
6576
6577 (define_insn "*subsi_2"
6578 [(set (reg 17)
6579 (compare
6580 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6581 (match_operand:SI 2 "general_operand" "ri,rm"))
6582 (const_int 0)))
6583 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584 (minus:SI (match_dup 1) (match_dup 2)))]
6585 "ix86_match_ccmode (insn, CCGOCmode)
6586 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587 "sub{l}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "mode" "SI")])
6590
6591 (define_insn "*subsi_2_zext"
6592 [(set (reg 17)
6593 (compare
6594 (minus:SI (match_operand:SI 1 "register_operand" "0")
6595 (match_operand:SI 2 "general_operand" "rim"))
6596 (const_int 0)))
6597 (set (match_operand:DI 0 "register_operand" "=r")
6598 (zero_extend:DI
6599 (minus:SI (match_dup 1)
6600 (match_dup 2))))]
6601 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6602 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6603 "sub{l}\t{%2, %k0|%k0, %2}"
6604 [(set_attr "type" "alu")
6605 (set_attr "mode" "SI")])
6606
6607 (define_insn "*subsi_3"
6608 [(set (reg 17)
6609 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6610 (match_operand:SI 2 "general_operand" "ri,rm")))
6611 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6612 (minus:SI (match_dup 1) (match_dup 2)))]
6613 "ix86_match_ccmode (insn, CCmode)
6614 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6615 "sub{l}\t{%2, %0|%0, %2}"
6616 [(set_attr "type" "alu")
6617 (set_attr "mode" "SI")])
6618
6619 (define_insn "*subsi_3_zext"
6620 [(set (reg 17)
6621 (compare (match_operand:SI 1 "register_operand" "0")
6622 (match_operand:SI 2 "general_operand" "rim")))
6623 (set (match_operand:DI 0 "register_operand" "=r")
6624 (zero_extend:DI
6625 (minus:SI (match_dup 1)
6626 (match_dup 2))))]
6627 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6628 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6629 "sub{q}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "DI")])
6632
6633 (define_expand "subhi3"
6634 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6635 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6636 (match_operand:HI 2 "general_operand" "")))
6637 (clobber (reg:CC 17))])]
6638 "TARGET_HIMODE_MATH"
6639 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6640
6641 (define_insn "*subhi_1"
6642 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6643 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:HI 2 "general_operand" "ri,rm")))
6645 (clobber (reg:CC 17))]
6646 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6647 "sub{w}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "HI")])
6650
6651 (define_insn "*subhi_2"
6652 [(set (reg 17)
6653 (compare
6654 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6655 (match_operand:HI 2 "general_operand" "ri,rm"))
6656 (const_int 0)))
6657 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6658 (minus:HI (match_dup 1) (match_dup 2)))]
6659 "ix86_match_ccmode (insn, CCGOCmode)
6660 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6661 "sub{w}\t{%2, %0|%0, %2}"
6662 [(set_attr "type" "alu")
6663 (set_attr "mode" "HI")])
6664
6665 (define_insn "*subhi_3"
6666 [(set (reg 17)
6667 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6668 (match_operand:HI 2 "general_operand" "ri,rm")))
6669 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6670 (minus:HI (match_dup 1) (match_dup 2)))]
6671 "ix86_match_ccmode (insn, CCmode)
6672 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6673 "sub{w}\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "mode" "HI")])
6676
6677 (define_expand "subqi3"
6678 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6679 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6680 (match_operand:QI 2 "general_operand" "")))
6681 (clobber (reg:CC 17))])]
6682 "TARGET_QIMODE_MATH"
6683 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6684
6685 (define_insn "*subqi_1"
6686 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6687 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:QI 2 "general_operand" "qn,qmn")))
6689 (clobber (reg:CC 17))]
6690 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6691 "sub{b}\t{%2, %0|%0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "mode" "QI")])
6694
6695 (define_insn "*subqi_1_slp"
6696 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6697 (minus:QI (match_dup 0)
6698 (match_operand:QI 1 "general_operand" "qn,qmn")))
6699 (clobber (reg:CC 17))]
6700 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6702 "sub{b}\t{%1, %0|%0, %1}"
6703 [(set_attr "type" "alu1")
6704 (set_attr "mode" "QI")])
6705
6706 (define_insn "*subqi_2"
6707 [(set (reg 17)
6708 (compare
6709 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6710 (match_operand:QI 2 "general_operand" "qi,qm"))
6711 (const_int 0)))
6712 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6713 (minus:HI (match_dup 1) (match_dup 2)))]
6714 "ix86_match_ccmode (insn, CCGOCmode)
6715 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6716 "sub{b}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "QI")])
6719
6720 (define_insn "*subqi_3"
6721 [(set (reg 17)
6722 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6723 (match_operand:QI 2 "general_operand" "qi,qm")))
6724 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6725 (minus:HI (match_dup 1) (match_dup 2)))]
6726 "ix86_match_ccmode (insn, CCmode)
6727 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6728 "sub{b}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "QI")])
6731
6732 ;; The patterns that match these are at the end of this file.
6733
6734 (define_expand "subxf3"
6735 [(set (match_operand:XF 0 "register_operand" "")
6736 (minus:XF (match_operand:XF 1 "register_operand" "")
6737 (match_operand:XF 2 "register_operand" "")))]
6738 "TARGET_80387"
6739 "")
6740
6741 (define_expand "subdf3"
6742 [(set (match_operand:DF 0 "register_operand" "")
6743 (minus:DF (match_operand:DF 1 "register_operand" "")
6744 (match_operand:DF 2 "nonimmediate_operand" "")))]
6745 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6746 "")
6747
6748 (define_expand "subsf3"
6749 [(set (match_operand:SF 0 "register_operand" "")
6750 (minus:SF (match_operand:SF 1 "register_operand" "")
6751 (match_operand:SF 2 "nonimmediate_operand" "")))]
6752 "TARGET_80387 || TARGET_SSE_MATH"
6753 "")
6754 \f
6755 ;; Multiply instructions
6756
6757 (define_expand "muldi3"
6758 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6759 (mult:DI (match_operand:DI 1 "register_operand" "")
6760 (match_operand:DI 2 "x86_64_general_operand" "")))
6761 (clobber (reg:CC 17))])]
6762 "TARGET_64BIT"
6763 "")
6764
6765 (define_insn "*muldi3_1_rex64"
6766 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6767 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6768 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6769 (clobber (reg:CC 17))]
6770 "TARGET_64BIT
6771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6772 "@
6773 imul{q}\t{%2, %1, %0|%0, %1, %2}
6774 imul{q}\t{%2, %1, %0|%0, %1, %2}
6775 imul{q}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "imul")
6777 (set_attr "prefix_0f" "0,0,1")
6778 (set (attr "athlon_decode")
6779 (cond [(eq_attr "cpu" "athlon")
6780 (const_string "vector")
6781 (eq_attr "alternative" "1")
6782 (const_string "vector")
6783 (and (eq_attr "alternative" "2")
6784 (match_operand 1 "memory_operand" ""))
6785 (const_string "vector")]
6786 (const_string "direct")))
6787 (set_attr "mode" "DI")])
6788
6789 (define_expand "mulsi3"
6790 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6791 (mult:SI (match_operand:SI 1 "register_operand" "")
6792 (match_operand:SI 2 "general_operand" "")))
6793 (clobber (reg:CC 17))])]
6794 ""
6795 "")
6796
6797 (define_insn "*mulsi3_1"
6798 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6799 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6800 (match_operand:SI 2 "general_operand" "K,i,mr")))
6801 (clobber (reg:CC 17))]
6802 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6803 "@
6804 imul{l}\t{%2, %1, %0|%0, %1, %2}
6805 imul{l}\t{%2, %1, %0|%0, %1, %2}
6806 imul{l}\t{%2, %0|%0, %2}"
6807 [(set_attr "type" "imul")
6808 (set_attr "prefix_0f" "0,0,1")
6809 (set (attr "athlon_decode")
6810 (cond [(eq_attr "cpu" "athlon")
6811 (const_string "vector")
6812 (eq_attr "alternative" "1")
6813 (const_string "vector")
6814 (and (eq_attr "alternative" "2")
6815 (match_operand 1 "memory_operand" ""))
6816 (const_string "vector")]
6817 (const_string "direct")))
6818 (set_attr "mode" "SI")])
6819
6820 (define_insn "*mulsi3_1_zext"
6821 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6822 (zero_extend:DI
6823 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6824 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6825 (clobber (reg:CC 17))]
6826 "TARGET_64BIT
6827 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6828 "@
6829 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6830 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6831 imul{l}\t{%2, %k0|%k0, %2}"
6832 [(set_attr "type" "imul")
6833 (set_attr "prefix_0f" "0,0,1")
6834 (set (attr "athlon_decode")
6835 (cond [(eq_attr "cpu" "athlon")
6836 (const_string "vector")
6837 (eq_attr "alternative" "1")
6838 (const_string "vector")
6839 (and (eq_attr "alternative" "2")
6840 (match_operand 1 "memory_operand" ""))
6841 (const_string "vector")]
6842 (const_string "direct")))
6843 (set_attr "mode" "SI")])
6844
6845 (define_expand "mulhi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6847 (mult:HI (match_operand:HI 1 "register_operand" "")
6848 (match_operand:HI 2 "general_operand" "")))
6849 (clobber (reg:CC 17))])]
6850 "TARGET_HIMODE_MATH"
6851 "")
6852
6853 (define_insn "*mulhi3_1"
6854 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6855 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6856 (match_operand:HI 2 "general_operand" "K,i,mr")))
6857 (clobber (reg:CC 17))]
6858 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6859 "@
6860 imul{w}\t{%2, %1, %0|%0, %1, %2}
6861 imul{w}\t{%2, %1, %0|%0, %1, %2}
6862 imul{w}\t{%2, %0|%0, %2}"
6863 [(set_attr "type" "imul")
6864 (set_attr "prefix_0f" "0,0,1")
6865 (set (attr "athlon_decode")
6866 (cond [(eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (eq_attr "alternative" "1,2")
6869 (const_string "vector")]
6870 (const_string "direct")))
6871 (set_attr "mode" "HI")])
6872
6873 (define_expand "mulqi3"
6874 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6875 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6876 (match_operand:QI 2 "register_operand" "")))
6877 (clobber (reg:CC 17))])]
6878 "TARGET_QIMODE_MATH"
6879 "")
6880
6881 (define_insn "*mulqi3_1"
6882 [(set (match_operand:QI 0 "register_operand" "=a")
6883 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6884 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6885 (clobber (reg:CC 17))]
6886 "TARGET_QIMODE_MATH
6887 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6888 "mul{b}\t%2"
6889 [(set_attr "type" "imul")
6890 (set_attr "length_immediate" "0")
6891 (set (attr "athlon_decode")
6892 (if_then_else (eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (const_string "direct")))
6895 (set_attr "mode" "QI")])
6896
6897 (define_expand "umulqihi3"
6898 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6899 (mult:HI (zero_extend:HI
6900 (match_operand:QI 1 "nonimmediate_operand" ""))
6901 (zero_extend:HI
6902 (match_operand:QI 2 "register_operand" ""))))
6903 (clobber (reg:CC 17))])]
6904 "TARGET_QIMODE_MATH"
6905 "")
6906
6907 (define_insn "*umulqihi3_1"
6908 [(set (match_operand:HI 0 "register_operand" "=a")
6909 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6910 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6911 (clobber (reg:CC 17))]
6912 "TARGET_QIMODE_MATH
6913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6914 "mul{b}\t%2"
6915 [(set_attr "type" "imul")
6916 (set_attr "length_immediate" "0")
6917 (set (attr "athlon_decode")
6918 (if_then_else (eq_attr "cpu" "athlon")
6919 (const_string "vector")
6920 (const_string "direct")))
6921 (set_attr "mode" "QI")])
6922
6923 (define_expand "mulqihi3"
6924 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6925 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6926 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6927 (clobber (reg:CC 17))])]
6928 "TARGET_QIMODE_MATH"
6929 "")
6930
6931 (define_insn "*mulqihi3_insn"
6932 [(set (match_operand:HI 0 "register_operand" "=a")
6933 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6934 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6935 (clobber (reg:CC 17))]
6936 "TARGET_QIMODE_MATH
6937 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6938 "imul{b}\t%2"
6939 [(set_attr "type" "imul")
6940 (set_attr "length_immediate" "0")
6941 (set (attr "athlon_decode")
6942 (if_then_else (eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (const_string "direct")))
6945 (set_attr "mode" "QI")])
6946
6947 (define_expand "umulditi3"
6948 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6949 (mult:TI (zero_extend:TI
6950 (match_operand:DI 1 "nonimmediate_operand" ""))
6951 (zero_extend:TI
6952 (match_operand:DI 2 "register_operand" ""))))
6953 (clobber (reg:CC 17))])]
6954 "TARGET_64BIT"
6955 "")
6956
6957 (define_insn "*umulditi3_insn"
6958 [(set (match_operand:TI 0 "register_operand" "=A")
6959 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6960 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6961 (clobber (reg:CC 17))]
6962 "TARGET_64BIT
6963 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6964 "mul{q}\t%2"
6965 [(set_attr "type" "imul")
6966 (set_attr "ppro_uops" "few")
6967 (set_attr "length_immediate" "0")
6968 (set (attr "athlon_decode")
6969 (if_then_else (eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (const_string "double")))
6972 (set_attr "mode" "DI")])
6973
6974 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6975 (define_expand "umulsidi3"
6976 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6977 (mult:DI (zero_extend:DI
6978 (match_operand:SI 1 "nonimmediate_operand" ""))
6979 (zero_extend:DI
6980 (match_operand:SI 2 "register_operand" ""))))
6981 (clobber (reg:CC 17))])]
6982 "!TARGET_64BIT"
6983 "")
6984
6985 (define_insn "*umulsidi3_insn"
6986 [(set (match_operand:DI 0 "register_operand" "=A")
6987 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6988 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6989 (clobber (reg:CC 17))]
6990 "!TARGET_64BIT
6991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6992 "mul{l}\t%2"
6993 [(set_attr "type" "imul")
6994 (set_attr "ppro_uops" "few")
6995 (set_attr "length_immediate" "0")
6996 (set (attr "athlon_decode")
6997 (if_then_else (eq_attr "cpu" "athlon")
6998 (const_string "vector")
6999 (const_string "double")))
7000 (set_attr "mode" "SI")])
7001
7002 (define_expand "mulditi3"
7003 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7004 (mult:TI (sign_extend:TI
7005 (match_operand:DI 1 "nonimmediate_operand" ""))
7006 (sign_extend:TI
7007 (match_operand:DI 2 "register_operand" ""))))
7008 (clobber (reg:CC 17))])]
7009 "TARGET_64BIT"
7010 "")
7011
7012 (define_insn "*mulditi3_insn"
7013 [(set (match_operand:TI 0 "register_operand" "=A")
7014 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7015 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7016 (clobber (reg:CC 17))]
7017 "TARGET_64BIT
7018 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7019 "imul{q}\t%2"
7020 [(set_attr "type" "imul")
7021 (set_attr "length_immediate" "0")
7022 (set (attr "athlon_decode")
7023 (if_then_else (eq_attr "cpu" "athlon")
7024 (const_string "vector")
7025 (const_string "double")))
7026 (set_attr "mode" "DI")])
7027
7028 (define_expand "mulsidi3"
7029 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7030 (mult:DI (sign_extend:DI
7031 (match_operand:SI 1 "nonimmediate_operand" ""))
7032 (sign_extend:DI
7033 (match_operand:SI 2 "register_operand" ""))))
7034 (clobber (reg:CC 17))])]
7035 "!TARGET_64BIT"
7036 "")
7037
7038 (define_insn "*mulsidi3_insn"
7039 [(set (match_operand:DI 0 "register_operand" "=A")
7040 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7041 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7042 (clobber (reg:CC 17))]
7043 "!TARGET_64BIT
7044 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7045 "imul{l}\t%2"
7046 [(set_attr "type" "imul")
7047 (set_attr "length_immediate" "0")
7048 (set (attr "athlon_decode")
7049 (if_then_else (eq_attr "cpu" "athlon")
7050 (const_string "vector")
7051 (const_string "double")))
7052 (set_attr "mode" "SI")])
7053
7054 (define_expand "umuldi3_highpart"
7055 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7056 (truncate:DI
7057 (lshiftrt:TI
7058 (mult:TI (zero_extend:TI
7059 (match_operand:DI 1 "nonimmediate_operand" ""))
7060 (zero_extend:TI
7061 (match_operand:DI 2 "register_operand" "")))
7062 (const_int 64))))
7063 (clobber (match_scratch:DI 3 ""))
7064 (clobber (reg:CC 17))])]
7065 "TARGET_64BIT"
7066 "")
7067
7068 (define_insn "*umuldi3_highpart_rex64"
7069 [(set (match_operand:DI 0 "register_operand" "=d")
7070 (truncate:DI
7071 (lshiftrt:TI
7072 (mult:TI (zero_extend:TI
7073 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7074 (zero_extend:TI
7075 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7076 (const_int 64))))
7077 (clobber (match_scratch:DI 3 "=1"))
7078 (clobber (reg:CC 17))]
7079 "TARGET_64BIT
7080 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7081 "mul{q}\t%2"
7082 [(set_attr "type" "imul")
7083 (set_attr "ppro_uops" "few")
7084 (set_attr "length_immediate" "0")
7085 (set (attr "athlon_decode")
7086 (if_then_else (eq_attr "cpu" "athlon")
7087 (const_string "vector")
7088 (const_string "double")))
7089 (set_attr "mode" "DI")])
7090
7091 (define_expand "umulsi3_highpart"
7092 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7093 (truncate:SI
7094 (lshiftrt:DI
7095 (mult:DI (zero_extend:DI
7096 (match_operand:SI 1 "nonimmediate_operand" ""))
7097 (zero_extend:DI
7098 (match_operand:SI 2 "register_operand" "")))
7099 (const_int 32))))
7100 (clobber (match_scratch:SI 3 ""))
7101 (clobber (reg:CC 17))])]
7102 ""
7103 "")
7104
7105 (define_insn "*umulsi3_highpart_insn"
7106 [(set (match_operand:SI 0 "register_operand" "=d")
7107 (truncate:SI
7108 (lshiftrt:DI
7109 (mult:DI (zero_extend:DI
7110 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7111 (zero_extend:DI
7112 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7113 (const_int 32))))
7114 (clobber (match_scratch:SI 3 "=1"))
7115 (clobber (reg:CC 17))]
7116 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7117 "mul{l}\t%2"
7118 [(set_attr "type" "imul")
7119 (set_attr "ppro_uops" "few")
7120 (set_attr "length_immediate" "0")
7121 (set (attr "athlon_decode")
7122 (if_then_else (eq_attr "cpu" "athlon")
7123 (const_string "vector")
7124 (const_string "double")))
7125 (set_attr "mode" "SI")])
7126
7127 (define_insn "*umulsi3_highpart_zext"
7128 [(set (match_operand:DI 0 "register_operand" "=d")
7129 (zero_extend:DI (truncate:SI
7130 (lshiftrt:DI
7131 (mult:DI (zero_extend:DI
7132 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7133 (zero_extend:DI
7134 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7135 (const_int 32)))))
7136 (clobber (match_scratch:SI 3 "=1"))
7137 (clobber (reg:CC 17))]
7138 "TARGET_64BIT
7139 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7140 "mul{l}\t%2"
7141 [(set_attr "type" "imul")
7142 (set_attr "ppro_uops" "few")
7143 (set_attr "length_immediate" "0")
7144 (set (attr "athlon_decode")
7145 (if_then_else (eq_attr "cpu" "athlon")
7146 (const_string "vector")
7147 (const_string "double")))
7148 (set_attr "mode" "SI")])
7149
7150 (define_expand "smuldi3_highpart"
7151 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7152 (truncate:DI
7153 (lshiftrt:TI
7154 (mult:TI (sign_extend:TI
7155 (match_operand:DI 1 "nonimmediate_operand" ""))
7156 (sign_extend:TI
7157 (match_operand:DI 2 "register_operand" "")))
7158 (const_int 64))))
7159 (clobber (match_scratch:DI 3 ""))
7160 (clobber (reg:CC 17))])]
7161 "TARGET_64BIT"
7162 "")
7163
7164 (define_insn "*smuldi3_highpart_rex64"
7165 [(set (match_operand:DI 0 "register_operand" "=d")
7166 (truncate:DI
7167 (lshiftrt:TI
7168 (mult:TI (sign_extend:TI
7169 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7170 (sign_extend:TI
7171 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7172 (const_int 64))))
7173 (clobber (match_scratch:DI 3 "=1"))
7174 (clobber (reg:CC 17))]
7175 "TARGET_64BIT
7176 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7177 "imul{q}\t%2"
7178 [(set_attr "type" "imul")
7179 (set_attr "ppro_uops" "few")
7180 (set (attr "athlon_decode")
7181 (if_then_else (eq_attr "cpu" "athlon")
7182 (const_string "vector")
7183 (const_string "double")))
7184 (set_attr "mode" "DI")])
7185
7186 (define_expand "smulsi3_highpart"
7187 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7188 (truncate:SI
7189 (lshiftrt:DI
7190 (mult:DI (sign_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" ""))
7192 (sign_extend:DI
7193 (match_operand:SI 2 "register_operand" "")))
7194 (const_int 32))))
7195 (clobber (match_scratch:SI 3 ""))
7196 (clobber (reg:CC 17))])]
7197 ""
7198 "")
7199
7200 (define_insn "*smulsi3_highpart_insn"
7201 [(set (match_operand:SI 0 "register_operand" "=d")
7202 (truncate:SI
7203 (lshiftrt:DI
7204 (mult:DI (sign_extend:DI
7205 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7206 (sign_extend:DI
7207 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7208 (const_int 32))))
7209 (clobber (match_scratch:SI 3 "=1"))
7210 (clobber (reg:CC 17))]
7211 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7212 "imul{l}\t%2"
7213 [(set_attr "type" "imul")
7214 (set_attr "ppro_uops" "few")
7215 (set (attr "athlon_decode")
7216 (if_then_else (eq_attr "cpu" "athlon")
7217 (const_string "vector")
7218 (const_string "double")))
7219 (set_attr "mode" "SI")])
7220
7221 (define_insn "*smulsi3_highpart_zext"
7222 [(set (match_operand:DI 0 "register_operand" "=d")
7223 (zero_extend:DI (truncate:SI
7224 (lshiftrt:DI
7225 (mult:DI (sign_extend:DI
7226 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7227 (sign_extend:DI
7228 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7229 (const_int 32)))))
7230 (clobber (match_scratch:SI 3 "=1"))
7231 (clobber (reg:CC 17))]
7232 "TARGET_64BIT
7233 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234 "imul{l}\t%2"
7235 [(set_attr "type" "imul")
7236 (set_attr "ppro_uops" "few")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "SI")])
7242
7243 ;; The patterns that match these are at the end of this file.
7244
7245 (define_expand "mulxf3"
7246 [(set (match_operand:XF 0 "register_operand" "")
7247 (mult:XF (match_operand:XF 1 "register_operand" "")
7248 (match_operand:XF 2 "register_operand" "")))]
7249 "TARGET_80387"
7250 "")
7251
7252 (define_expand "muldf3"
7253 [(set (match_operand:DF 0 "register_operand" "")
7254 (mult:DF (match_operand:DF 1 "register_operand" "")
7255 (match_operand:DF 2 "nonimmediate_operand" "")))]
7256 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7257 "")
7258
7259 (define_expand "mulsf3"
7260 [(set (match_operand:SF 0 "register_operand" "")
7261 (mult:SF (match_operand:SF 1 "register_operand" "")
7262 (match_operand:SF 2 "nonimmediate_operand" "")))]
7263 "TARGET_80387 || TARGET_SSE_MATH"
7264 "")
7265 \f
7266 ;; Divide instructions
7267
7268 (define_insn "divqi3"
7269 [(set (match_operand:QI 0 "register_operand" "=a")
7270 (div:QI (match_operand:HI 1 "register_operand" "0")
7271 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7272 (clobber (reg:CC 17))]
7273 "TARGET_QIMODE_MATH"
7274 "idiv{b}\t%2"
7275 [(set_attr "type" "idiv")
7276 (set_attr "mode" "QI")
7277 (set_attr "ppro_uops" "few")])
7278
7279 (define_insn "udivqi3"
7280 [(set (match_operand:QI 0 "register_operand" "=a")
7281 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7282 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7283 (clobber (reg:CC 17))]
7284 "TARGET_QIMODE_MATH"
7285 "div{b}\t%2"
7286 [(set_attr "type" "idiv")
7287 (set_attr "mode" "QI")
7288 (set_attr "ppro_uops" "few")])
7289
7290 ;; The patterns that match these are at the end of this file.
7291
7292 (define_expand "divxf3"
7293 [(set (match_operand:XF 0 "register_operand" "")
7294 (div:XF (match_operand:XF 1 "register_operand" "")
7295 (match_operand:XF 2 "register_operand" "")))]
7296 "TARGET_80387"
7297 "")
7298
7299 (define_expand "divdf3"
7300 [(set (match_operand:DF 0 "register_operand" "")
7301 (div:DF (match_operand:DF 1 "register_operand" "")
7302 (match_operand:DF 2 "nonimmediate_operand" "")))]
7303 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7304 "")
7305
7306 (define_expand "divsf3"
7307 [(set (match_operand:SF 0 "register_operand" "")
7308 (div:SF (match_operand:SF 1 "register_operand" "")
7309 (match_operand:SF 2 "nonimmediate_operand" "")))]
7310 "TARGET_80387 || TARGET_SSE_MATH"
7311 "")
7312 \f
7313 ;; Remainder instructions.
7314
7315 (define_expand "divmoddi4"
7316 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7317 (div:DI (match_operand:DI 1 "register_operand" "")
7318 (match_operand:DI 2 "nonimmediate_operand" "")))
7319 (set (match_operand:DI 3 "register_operand" "")
7320 (mod:DI (match_dup 1) (match_dup 2)))
7321 (clobber (reg:CC 17))])]
7322 "TARGET_64BIT"
7323 "")
7324
7325 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7326 ;; Penalize eax case slightly because it results in worse scheduling
7327 ;; of code.
7328 (define_insn "*divmoddi4_nocltd_rex64"
7329 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7330 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7331 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7332 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7333 (mod:DI (match_dup 2) (match_dup 3)))
7334 (clobber (reg:CC 17))]
7335 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7336 "#"
7337 [(set_attr "type" "multi")])
7338
7339 (define_insn "*divmoddi4_cltd_rex64"
7340 [(set (match_operand:DI 0 "register_operand" "=a")
7341 (div:DI (match_operand:DI 2 "register_operand" "a")
7342 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7343 (set (match_operand:DI 1 "register_operand" "=&d")
7344 (mod:DI (match_dup 2) (match_dup 3)))
7345 (clobber (reg:CC 17))]
7346 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7347 "#"
7348 [(set_attr "type" "multi")])
7349
7350 (define_insn "*divmoddi_noext_rex64"
7351 [(set (match_operand:DI 0 "register_operand" "=a")
7352 (div:DI (match_operand:DI 1 "register_operand" "0")
7353 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7354 (set (match_operand:DI 3 "register_operand" "=d")
7355 (mod:DI (match_dup 1) (match_dup 2)))
7356 (use (match_operand:DI 4 "register_operand" "3"))
7357 (clobber (reg:CC 17))]
7358 "TARGET_64BIT"
7359 "idiv{q}\t%2"
7360 [(set_attr "type" "idiv")
7361 (set_attr "mode" "DI")
7362 (set_attr "ppro_uops" "few")])
7363
7364 (define_split
7365 [(set (match_operand:DI 0 "register_operand" "")
7366 (div:DI (match_operand:DI 1 "register_operand" "")
7367 (match_operand:DI 2 "nonimmediate_operand" "")))
7368 (set (match_operand:DI 3 "register_operand" "")
7369 (mod:DI (match_dup 1) (match_dup 2)))
7370 (clobber (reg:CC 17))]
7371 "TARGET_64BIT && reload_completed"
7372 [(parallel [(set (match_dup 3)
7373 (ashiftrt:DI (match_dup 4) (const_int 63)))
7374 (clobber (reg:CC 17))])
7375 (parallel [(set (match_dup 0)
7376 (div:DI (reg:DI 0) (match_dup 2)))
7377 (set (match_dup 3)
7378 (mod:DI (reg:DI 0) (match_dup 2)))
7379 (use (match_dup 3))
7380 (clobber (reg:CC 17))])]
7381 {
7382 /* Avoid use of cltd in favor of a mov+shift. */
7383 if (!TARGET_USE_CLTD && !optimize_size)
7384 {
7385 if (true_regnum (operands[1]))
7386 emit_move_insn (operands[0], operands[1]);
7387 else
7388 emit_move_insn (operands[3], operands[1]);
7389 operands[4] = operands[3];
7390 }
7391 else
7392 {
7393 if (true_regnum (operands[1]))
7394 abort();
7395 operands[4] = operands[1];
7396 }
7397 })
7398
7399
7400 (define_expand "divmodsi4"
7401 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7402 (div:SI (match_operand:SI 1 "register_operand" "")
7403 (match_operand:SI 2 "nonimmediate_operand" "")))
7404 (set (match_operand:SI 3 "register_operand" "")
7405 (mod:SI (match_dup 1) (match_dup 2)))
7406 (clobber (reg:CC 17))])]
7407 ""
7408 "")
7409
7410 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7411 ;; Penalize eax case slightly because it results in worse scheduling
7412 ;; of code.
7413 (define_insn "*divmodsi4_nocltd"
7414 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7415 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7416 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7417 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7418 (mod:SI (match_dup 2) (match_dup 3)))
7419 (clobber (reg:CC 17))]
7420 "!optimize_size && !TARGET_USE_CLTD"
7421 "#"
7422 [(set_attr "type" "multi")])
7423
7424 (define_insn "*divmodsi4_cltd"
7425 [(set (match_operand:SI 0 "register_operand" "=a")
7426 (div:SI (match_operand:SI 2 "register_operand" "a")
7427 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7428 (set (match_operand:SI 1 "register_operand" "=&d")
7429 (mod:SI (match_dup 2) (match_dup 3)))
7430 (clobber (reg:CC 17))]
7431 "optimize_size || TARGET_USE_CLTD"
7432 "#"
7433 [(set_attr "type" "multi")])
7434
7435 (define_insn "*divmodsi_noext"
7436 [(set (match_operand:SI 0 "register_operand" "=a")
7437 (div:SI (match_operand:SI 1 "register_operand" "0")
7438 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7439 (set (match_operand:SI 3 "register_operand" "=d")
7440 (mod:SI (match_dup 1) (match_dup 2)))
7441 (use (match_operand:SI 4 "register_operand" "3"))
7442 (clobber (reg:CC 17))]
7443 ""
7444 "idiv{l}\t%2"
7445 [(set_attr "type" "idiv")
7446 (set_attr "mode" "SI")
7447 (set_attr "ppro_uops" "few")])
7448
7449 (define_split
7450 [(set (match_operand:SI 0 "register_operand" "")
7451 (div:SI (match_operand:SI 1 "register_operand" "")
7452 (match_operand:SI 2 "nonimmediate_operand" "")))
7453 (set (match_operand:SI 3 "register_operand" "")
7454 (mod:SI (match_dup 1) (match_dup 2)))
7455 (clobber (reg:CC 17))]
7456 "reload_completed"
7457 [(parallel [(set (match_dup 3)
7458 (ashiftrt:SI (match_dup 4) (const_int 31)))
7459 (clobber (reg:CC 17))])
7460 (parallel [(set (match_dup 0)
7461 (div:SI (reg:SI 0) (match_dup 2)))
7462 (set (match_dup 3)
7463 (mod:SI (reg:SI 0) (match_dup 2)))
7464 (use (match_dup 3))
7465 (clobber (reg:CC 17))])]
7466 {
7467 /* Avoid use of cltd in favor of a mov+shift. */
7468 if (!TARGET_USE_CLTD && !optimize_size)
7469 {
7470 if (true_regnum (operands[1]))
7471 emit_move_insn (operands[0], operands[1]);
7472 else
7473 emit_move_insn (operands[3], operands[1]);
7474 operands[4] = operands[3];
7475 }
7476 else
7477 {
7478 if (true_regnum (operands[1]))
7479 abort();
7480 operands[4] = operands[1];
7481 }
7482 })
7483 ;; %%% Split me.
7484 (define_insn "divmodhi4"
7485 [(set (match_operand:HI 0 "register_operand" "=a")
7486 (div:HI (match_operand:HI 1 "register_operand" "0")
7487 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7488 (set (match_operand:HI 3 "register_operand" "=&d")
7489 (mod:HI (match_dup 1) (match_dup 2)))
7490 (clobber (reg:CC 17))]
7491 "TARGET_HIMODE_MATH"
7492 "cwtd\;idiv{w}\t%2"
7493 [(set_attr "type" "multi")
7494 (set_attr "length_immediate" "0")
7495 (set_attr "mode" "SI")])
7496
7497 (define_insn "udivmoddi4"
7498 [(set (match_operand:DI 0 "register_operand" "=a")
7499 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7500 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7501 (set (match_operand:DI 3 "register_operand" "=&d")
7502 (umod:DI (match_dup 1) (match_dup 2)))
7503 (clobber (reg:CC 17))]
7504 "TARGET_64BIT"
7505 "xor{q}\t%3, %3\;div{q}\t%2"
7506 [(set_attr "type" "multi")
7507 (set_attr "length_immediate" "0")
7508 (set_attr "mode" "DI")])
7509
7510 (define_insn "*udivmoddi4_noext"
7511 [(set (match_operand:DI 0 "register_operand" "=a")
7512 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7513 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7514 (set (match_operand:DI 3 "register_operand" "=d")
7515 (umod:DI (match_dup 1) (match_dup 2)))
7516 (use (match_dup 3))
7517 (clobber (reg:CC 17))]
7518 "TARGET_64BIT"
7519 "div{q}\t%2"
7520 [(set_attr "type" "idiv")
7521 (set_attr "ppro_uops" "few")
7522 (set_attr "mode" "DI")])
7523
7524 (define_split
7525 [(set (match_operand:DI 0 "register_operand" "")
7526 (udiv:DI (match_operand:DI 1 "register_operand" "")
7527 (match_operand:DI 2 "nonimmediate_operand" "")))
7528 (set (match_operand:DI 3 "register_operand" "")
7529 (umod:DI (match_dup 1) (match_dup 2)))
7530 (clobber (reg:CC 17))]
7531 "TARGET_64BIT && reload_completed"
7532 [(set (match_dup 3) (const_int 0))
7533 (parallel [(set (match_dup 0)
7534 (udiv:DI (match_dup 1) (match_dup 2)))
7535 (set (match_dup 3)
7536 (umod:DI (match_dup 1) (match_dup 2)))
7537 (use (match_dup 3))
7538 (clobber (reg:CC 17))])]
7539 "")
7540
7541 (define_insn "udivmodsi4"
7542 [(set (match_operand:SI 0 "register_operand" "=a")
7543 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7544 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7545 (set (match_operand:SI 3 "register_operand" "=&d")
7546 (umod:SI (match_dup 1) (match_dup 2)))
7547 (clobber (reg:CC 17))]
7548 ""
7549 "xor{l}\t%3, %3\;div{l}\t%2"
7550 [(set_attr "type" "multi")
7551 (set_attr "length_immediate" "0")
7552 (set_attr "mode" "SI")])
7553
7554 (define_insn "*udivmodsi4_noext"
7555 [(set (match_operand:SI 0 "register_operand" "=a")
7556 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7557 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7558 (set (match_operand:SI 3 "register_operand" "=d")
7559 (umod:SI (match_dup 1) (match_dup 2)))
7560 (use (match_dup 3))
7561 (clobber (reg:CC 17))]
7562 ""
7563 "div{l}\t%2"
7564 [(set_attr "type" "idiv")
7565 (set_attr "ppro_uops" "few")
7566 (set_attr "mode" "SI")])
7567
7568 (define_split
7569 [(set (match_operand:SI 0 "register_operand" "")
7570 (udiv:SI (match_operand:SI 1 "register_operand" "")
7571 (match_operand:SI 2 "nonimmediate_operand" "")))
7572 (set (match_operand:SI 3 "register_operand" "")
7573 (umod:SI (match_dup 1) (match_dup 2)))
7574 (clobber (reg:CC 17))]
7575 "reload_completed"
7576 [(set (match_dup 3) (const_int 0))
7577 (parallel [(set (match_dup 0)
7578 (udiv:SI (match_dup 1) (match_dup 2)))
7579 (set (match_dup 3)
7580 (umod:SI (match_dup 1) (match_dup 2)))
7581 (use (match_dup 3))
7582 (clobber (reg:CC 17))])]
7583 "")
7584
7585 (define_expand "udivmodhi4"
7586 [(set (match_dup 4) (const_int 0))
7587 (parallel [(set (match_operand:HI 0 "register_operand" "")
7588 (udiv:HI (match_operand:HI 1 "register_operand" "")
7589 (match_operand:HI 2 "nonimmediate_operand" "")))
7590 (set (match_operand:HI 3 "register_operand" "")
7591 (umod:HI (match_dup 1) (match_dup 2)))
7592 (use (match_dup 4))
7593 (clobber (reg:CC 17))])]
7594 "TARGET_HIMODE_MATH"
7595 "operands[4] = gen_reg_rtx (HImode);")
7596
7597 (define_insn "*udivmodhi_noext"
7598 [(set (match_operand:HI 0 "register_operand" "=a")
7599 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7600 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7601 (set (match_operand:HI 3 "register_operand" "=d")
7602 (umod:HI (match_dup 1) (match_dup 2)))
7603 (use (match_operand:HI 4 "register_operand" "3"))
7604 (clobber (reg:CC 17))]
7605 ""
7606 "div{w}\t%2"
7607 [(set_attr "type" "idiv")
7608 (set_attr "mode" "HI")
7609 (set_attr "ppro_uops" "few")])
7610
7611 ;; We can not use div/idiv for double division, because it causes
7612 ;; "division by zero" on the overflow and that's not what we expect
7613 ;; from truncate. Because true (non truncating) double division is
7614 ;; never generated, we can't create this insn anyway.
7615 ;
7616 ;(define_insn ""
7617 ; [(set (match_operand:SI 0 "register_operand" "=a")
7618 ; (truncate:SI
7619 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7620 ; (zero_extend:DI
7621 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7622 ; (set (match_operand:SI 3 "register_operand" "=d")
7623 ; (truncate:SI
7624 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7625 ; (clobber (reg:CC 17))]
7626 ; ""
7627 ; "div{l}\t{%2, %0|%0, %2}"
7628 ; [(set_attr "type" "idiv")
7629 ; (set_attr "ppro_uops" "few")])
7630 \f
7631 ;;- Logical AND instructions
7632
7633 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7634 ;; Note that this excludes ah.
7635
7636 (define_insn "*testdi_1_rex64"
7637 [(set (reg 17)
7638 (compare
7639 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7640 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7641 (const_int 0)))]
7642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7643 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7644 "@
7645 test{l}\t{%k1, %k0|%k0, %k1}
7646 test{l}\t{%k1, %k0|%k0, %k1}
7647 test{q}\t{%1, %0|%0, %1}
7648 test{q}\t{%1, %0|%0, %1}
7649 test{q}\t{%1, %0|%0, %1}"
7650 [(set_attr "type" "test")
7651 (set_attr "modrm" "0,1,0,1,1")
7652 (set_attr "mode" "SI,SI,DI,DI,DI")
7653 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7654
7655 (define_insn "testsi_1"
7656 [(set (reg 17)
7657 (compare
7658 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7659 (match_operand:SI 1 "general_operand" "in,in,rin"))
7660 (const_int 0)))]
7661 "ix86_match_ccmode (insn, CCNOmode)
7662 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7663 "test{l}\t{%1, %0|%0, %1}"
7664 [(set_attr "type" "test")
7665 (set_attr "modrm" "0,1,1")
7666 (set_attr "mode" "SI")
7667 (set_attr "pent_pair" "uv,np,uv")])
7668
7669 (define_expand "testsi_ccno_1"
7670 [(set (reg:CCNO 17)
7671 (compare:CCNO
7672 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7673 (match_operand:SI 1 "nonmemory_operand" ""))
7674 (const_int 0)))]
7675 ""
7676 "")
7677
7678 (define_insn "*testhi_1"
7679 [(set (reg 17)
7680 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7681 (match_operand:HI 1 "general_operand" "n,n,rn"))
7682 (const_int 0)))]
7683 "ix86_match_ccmode (insn, CCNOmode)
7684 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7685 "test{w}\t{%1, %0|%0, %1}"
7686 [(set_attr "type" "test")
7687 (set_attr "modrm" "0,1,1")
7688 (set_attr "mode" "HI")
7689 (set_attr "pent_pair" "uv,np,uv")])
7690
7691 (define_expand "testqi_ccz_1"
7692 [(set (reg:CCZ 17)
7693 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7694 (match_operand:QI 1 "nonmemory_operand" ""))
7695 (const_int 0)))]
7696 ""
7697 "")
7698
7699 (define_insn "*testqi_1"
7700 [(set (reg 17)
7701 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7702 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7703 (const_int 0)))]
7704 "ix86_match_ccmode (insn, CCNOmode)
7705 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7706 {
7707 if (which_alternative == 3)
7708 {
7709 if (GET_CODE (operands[1]) == CONST_INT
7710 && (INTVAL (operands[1]) & 0xffffff00))
7711 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7712 return "test{l}\t{%1, %k0|%k0, %1}";
7713 }
7714 return "test{b}\t{%1, %0|%0, %1}";
7715 }
7716 [(set_attr "type" "test")
7717 (set_attr "modrm" "0,1,1,1")
7718 (set_attr "mode" "QI,QI,QI,SI")
7719 (set_attr "pent_pair" "uv,np,uv,np")])
7720
7721 (define_expand "testqi_ext_ccno_0"
7722 [(set (reg:CCNO 17)
7723 (compare:CCNO
7724 (and:SI
7725 (zero_extract:SI
7726 (match_operand 0 "ext_register_operand" "")
7727 (const_int 8)
7728 (const_int 8))
7729 (match_operand 1 "const_int_operand" ""))
7730 (const_int 0)))]
7731 ""
7732 "")
7733
7734 (define_insn "*testqi_ext_0"
7735 [(set (reg 17)
7736 (compare
7737 (and:SI
7738 (zero_extract:SI
7739 (match_operand 0 "ext_register_operand" "Q")
7740 (const_int 8)
7741 (const_int 8))
7742 (match_operand 1 "const_int_operand" "n"))
7743 (const_int 0)))]
7744 "ix86_match_ccmode (insn, CCNOmode)"
7745 "test{b}\t{%1, %h0|%h0, %1}"
7746 [(set_attr "type" "test")
7747 (set_attr "mode" "QI")
7748 (set_attr "length_immediate" "1")
7749 (set_attr "pent_pair" "np")])
7750
7751 (define_insn "*testqi_ext_1"
7752 [(set (reg 17)
7753 (compare
7754 (and:SI
7755 (zero_extract:SI
7756 (match_operand 0 "ext_register_operand" "Q")
7757 (const_int 8)
7758 (const_int 8))
7759 (zero_extend:SI
7760 (match_operand:QI 1 "general_operand" "Qm")))
7761 (const_int 0)))]
7762 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7763 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7764 "test{b}\t{%1, %h0|%h0, %1}"
7765 [(set_attr "type" "test")
7766 (set_attr "mode" "QI")])
7767
7768 (define_insn "*testqi_ext_1_rex64"
7769 [(set (reg 17)
7770 (compare
7771 (and:SI
7772 (zero_extract:SI
7773 (match_operand 0 "ext_register_operand" "Q")
7774 (const_int 8)
7775 (const_int 8))
7776 (zero_extend:SI
7777 (match_operand:QI 1 "register_operand" "Q")))
7778 (const_int 0)))]
7779 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7780 "test{b}\t{%1, %h0|%h0, %1}"
7781 [(set_attr "type" "test")
7782 (set_attr "mode" "QI")])
7783
7784 (define_insn "*testqi_ext_2"
7785 [(set (reg 17)
7786 (compare
7787 (and:SI
7788 (zero_extract:SI
7789 (match_operand 0 "ext_register_operand" "Q")
7790 (const_int 8)
7791 (const_int 8))
7792 (zero_extract:SI
7793 (match_operand 1 "ext_register_operand" "Q")
7794 (const_int 8)
7795 (const_int 8)))
7796 (const_int 0)))]
7797 "ix86_match_ccmode (insn, CCNOmode)"
7798 "test{b}\t{%h1, %h0|%h0, %h1}"
7799 [(set_attr "type" "test")
7800 (set_attr "mode" "QI")])
7801
7802 ;; Combine likes to form bit extractions for some tests. Humor it.
7803 (define_insn "*testqi_ext_3"
7804 [(set (reg 17)
7805 (compare (zero_extract:SI
7806 (match_operand 0 "nonimmediate_operand" "rm")
7807 (match_operand:SI 1 "const_int_operand" "")
7808 (match_operand:SI 2 "const_int_operand" ""))
7809 (const_int 0)))]
7810 "ix86_match_ccmode (insn, CCNOmode)
7811 && (GET_MODE (operands[0]) == SImode
7812 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7813 || GET_MODE (operands[0]) == HImode
7814 || GET_MODE (operands[0]) == QImode)"
7815 "#")
7816
7817 (define_insn "*testqi_ext_3_rex64"
7818 [(set (reg 17)
7819 (compare (zero_extract:DI
7820 (match_operand 0 "nonimmediate_operand" "rm")
7821 (match_operand:DI 1 "const_int_operand" "")
7822 (match_operand:DI 2 "const_int_operand" ""))
7823 (const_int 0)))]
7824 "TARGET_64BIT
7825 && ix86_match_ccmode (insn, CCNOmode)
7826 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7827 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7828 /* Ensure that resulting mask is zero or sign extended operand. */
7829 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7830 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7831 && INTVAL (operands[1]) > 32))
7832 && (GET_MODE (operands[0]) == SImode
7833 || GET_MODE (operands[0]) == DImode
7834 || GET_MODE (operands[0]) == HImode
7835 || GET_MODE (operands[0]) == QImode)"
7836 "#")
7837
7838 (define_split
7839 [(set (reg 17)
7840 (compare (zero_extract
7841 (match_operand 0 "nonimmediate_operand" "")
7842 (match_operand 1 "const_int_operand" "")
7843 (match_operand 2 "const_int_operand" ""))
7844 (const_int 0)))]
7845 "ix86_match_ccmode (insn, CCNOmode)"
7846 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
7847 {
7848 HOST_WIDE_INT len = INTVAL (operands[1]);
7849 HOST_WIDE_INT pos = INTVAL (operands[2]);
7850 HOST_WIDE_INT mask;
7851 enum machine_mode mode, submode;
7852
7853 mode = GET_MODE (operands[0]);
7854 if (GET_CODE (operands[0]) == MEM)
7855 {
7856 /* ??? Combine likes to put non-volatile mem extractions in QImode
7857 no matter the size of the test. So find a mode that works. */
7858 if (! MEM_VOLATILE_P (operands[0]))
7859 {
7860 mode = smallest_mode_for_size (pos + len, MODE_INT);
7861 operands[0] = adjust_address (operands[0], mode, 0);
7862 }
7863 }
7864 else if (GET_CODE (operands[0]) == SUBREG
7865 && (submode = GET_MODE (SUBREG_REG (operands[0])),
7866 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7867 && pos + len <= GET_MODE_BITSIZE (submode))
7868 {
7869 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7870 mode = submode;
7871 operands[0] = SUBREG_REG (operands[0]);
7872 }
7873 else if (mode == HImode && pos + len <= 8)
7874 {
7875 /* Small HImode tests can be converted to QImode. */
7876 mode = QImode;
7877 operands[0] = gen_lowpart (QImode, operands[0]);
7878 }
7879
7880 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7881 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7882
7883 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
7884 })
7885
7886 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7887 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7888 ;; this is relatively important trick.
7889 ;; Do the conversion only post-reload to avoid limiting of the register class
7890 ;; to QI regs.
7891 (define_split
7892 [(set (reg 17)
7893 (compare
7894 (and (match_operand 0 "register_operand" "")
7895 (match_operand 1 "const_int_operand" ""))
7896 (const_int 0)))]
7897 "reload_completed
7898 && QI_REG_P (operands[0])
7899 && ((ix86_match_ccmode (insn, CCZmode)
7900 && !(INTVAL (operands[1]) & ~(255 << 8)))
7901 || (ix86_match_ccmode (insn, CCNOmode)
7902 && !(INTVAL (operands[1]) & ~(127 << 8))))
7903 && GET_MODE (operands[0]) != QImode"
7904 [(set (reg:CCNO 17)
7905 (compare:CCNO
7906 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7907 (match_dup 1))
7908 (const_int 0)))]
7909 "operands[0] = gen_lowpart (SImode, operands[0]);
7910 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
7911
7912 (define_split
7913 [(set (reg 17)
7914 (compare
7915 (and (match_operand 0 "nonimmediate_operand" "")
7916 (match_operand 1 "const_int_operand" ""))
7917 (const_int 0)))]
7918 "reload_completed
7919 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
7920 && ((ix86_match_ccmode (insn, CCZmode)
7921 && !(INTVAL (operands[1]) & ~255))
7922 || (ix86_match_ccmode (insn, CCNOmode)
7923 && !(INTVAL (operands[1]) & ~127)))
7924 && GET_MODE (operands[0]) != QImode"
7925 [(set (reg:CCNO 17)
7926 (compare:CCNO
7927 (and:QI (match_dup 0)
7928 (match_dup 1))
7929 (const_int 0)))]
7930 "operands[0] = gen_lowpart (QImode, operands[0]);
7931 operands[1] = gen_lowpart (QImode, operands[1]);")
7932
7933
7934 ;; %%% This used to optimize known byte-wide and operations to memory,
7935 ;; and sometimes to QImode registers. If this is considered useful,
7936 ;; it should be done with splitters.
7937
7938 (define_expand "anddi3"
7939 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7940 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7941 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7942 (clobber (reg:CC 17))]
7943 "TARGET_64BIT"
7944 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7945
7946 (define_insn "*anddi_1_rex64"
7947 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7948 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7949 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7950 (clobber (reg:CC 17))]
7951 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7952 {
7953 switch (get_attr_type (insn))
7954 {
7955 case TYPE_IMOVX:
7956 {
7957 enum machine_mode mode;
7958
7959 if (GET_CODE (operands[2]) != CONST_INT)
7960 abort ();
7961 if (INTVAL (operands[2]) == 0xff)
7962 mode = QImode;
7963 else if (INTVAL (operands[2]) == 0xffff)
7964 mode = HImode;
7965 else
7966 abort ();
7967
7968 operands[1] = gen_lowpart (mode, operands[1]);
7969 if (mode == QImode)
7970 return "movz{bq|x}\t{%1,%0|%0, %1}";
7971 else
7972 return "movz{wq|x}\t{%1,%0|%0, %1}";
7973 }
7974
7975 default:
7976 if (! rtx_equal_p (operands[0], operands[1]))
7977 abort ();
7978 if (get_attr_mode (insn) == MODE_SI)
7979 return "and{l}\t{%k2, %k0|%k0, %k2}";
7980 else
7981 return "and{q}\t{%2, %0|%0, %2}";
7982 }
7983 }
7984 [(set_attr "type" "alu,alu,alu,imovx")
7985 (set_attr "length_immediate" "*,*,*,0")
7986 (set_attr "mode" "SI,DI,DI,DI")])
7987
7988 (define_insn "*anddi_2"
7989 [(set (reg 17)
7990 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7991 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7992 (const_int 0)))
7993 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7994 (and:DI (match_dup 1) (match_dup 2)))]
7995 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7996 && ix86_binary_operator_ok (AND, DImode, operands)"
7997 "@
7998 and{l}\t{%k2, %k0|%k0, %k2}
7999 and{q}\t{%2, %0|%0, %2}
8000 and{q}\t{%2, %0|%0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "mode" "SI,DI,DI")])
8003
8004 (define_expand "andsi3"
8005 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8006 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8007 (match_operand:SI 2 "general_operand" "")))
8008 (clobber (reg:CC 17))]
8009 ""
8010 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8011
8012 (define_insn "*andsi_1"
8013 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8014 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8015 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8016 (clobber (reg:CC 17))]
8017 "ix86_binary_operator_ok (AND, SImode, operands)"
8018 {
8019 switch (get_attr_type (insn))
8020 {
8021 case TYPE_IMOVX:
8022 {
8023 enum machine_mode mode;
8024
8025 if (GET_CODE (operands[2]) != CONST_INT)
8026 abort ();
8027 if (INTVAL (operands[2]) == 0xff)
8028 mode = QImode;
8029 else if (INTVAL (operands[2]) == 0xffff)
8030 mode = HImode;
8031 else
8032 abort ();
8033
8034 operands[1] = gen_lowpart (mode, operands[1]);
8035 if (mode == QImode)
8036 return "movz{bl|x}\t{%1,%0|%0, %1}";
8037 else
8038 return "movz{wl|x}\t{%1,%0|%0, %1}";
8039 }
8040
8041 default:
8042 if (! rtx_equal_p (operands[0], operands[1]))
8043 abort ();
8044 return "and{l}\t{%2, %0|%0, %2}";
8045 }
8046 }
8047 [(set_attr "type" "alu,alu,imovx")
8048 (set_attr "length_immediate" "*,*,0")
8049 (set_attr "mode" "SI")])
8050
8051 (define_split
8052 [(set (match_operand 0 "register_operand" "")
8053 (and (match_dup 0)
8054 (const_int -65536)))
8055 (clobber (reg:CC 17))]
8056 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8057 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8058 "operands[1] = gen_lowpart (HImode, operands[0]);")
8059
8060 (define_split
8061 [(set (match_operand 0 "ext_register_operand" "")
8062 (and (match_dup 0)
8063 (const_int -256)))
8064 (clobber (reg:CC 17))]
8065 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8066 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8067 "operands[1] = gen_lowpart (QImode, operands[0]);")
8068
8069 (define_split
8070 [(set (match_operand 0 "ext_register_operand" "")
8071 (and (match_dup 0)
8072 (const_int -65281)))
8073 (clobber (reg:CC 17))]
8074 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8075 [(parallel [(set (zero_extract:SI (match_dup 0)
8076 (const_int 8)
8077 (const_int 8))
8078 (xor:SI
8079 (zero_extract:SI (match_dup 0)
8080 (const_int 8)
8081 (const_int 8))
8082 (zero_extract:SI (match_dup 0)
8083 (const_int 8)
8084 (const_int 8))))
8085 (clobber (reg:CC 17))])]
8086 "operands[0] = gen_lowpart (SImode, operands[0]);")
8087
8088 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8089 (define_insn "*andsi_1_zext"
8090 [(set (match_operand:DI 0 "register_operand" "=r")
8091 (zero_extend:DI
8092 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8093 (match_operand:SI 2 "general_operand" "rim"))))
8094 (clobber (reg:CC 17))]
8095 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8096 "and{l}\t{%2, %k0|%k0, %2}"
8097 [(set_attr "type" "alu")
8098 (set_attr "mode" "SI")])
8099
8100 (define_insn "*andsi_2"
8101 [(set (reg 17)
8102 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8103 (match_operand:SI 2 "general_operand" "rim,ri"))
8104 (const_int 0)))
8105 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8106 (and:SI (match_dup 1) (match_dup 2)))]
8107 "ix86_match_ccmode (insn, CCNOmode)
8108 && ix86_binary_operator_ok (AND, SImode, operands)"
8109 "and{l}\t{%2, %0|%0, %2}"
8110 [(set_attr "type" "alu")
8111 (set_attr "mode" "SI")])
8112
8113 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8114 (define_insn "*andsi_2_zext"
8115 [(set (reg 17)
8116 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8117 (match_operand:SI 2 "general_operand" "rim"))
8118 (const_int 0)))
8119 (set (match_operand:DI 0 "register_operand" "=r")
8120 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8121 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8122 && ix86_binary_operator_ok (AND, SImode, operands)"
8123 "and{l}\t{%2, %k0|%k0, %2}"
8124 [(set_attr "type" "alu")
8125 (set_attr "mode" "SI")])
8126
8127 (define_expand "andhi3"
8128 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8129 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8130 (match_operand:HI 2 "general_operand" "")))
8131 (clobber (reg:CC 17))]
8132 "TARGET_HIMODE_MATH"
8133 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8134
8135 (define_insn "*andhi_1"
8136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8137 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8138 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8139 (clobber (reg:CC 17))]
8140 "ix86_binary_operator_ok (AND, HImode, operands)"
8141 {
8142 switch (get_attr_type (insn))
8143 {
8144 case TYPE_IMOVX:
8145 if (GET_CODE (operands[2]) != CONST_INT)
8146 abort ();
8147 if (INTVAL (operands[2]) == 0xff)
8148 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8149 abort ();
8150
8151 default:
8152 if (! rtx_equal_p (operands[0], operands[1]))
8153 abort ();
8154
8155 return "and{w}\t{%2, %0|%0, %2}";
8156 }
8157 }
8158 [(set_attr "type" "alu,alu,imovx")
8159 (set_attr "length_immediate" "*,*,0")
8160 (set_attr "mode" "HI,HI,SI")])
8161
8162 (define_insn "*andhi_2"
8163 [(set (reg 17)
8164 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8165 (match_operand:HI 2 "general_operand" "rim,ri"))
8166 (const_int 0)))
8167 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8168 (and:HI (match_dup 1) (match_dup 2)))]
8169 "ix86_match_ccmode (insn, CCNOmode)
8170 && ix86_binary_operator_ok (AND, HImode, operands)"
8171 "and{w}\t{%2, %0|%0, %2}"
8172 [(set_attr "type" "alu")
8173 (set_attr "mode" "HI")])
8174
8175 (define_expand "andqi3"
8176 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8177 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8178 (match_operand:QI 2 "general_operand" "")))
8179 (clobber (reg:CC 17))]
8180 "TARGET_QIMODE_MATH"
8181 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8182
8183 ;; %%% Potential partial reg stall on alternative 2. What to do?
8184 (define_insn "*andqi_1"
8185 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8186 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8187 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8188 (clobber (reg:CC 17))]
8189 "ix86_binary_operator_ok (AND, QImode, operands)"
8190 "@
8191 and{b}\t{%2, %0|%0, %2}
8192 and{b}\t{%2, %0|%0, %2}
8193 and{l}\t{%k2, %k0|%k0, %k2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "mode" "QI,QI,SI")])
8196
8197 (define_insn "*andqi_1_slp"
8198 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8199 (and:QI (match_dup 0)
8200 (match_operand:QI 1 "general_operand" "qi,qmi")))
8201 (clobber (reg:CC 17))]
8202 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8203 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8204 "and{b}\t{%1, %0|%0, %1}"
8205 [(set_attr "type" "alu1")
8206 (set_attr "mode" "QI")])
8207
8208 (define_insn "*andqi_2"
8209 [(set (reg 17)
8210 (compare (and:QI
8211 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8212 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8213 (const_int 0)))
8214 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8215 (and:QI (match_dup 1) (match_dup 2)))]
8216 "ix86_match_ccmode (insn, CCNOmode)
8217 && ix86_binary_operator_ok (AND, QImode, operands)"
8218 {
8219 if (which_alternative == 2)
8220 {
8221 if (GET_CODE (operands[2]) == CONST_INT
8222 && (INTVAL (operands[2]) & 0xffffff00))
8223 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8224 return "and{l}\t{%2, %k0|%k0, %2}";
8225 }
8226 return "and{b}\t{%2, %0|%0, %2}";
8227 }
8228 [(set_attr "type" "alu")
8229 (set_attr "mode" "QI,QI,SI")])
8230
8231 (define_insn "*andqi_2_slp"
8232 [(set (reg 17)
8233 (compare (and:QI
8234 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8235 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8236 (const_int 0)))
8237 (set (strict_low_part (match_dup 0))
8238 (and:QI (match_dup 0) (match_dup 1)))]
8239 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8240 && ix86_match_ccmode (insn, CCNOmode)
8241 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8242 "and{b}\t{%1, %0|%0, %1}"
8243 [(set_attr "type" "alu1")
8244 (set_attr "mode" "QI")])
8245
8246 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8247 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8248 ;; for a QImode operand, which of course failed.
8249
8250 (define_insn "andqi_ext_0"
8251 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8252 (const_int 8)
8253 (const_int 8))
8254 (and:SI
8255 (zero_extract:SI
8256 (match_operand 1 "ext_register_operand" "0")
8257 (const_int 8)
8258 (const_int 8))
8259 (match_operand 2 "const_int_operand" "n")))
8260 (clobber (reg:CC 17))]
8261 ""
8262 "and{b}\t{%2, %h0|%h0, %2}"
8263 [(set_attr "type" "alu")
8264 (set_attr "length_immediate" "1")
8265 (set_attr "mode" "QI")])
8266
8267 ;; Generated by peephole translating test to and. This shows up
8268 ;; often in fp comparisons.
8269
8270 (define_insn "*andqi_ext_0_cc"
8271 [(set (reg 17)
8272 (compare
8273 (and:SI
8274 (zero_extract:SI
8275 (match_operand 1 "ext_register_operand" "0")
8276 (const_int 8)
8277 (const_int 8))
8278 (match_operand 2 "const_int_operand" "n"))
8279 (const_int 0)))
8280 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8281 (const_int 8)
8282 (const_int 8))
8283 (and:SI
8284 (zero_extract:SI
8285 (match_dup 1)
8286 (const_int 8)
8287 (const_int 8))
8288 (match_dup 2)))]
8289 "ix86_match_ccmode (insn, CCNOmode)"
8290 "and{b}\t{%2, %h0|%h0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "length_immediate" "1")
8293 (set_attr "mode" "QI")])
8294
8295 (define_insn "*andqi_ext_1"
8296 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8297 (const_int 8)
8298 (const_int 8))
8299 (and:SI
8300 (zero_extract:SI
8301 (match_operand 1 "ext_register_operand" "0")
8302 (const_int 8)
8303 (const_int 8))
8304 (zero_extend:SI
8305 (match_operand:QI 2 "general_operand" "Qm"))))
8306 (clobber (reg:CC 17))]
8307 "!TARGET_64BIT"
8308 "and{b}\t{%2, %h0|%h0, %2}"
8309 [(set_attr "type" "alu")
8310 (set_attr "length_immediate" "0")
8311 (set_attr "mode" "QI")])
8312
8313 (define_insn "*andqi_ext_1_rex64"
8314 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8315 (const_int 8)
8316 (const_int 8))
8317 (and:SI
8318 (zero_extract:SI
8319 (match_operand 1 "ext_register_operand" "0")
8320 (const_int 8)
8321 (const_int 8))
8322 (zero_extend:SI
8323 (match_operand 2 "ext_register_operand" "Q"))))
8324 (clobber (reg:CC 17))]
8325 "TARGET_64BIT"
8326 "and{b}\t{%2, %h0|%h0, %2}"
8327 [(set_attr "type" "alu")
8328 (set_attr "length_immediate" "0")
8329 (set_attr "mode" "QI")])
8330
8331 (define_insn "*andqi_ext_2"
8332 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333 (const_int 8)
8334 (const_int 8))
8335 (and:SI
8336 (zero_extract:SI
8337 (match_operand 1 "ext_register_operand" "%0")
8338 (const_int 8)
8339 (const_int 8))
8340 (zero_extract:SI
8341 (match_operand 2 "ext_register_operand" "Q")
8342 (const_int 8)
8343 (const_int 8))))
8344 (clobber (reg:CC 17))]
8345 ""
8346 "and{b}\t{%h2, %h0|%h0, %h2}"
8347 [(set_attr "type" "alu")
8348 (set_attr "length_immediate" "0")
8349 (set_attr "mode" "QI")])
8350
8351 ;; Convert wide AND instructions with immediate operand to shorter QImode
8352 ;; equivalents when possible.
8353 ;; Don't do the splitting with memory operands, since it introduces risk
8354 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8355 ;; for size, but that can (should?) be handled by generic code instead.
8356 (define_split
8357 [(set (match_operand 0 "register_operand" "")
8358 (and (match_operand 1 "register_operand" "")
8359 (match_operand 2 "const_int_operand" "")))
8360 (clobber (reg:CC 17))]
8361 "reload_completed
8362 && QI_REG_P (operands[0])
8363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8364 && !(~INTVAL (operands[2]) & ~(255 << 8))
8365 && GET_MODE (operands[0]) != QImode"
8366 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8367 (and:SI (zero_extract:SI (match_dup 1)
8368 (const_int 8) (const_int 8))
8369 (match_dup 2)))
8370 (clobber (reg:CC 17))])]
8371 "operands[0] = gen_lowpart (SImode, operands[0]);
8372 operands[1] = gen_lowpart (SImode, operands[1]);
8373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8374
8375 ;; Since AND can be encoded with sign extended immediate, this is only
8376 ;; profitable when 7th bit is not set.
8377 (define_split
8378 [(set (match_operand 0 "register_operand" "")
8379 (and (match_operand 1 "general_operand" "")
8380 (match_operand 2 "const_int_operand" "")))
8381 (clobber (reg:CC 17))]
8382 "reload_completed
8383 && ANY_QI_REG_P (operands[0])
8384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8385 && !(~INTVAL (operands[2]) & ~255)
8386 && !(INTVAL (operands[2]) & 128)
8387 && GET_MODE (operands[0]) != QImode"
8388 [(parallel [(set (strict_low_part (match_dup 0))
8389 (and:QI (match_dup 1)
8390 (match_dup 2)))
8391 (clobber (reg:CC 17))])]
8392 "operands[0] = gen_lowpart (QImode, operands[0]);
8393 operands[1] = gen_lowpart (QImode, operands[1]);
8394 operands[2] = gen_lowpart (QImode, operands[2]);")
8395 \f
8396 ;; Logical inclusive OR instructions
8397
8398 ;; %%% This used to optimize known byte-wide and operations to memory.
8399 ;; If this is considered useful, it should be done with splitters.
8400
8401 (define_expand "iordi3"
8402 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8403 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8404 (match_operand:DI 2 "x86_64_general_operand" "")))
8405 (clobber (reg:CC 17))]
8406 "TARGET_64BIT"
8407 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8408
8409 (define_insn "*iordi_1_rex64"
8410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8411 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8412 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8413 (clobber (reg:CC 17))]
8414 "TARGET_64BIT
8415 && ix86_binary_operator_ok (IOR, DImode, operands)"
8416 "or{q}\t{%2, %0|%0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "mode" "DI")])
8419
8420 (define_insn "*iordi_2_rex64"
8421 [(set (reg 17)
8422 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8423 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8424 (const_int 0)))
8425 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8426 (ior:DI (match_dup 1) (match_dup 2)))]
8427 "TARGET_64BIT
8428 && ix86_match_ccmode (insn, CCNOmode)
8429 && ix86_binary_operator_ok (IOR, DImode, operands)"
8430 "or{q}\t{%2, %0|%0, %2}"
8431 [(set_attr "type" "alu")
8432 (set_attr "mode" "DI")])
8433
8434 (define_insn "*iordi_3_rex64"
8435 [(set (reg 17)
8436 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8437 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8438 (const_int 0)))
8439 (clobber (match_scratch:DI 0 "=r"))]
8440 "TARGET_64BIT
8441 && ix86_match_ccmode (insn, CCNOmode)
8442 && ix86_binary_operator_ok (IOR, DImode, operands)"
8443 "or{q}\t{%2, %0|%0, %2}"
8444 [(set_attr "type" "alu")
8445 (set_attr "mode" "DI")])
8446
8447
8448 (define_expand "iorsi3"
8449 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8450 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8451 (match_operand:SI 2 "general_operand" "")))
8452 (clobber (reg:CC 17))]
8453 ""
8454 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8455
8456 (define_insn "*iorsi_1"
8457 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8458 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8459 (match_operand:SI 2 "general_operand" "ri,rmi")))
8460 (clobber (reg:CC 17))]
8461 "ix86_binary_operator_ok (IOR, SImode, operands)"
8462 "or{l}\t{%2, %0|%0, %2}"
8463 [(set_attr "type" "alu")
8464 (set_attr "mode" "SI")])
8465
8466 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8467 (define_insn "*iorsi_1_zext"
8468 [(set (match_operand:DI 0 "register_operand" "=rm")
8469 (zero_extend:DI
8470 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8471 (match_operand:SI 2 "general_operand" "rim"))))
8472 (clobber (reg:CC 17))]
8473 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8474 "or{l}\t{%2, %k0|%k0, %2}"
8475 [(set_attr "type" "alu")
8476 (set_attr "mode" "SI")])
8477
8478 (define_insn "*iorsi_1_zext_imm"
8479 [(set (match_operand:DI 0 "register_operand" "=rm")
8480 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8481 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8482 (clobber (reg:CC 17))]
8483 "TARGET_64BIT"
8484 "or{l}\t{%2, %k0|%k0, %2}"
8485 [(set_attr "type" "alu")
8486 (set_attr "mode" "SI")])
8487
8488 (define_insn "*iorsi_2"
8489 [(set (reg 17)
8490 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8491 (match_operand:SI 2 "general_operand" "rim,ri"))
8492 (const_int 0)))
8493 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8494 (ior:SI (match_dup 1) (match_dup 2)))]
8495 "ix86_match_ccmode (insn, CCNOmode)
8496 && ix86_binary_operator_ok (IOR, SImode, operands)"
8497 "or{l}\t{%2, %0|%0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "mode" "SI")])
8500
8501 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8502 ;; ??? Special case for immediate operand is missing - it is tricky.
8503 (define_insn "*iorsi_2_zext"
8504 [(set (reg 17)
8505 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8506 (match_operand:SI 2 "general_operand" "rim"))
8507 (const_int 0)))
8508 (set (match_operand:DI 0 "register_operand" "=r")
8509 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8510 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8511 && ix86_binary_operator_ok (IOR, SImode, operands)"
8512 "or{l}\t{%2, %k0|%k0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "mode" "SI")])
8515
8516 (define_insn "*iorsi_2_zext_imm"
8517 [(set (reg 17)
8518 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8519 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8520 (const_int 0)))
8521 (set (match_operand:DI 0 "register_operand" "=r")
8522 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8523 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8524 && ix86_binary_operator_ok (IOR, SImode, operands)"
8525 "or{l}\t{%2, %k0|%k0, %2}"
8526 [(set_attr "type" "alu")
8527 (set_attr "mode" "SI")])
8528
8529 (define_insn "*iorsi_3"
8530 [(set (reg 17)
8531 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8532 (match_operand:SI 2 "general_operand" "rim"))
8533 (const_int 0)))
8534 (clobber (match_scratch:SI 0 "=r"))]
8535 "ix86_match_ccmode (insn, CCNOmode)
8536 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8537 "or{l}\t{%2, %0|%0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "SI")])
8540
8541 (define_expand "iorhi3"
8542 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8543 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8544 (match_operand:HI 2 "general_operand" "")))
8545 (clobber (reg:CC 17))]
8546 "TARGET_HIMODE_MATH"
8547 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8548
8549 (define_insn "*iorhi_1"
8550 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8551 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8552 (match_operand:HI 2 "general_operand" "rmi,ri")))
8553 (clobber (reg:CC 17))]
8554 "ix86_binary_operator_ok (IOR, HImode, operands)"
8555 "or{w}\t{%2, %0|%0, %2}"
8556 [(set_attr "type" "alu")
8557 (set_attr "mode" "HI")])
8558
8559 (define_insn "*iorhi_2"
8560 [(set (reg 17)
8561 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8562 (match_operand:HI 2 "general_operand" "rim,ri"))
8563 (const_int 0)))
8564 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8565 (ior:HI (match_dup 1) (match_dup 2)))]
8566 "ix86_match_ccmode (insn, CCNOmode)
8567 && ix86_binary_operator_ok (IOR, HImode, operands)"
8568 "or{w}\t{%2, %0|%0, %2}"
8569 [(set_attr "type" "alu")
8570 (set_attr "mode" "HI")])
8571
8572 (define_insn "*iorhi_3"
8573 [(set (reg 17)
8574 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8575 (match_operand:HI 2 "general_operand" "rim"))
8576 (const_int 0)))
8577 (clobber (match_scratch:HI 0 "=r"))]
8578 "ix86_match_ccmode (insn, CCNOmode)
8579 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8580 "or{w}\t{%2, %0|%0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "HI")])
8583
8584 (define_expand "iorqi3"
8585 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8586 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8587 (match_operand:QI 2 "general_operand" "")))
8588 (clobber (reg:CC 17))]
8589 "TARGET_QIMODE_MATH"
8590 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8591
8592 ;; %%% Potential partial reg stall on alternative 2. What to do?
8593 (define_insn "*iorqi_1"
8594 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8595 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8596 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8597 (clobber (reg:CC 17))]
8598 "ix86_binary_operator_ok (IOR, QImode, operands)"
8599 "@
8600 or{b}\t{%2, %0|%0, %2}
8601 or{b}\t{%2, %0|%0, %2}
8602 or{l}\t{%k2, %k0|%k0, %k2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "QI,QI,SI")])
8605
8606 (define_insn "*iorqi_1_slp"
8607 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8608 (ior:QI (match_dup 0)
8609 (match_operand:QI 1 "general_operand" "qmi,qi")))
8610 (clobber (reg:CC 17))]
8611 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8612 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8613 "or{b}\t{%1, %0|%0, %1}"
8614 [(set_attr "type" "alu1")
8615 (set_attr "mode" "QI")])
8616
8617 (define_insn "*iorqi_2"
8618 [(set (reg 17)
8619 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8620 (match_operand:QI 2 "general_operand" "qim,qi"))
8621 (const_int 0)))
8622 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8623 (ior:QI (match_dup 1) (match_dup 2)))]
8624 "ix86_match_ccmode (insn, CCNOmode)
8625 && ix86_binary_operator_ok (IOR, QImode, operands)"
8626 "or{b}\t{%2, %0|%0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "mode" "QI")])
8629
8630 (define_insn "*iorqi_2_slp"
8631 [(set (reg 17)
8632 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8633 (match_operand:QI 1 "general_operand" "qim,qi"))
8634 (const_int 0)))
8635 (set (strict_low_part (match_dup 0))
8636 (ior:QI (match_dup 0) (match_dup 1)))]
8637 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8638 && ix86_match_ccmode (insn, CCNOmode)
8639 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8640 "or{b}\t{%1, %0|%0, %1}"
8641 [(set_attr "type" "alu1")
8642 (set_attr "mode" "QI")])
8643
8644 (define_insn "*iorqi_3"
8645 [(set (reg 17)
8646 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8647 (match_operand:QI 2 "general_operand" "qim"))
8648 (const_int 0)))
8649 (clobber (match_scratch:QI 0 "=q"))]
8650 "ix86_match_ccmode (insn, CCNOmode)
8651 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8652 "or{b}\t{%2, %0|%0, %2}"
8653 [(set_attr "type" "alu")
8654 (set_attr "mode" "QI")])
8655
8656 (define_insn "iorqi_ext_0"
8657 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8658 (const_int 8)
8659 (const_int 8))
8660 (ior:SI
8661 (zero_extract:SI
8662 (match_operand 1 "ext_register_operand" "0")
8663 (const_int 8)
8664 (const_int 8))
8665 (match_operand 2 "const_int_operand" "n")))
8666 (clobber (reg:CC 17))]
8667 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8668 "or{b}\t{%2, %h0|%h0, %2}"
8669 [(set_attr "type" "alu")
8670 (set_attr "length_immediate" "1")
8671 (set_attr "mode" "QI")])
8672
8673 (define_insn "*iorqi_ext_1"
8674 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8675 (const_int 8)
8676 (const_int 8))
8677 (ior:SI
8678 (zero_extract:SI
8679 (match_operand 1 "ext_register_operand" "0")
8680 (const_int 8)
8681 (const_int 8))
8682 (zero_extend:SI
8683 (match_operand:QI 2 "general_operand" "Qm"))))
8684 (clobber (reg:CC 17))]
8685 "!TARGET_64BIT
8686 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8687 "or{b}\t{%2, %h0|%h0, %2}"
8688 [(set_attr "type" "alu")
8689 (set_attr "length_immediate" "0")
8690 (set_attr "mode" "QI")])
8691
8692 (define_insn "*iorqi_ext_1_rex64"
8693 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8694 (const_int 8)
8695 (const_int 8))
8696 (ior:SI
8697 (zero_extract:SI
8698 (match_operand 1 "ext_register_operand" "0")
8699 (const_int 8)
8700 (const_int 8))
8701 (zero_extend:SI
8702 (match_operand 2 "ext_register_operand" "Q"))))
8703 (clobber (reg:CC 17))]
8704 "TARGET_64BIT
8705 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8706 "or{b}\t{%2, %h0|%h0, %2}"
8707 [(set_attr "type" "alu")
8708 (set_attr "length_immediate" "0")
8709 (set_attr "mode" "QI")])
8710
8711 (define_insn "*iorqi_ext_2"
8712 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8713 (const_int 8)
8714 (const_int 8))
8715 (ior:SI
8716 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8717 (const_int 8)
8718 (const_int 8))
8719 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8720 (const_int 8)
8721 (const_int 8))))
8722 (clobber (reg:CC 17))]
8723 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8724 "ior{b}\t{%h2, %h0|%h0, %h2}"
8725 [(set_attr "type" "alu")
8726 (set_attr "length_immediate" "0")
8727 (set_attr "mode" "QI")])
8728
8729 (define_split
8730 [(set (match_operand 0 "register_operand" "")
8731 (ior (match_operand 1 "register_operand" "")
8732 (match_operand 2 "const_int_operand" "")))
8733 (clobber (reg:CC 17))]
8734 "reload_completed
8735 && QI_REG_P (operands[0])
8736 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8737 && !(INTVAL (operands[2]) & ~(255 << 8))
8738 && GET_MODE (operands[0]) != QImode"
8739 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8740 (ior:SI (zero_extract:SI (match_dup 1)
8741 (const_int 8) (const_int 8))
8742 (match_dup 2)))
8743 (clobber (reg:CC 17))])]
8744 "operands[0] = gen_lowpart (SImode, operands[0]);
8745 operands[1] = gen_lowpart (SImode, operands[1]);
8746 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8747
8748 ;; Since OR can be encoded with sign extended immediate, this is only
8749 ;; profitable when 7th bit is set.
8750 (define_split
8751 [(set (match_operand 0 "register_operand" "")
8752 (ior (match_operand 1 "general_operand" "")
8753 (match_operand 2 "const_int_operand" "")))
8754 (clobber (reg:CC 17))]
8755 "reload_completed
8756 && ANY_QI_REG_P (operands[0])
8757 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8758 && !(INTVAL (operands[2]) & ~255)
8759 && (INTVAL (operands[2]) & 128)
8760 && GET_MODE (operands[0]) != QImode"
8761 [(parallel [(set (strict_low_part (match_dup 0))
8762 (ior:QI (match_dup 1)
8763 (match_dup 2)))
8764 (clobber (reg:CC 17))])]
8765 "operands[0] = gen_lowpart (QImode, operands[0]);
8766 operands[1] = gen_lowpart (QImode, operands[1]);
8767 operands[2] = gen_lowpart (QImode, operands[2]);")
8768 \f
8769 ;; Logical XOR instructions
8770
8771 ;; %%% This used to optimize known byte-wide and operations to memory.
8772 ;; If this is considered useful, it should be done with splitters.
8773
8774 (define_expand "xordi3"
8775 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8776 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8777 (match_operand:DI 2 "x86_64_general_operand" "")))
8778 (clobber (reg:CC 17))]
8779 "TARGET_64BIT"
8780 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8781
8782 (define_insn "*xordi_1_rex64"
8783 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8784 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8785 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8786 (clobber (reg:CC 17))]
8787 "TARGET_64BIT
8788 && ix86_binary_operator_ok (XOR, DImode, operands)"
8789 "@
8790 xor{q}\t{%2, %0|%0, %2}
8791 xor{q}\t{%2, %0|%0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "mode" "DI,DI")])
8794
8795 (define_insn "*xordi_2_rex64"
8796 [(set (reg 17)
8797 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8798 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8799 (const_int 0)))
8800 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8801 (xor:DI (match_dup 1) (match_dup 2)))]
8802 "TARGET_64BIT
8803 && ix86_match_ccmode (insn, CCNOmode)
8804 && ix86_binary_operator_ok (XOR, DImode, operands)"
8805 "@
8806 xor{q}\t{%2, %0|%0, %2}
8807 xor{q}\t{%2, %0|%0, %2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "mode" "DI,DI")])
8810
8811 (define_insn "*xordi_3_rex64"
8812 [(set (reg 17)
8813 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8814 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8815 (const_int 0)))
8816 (clobber (match_scratch:DI 0 "=r"))]
8817 "TARGET_64BIT
8818 && ix86_match_ccmode (insn, CCNOmode)
8819 && ix86_binary_operator_ok (XOR, DImode, operands)"
8820 "xor{q}\t{%2, %0|%0, %2}"
8821 [(set_attr "type" "alu")
8822 (set_attr "mode" "DI")])
8823
8824 (define_expand "xorsi3"
8825 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8826 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8827 (match_operand:SI 2 "general_operand" "")))
8828 (clobber (reg:CC 17))]
8829 ""
8830 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8831
8832 (define_insn "*xorsi_1"
8833 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8834 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8835 (match_operand:SI 2 "general_operand" "ri,rm")))
8836 (clobber (reg:CC 17))]
8837 "ix86_binary_operator_ok (XOR, SImode, operands)"
8838 "xor{l}\t{%2, %0|%0, %2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "SI")])
8841
8842 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8843 ;; Add speccase for immediates
8844 (define_insn "*xorsi_1_zext"
8845 [(set (match_operand:DI 0 "register_operand" "=r")
8846 (zero_extend:DI
8847 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8848 (match_operand:SI 2 "general_operand" "rim"))))
8849 (clobber (reg:CC 17))]
8850 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8851 "xor{l}\t{%2, %k0|%k0, %2}"
8852 [(set_attr "type" "alu")
8853 (set_attr "mode" "SI")])
8854
8855 (define_insn "*xorsi_1_zext_imm"
8856 [(set (match_operand:DI 0 "register_operand" "=r")
8857 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8858 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8859 (clobber (reg:CC 17))]
8860 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8861 "xor{l}\t{%2, %k0|%k0, %2}"
8862 [(set_attr "type" "alu")
8863 (set_attr "mode" "SI")])
8864
8865 (define_insn "*xorsi_2"
8866 [(set (reg 17)
8867 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8868 (match_operand:SI 2 "general_operand" "rim,ri"))
8869 (const_int 0)))
8870 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8871 (xor:SI (match_dup 1) (match_dup 2)))]
8872 "ix86_match_ccmode (insn, CCNOmode)
8873 && ix86_binary_operator_ok (XOR, SImode, operands)"
8874 "xor{l}\t{%2, %0|%0, %2}"
8875 [(set_attr "type" "alu")
8876 (set_attr "mode" "SI")])
8877
8878 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8879 ;; ??? Special case for immediate operand is missing - it is tricky.
8880 (define_insn "*xorsi_2_zext"
8881 [(set (reg 17)
8882 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8883 (match_operand:SI 2 "general_operand" "rim"))
8884 (const_int 0)))
8885 (set (match_operand:DI 0 "register_operand" "=r")
8886 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8887 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8888 && ix86_binary_operator_ok (XOR, SImode, operands)"
8889 "xor{l}\t{%2, %k0|%k0, %2}"
8890 [(set_attr "type" "alu")
8891 (set_attr "mode" "SI")])
8892
8893 (define_insn "*xorsi_2_zext_imm"
8894 [(set (reg 17)
8895 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8896 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8897 (const_int 0)))
8898 (set (match_operand:DI 0 "register_operand" "=r")
8899 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8900 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8901 && ix86_binary_operator_ok (XOR, SImode, operands)"
8902 "xor{l}\t{%2, %k0|%k0, %2}"
8903 [(set_attr "type" "alu")
8904 (set_attr "mode" "SI")])
8905
8906 (define_insn "*xorsi_3"
8907 [(set (reg 17)
8908 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8909 (match_operand:SI 2 "general_operand" "rim"))
8910 (const_int 0)))
8911 (clobber (match_scratch:SI 0 "=r"))]
8912 "ix86_match_ccmode (insn, CCNOmode)
8913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8914 "xor{l}\t{%2, %0|%0, %2}"
8915 [(set_attr "type" "alu")
8916 (set_attr "mode" "SI")])
8917
8918 (define_expand "xorhi3"
8919 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8920 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8921 (match_operand:HI 2 "general_operand" "")))
8922 (clobber (reg:CC 17))]
8923 "TARGET_HIMODE_MATH"
8924 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8925
8926 (define_insn "*xorhi_1"
8927 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8928 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:HI 2 "general_operand" "rmi,ri")))
8930 (clobber (reg:CC 17))]
8931 "ix86_binary_operator_ok (XOR, HImode, operands)"
8932 "xor{w}\t{%2, %0|%0, %2}"
8933 [(set_attr "type" "alu")
8934 (set_attr "mode" "HI")])
8935
8936 (define_insn "*xorhi_2"
8937 [(set (reg 17)
8938 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8939 (match_operand:HI 2 "general_operand" "rim,ri"))
8940 (const_int 0)))
8941 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8942 (xor:HI (match_dup 1) (match_dup 2)))]
8943 "ix86_match_ccmode (insn, CCNOmode)
8944 && ix86_binary_operator_ok (XOR, HImode, operands)"
8945 "xor{w}\t{%2, %0|%0, %2}"
8946 [(set_attr "type" "alu")
8947 (set_attr "mode" "HI")])
8948
8949 (define_insn "*xorhi_3"
8950 [(set (reg 17)
8951 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8952 (match_operand:HI 2 "general_operand" "rim"))
8953 (const_int 0)))
8954 (clobber (match_scratch:HI 0 "=r"))]
8955 "ix86_match_ccmode (insn, CCNOmode)
8956 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8957 "xor{w}\t{%2, %0|%0, %2}"
8958 [(set_attr "type" "alu")
8959 (set_attr "mode" "HI")])
8960
8961 (define_expand "xorqi3"
8962 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8963 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8964 (match_operand:QI 2 "general_operand" "")))
8965 (clobber (reg:CC 17))]
8966 "TARGET_QIMODE_MATH"
8967 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8968
8969 ;; %%% Potential partial reg stall on alternative 2. What to do?
8970 (define_insn "*xorqi_1"
8971 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8972 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8973 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8974 (clobber (reg:CC 17))]
8975 "ix86_binary_operator_ok (XOR, QImode, operands)"
8976 "@
8977 xor{b}\t{%2, %0|%0, %2}
8978 xor{b}\t{%2, %0|%0, %2}
8979 xor{l}\t{%k2, %k0|%k0, %k2}"
8980 [(set_attr "type" "alu")
8981 (set_attr "mode" "QI,QI,SI")])
8982
8983 (define_insn "*xorqi_1_slp"
8984 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8985 (xor:QI (match_dup 0)
8986 (match_operand:QI 1 "general_operand" "qi,qmi")))
8987 (clobber (reg:CC 17))]
8988 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8989 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8990 "xor{b}\t{%1, %0|%0, %1}"
8991 [(set_attr "type" "alu1")
8992 (set_attr "mode" "QI")])
8993
8994 (define_insn "xorqi_ext_0"
8995 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8996 (const_int 8)
8997 (const_int 8))
8998 (xor:SI
8999 (zero_extract:SI
9000 (match_operand 1 "ext_register_operand" "0")
9001 (const_int 8)
9002 (const_int 8))
9003 (match_operand 2 "const_int_operand" "n")))
9004 (clobber (reg:CC 17))]
9005 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9006 "xor{b}\t{%2, %h0|%h0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "length_immediate" "1")
9009 (set_attr "mode" "QI")])
9010
9011 (define_insn "*xorqi_ext_1"
9012 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9013 (const_int 8)
9014 (const_int 8))
9015 (xor:SI
9016 (zero_extract:SI
9017 (match_operand 1 "ext_register_operand" "0")
9018 (const_int 8)
9019 (const_int 8))
9020 (zero_extend:SI
9021 (match_operand:QI 2 "general_operand" "Qm"))))
9022 (clobber (reg:CC 17))]
9023 "!TARGET_64BIT
9024 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9025 "xor{b}\t{%2, %h0|%h0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "length_immediate" "0")
9028 (set_attr "mode" "QI")])
9029
9030 (define_insn "*xorqi_ext_1_rex64"
9031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9032 (const_int 8)
9033 (const_int 8))
9034 (xor:SI
9035 (zero_extract:SI
9036 (match_operand 1 "ext_register_operand" "0")
9037 (const_int 8)
9038 (const_int 8))
9039 (zero_extend:SI
9040 (match_operand 2 "ext_register_operand" "Q"))))
9041 (clobber (reg:CC 17))]
9042 "TARGET_64BIT
9043 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9044 "xor{b}\t{%2, %h0|%h0, %2}"
9045 [(set_attr "type" "alu")
9046 (set_attr "length_immediate" "0")
9047 (set_attr "mode" "QI")])
9048
9049 (define_insn "*xorqi_ext_2"
9050 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9051 (const_int 8)
9052 (const_int 8))
9053 (xor:SI
9054 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9055 (const_int 8)
9056 (const_int 8))
9057 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9058 (const_int 8)
9059 (const_int 8))))
9060 (clobber (reg:CC 17))]
9061 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9062 "xor{b}\t{%h2, %h0|%h0, %h2}"
9063 [(set_attr "type" "alu")
9064 (set_attr "length_immediate" "0")
9065 (set_attr "mode" "QI")])
9066
9067 (define_insn "*xorqi_cc_1"
9068 [(set (reg 17)
9069 (compare
9070 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9071 (match_operand:QI 2 "general_operand" "qim,qi"))
9072 (const_int 0)))
9073 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9074 (xor:QI (match_dup 1) (match_dup 2)))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && ix86_binary_operator_ok (XOR, QImode, operands)"
9077 "xor{b}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "QI")])
9080
9081 (define_insn "*xorqi_2_slp"
9082 [(set (reg 17)
9083 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9084 (match_operand:QI 1 "general_operand" "qim,qi"))
9085 (const_int 0)))
9086 (set (strict_low_part (match_dup 0))
9087 (xor:QI (match_dup 0) (match_dup 1)))]
9088 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9089 && ix86_match_ccmode (insn, CCNOmode)
9090 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9091 "xor{b}\t{%1, %0|%0, %1}"
9092 [(set_attr "type" "alu1")
9093 (set_attr "mode" "QI")])
9094
9095 (define_insn "*xorqi_cc_2"
9096 [(set (reg 17)
9097 (compare
9098 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9099 (match_operand:QI 2 "general_operand" "qim"))
9100 (const_int 0)))
9101 (clobber (match_scratch:QI 0 "=q"))]
9102 "ix86_match_ccmode (insn, CCNOmode)
9103 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9104 "xor{b}\t{%2, %0|%0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "mode" "QI")])
9107
9108 (define_insn "*xorqi_cc_ext_1"
9109 [(set (reg 17)
9110 (compare
9111 (xor:SI
9112 (zero_extract:SI
9113 (match_operand 1 "ext_register_operand" "0")
9114 (const_int 8)
9115 (const_int 8))
9116 (match_operand:QI 2 "general_operand" "qmn"))
9117 (const_int 0)))
9118 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9119 (const_int 8)
9120 (const_int 8))
9121 (xor:SI
9122 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9123 (match_dup 2)))]
9124 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9125 "xor{b}\t{%2, %h0|%h0, %2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "QI")])
9128
9129 (define_insn "*xorqi_cc_ext_1_rex64"
9130 [(set (reg 17)
9131 (compare
9132 (xor:SI
9133 (zero_extract:SI
9134 (match_operand 1 "ext_register_operand" "0")
9135 (const_int 8)
9136 (const_int 8))
9137 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9138 (const_int 0)))
9139 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140 (const_int 8)
9141 (const_int 8))
9142 (xor:SI
9143 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9144 (match_dup 2)))]
9145 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9146 "xor{b}\t{%2, %h0|%h0, %2}"
9147 [(set_attr "type" "alu")
9148 (set_attr "mode" "QI")])
9149
9150 (define_expand "xorqi_cc_ext_1"
9151 [(parallel [
9152 (set (reg:CCNO 17)
9153 (compare:CCNO
9154 (xor:SI
9155 (zero_extract:SI
9156 (match_operand 1 "ext_register_operand" "")
9157 (const_int 8)
9158 (const_int 8))
9159 (match_operand:QI 2 "general_operand" ""))
9160 (const_int 0)))
9161 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9162 (const_int 8)
9163 (const_int 8))
9164 (xor:SI
9165 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9166 (match_dup 2)))])]
9167 ""
9168 "")
9169
9170 (define_split
9171 [(set (match_operand 0 "register_operand" "")
9172 (xor (match_operand 1 "register_operand" "")
9173 (match_operand 2 "const_int_operand" "")))
9174 (clobber (reg:CC 17))]
9175 "reload_completed
9176 && QI_REG_P (operands[0])
9177 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9178 && !(INTVAL (operands[2]) & ~(255 << 8))
9179 && GET_MODE (operands[0]) != QImode"
9180 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9181 (xor:SI (zero_extract:SI (match_dup 1)
9182 (const_int 8) (const_int 8))
9183 (match_dup 2)))
9184 (clobber (reg:CC 17))])]
9185 "operands[0] = gen_lowpart (SImode, operands[0]);
9186 operands[1] = gen_lowpart (SImode, operands[1]);
9187 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9188
9189 ;; Since XOR can be encoded with sign extended immediate, this is only
9190 ;; profitable when 7th bit is set.
9191 (define_split
9192 [(set (match_operand 0 "register_operand" "")
9193 (xor (match_operand 1 "general_operand" "")
9194 (match_operand 2 "const_int_operand" "")))
9195 (clobber (reg:CC 17))]
9196 "reload_completed
9197 && ANY_QI_REG_P (operands[0])
9198 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9199 && !(INTVAL (operands[2]) & ~255)
9200 && (INTVAL (operands[2]) & 128)
9201 && GET_MODE (operands[0]) != QImode"
9202 [(parallel [(set (strict_low_part (match_dup 0))
9203 (xor:QI (match_dup 1)
9204 (match_dup 2)))
9205 (clobber (reg:CC 17))])]
9206 "operands[0] = gen_lowpart (QImode, operands[0]);
9207 operands[1] = gen_lowpart (QImode, operands[1]);
9208 operands[2] = gen_lowpart (QImode, operands[2]);")
9209 \f
9210 ;; Negation instructions
9211
9212 (define_expand "negdi2"
9213 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9214 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9215 (clobber (reg:CC 17))])]
9216 ""
9217 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9218
9219 (define_insn "*negdi2_1"
9220 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9221 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9222 (clobber (reg:CC 17))]
9223 "!TARGET_64BIT
9224 && ix86_unary_operator_ok (NEG, DImode, operands)"
9225 "#")
9226
9227 (define_split
9228 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229 (neg:DI (match_operand:DI 1 "general_operand" "")))
9230 (clobber (reg:CC 17))]
9231 "!TARGET_64BIT && reload_completed"
9232 [(parallel
9233 [(set (reg:CCZ 17)
9234 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9235 (set (match_dup 0) (neg:SI (match_dup 2)))])
9236 (parallel
9237 [(set (match_dup 1)
9238 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9239 (match_dup 3))
9240 (const_int 0)))
9241 (clobber (reg:CC 17))])
9242 (parallel
9243 [(set (match_dup 1)
9244 (neg:SI (match_dup 1)))
9245 (clobber (reg:CC 17))])]
9246 "split_di (operands+1, 1, operands+2, operands+3);
9247 split_di (operands+0, 1, operands+0, operands+1);")
9248
9249 (define_insn "*negdi2_1_rex64"
9250 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9251 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9252 (clobber (reg:CC 17))]
9253 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9254 "neg{q}\t%0"
9255 [(set_attr "type" "negnot")
9256 (set_attr "mode" "DI")])
9257
9258 ;; The problem with neg is that it does not perform (compare x 0),
9259 ;; it really performs (compare 0 x), which leaves us with the zero
9260 ;; flag being the only useful item.
9261
9262 (define_insn "*negdi2_cmpz_rex64"
9263 [(set (reg:CCZ 17)
9264 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9265 (const_int 0)))
9266 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9267 (neg:DI (match_dup 1)))]
9268 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9269 "neg{q}\t%0"
9270 [(set_attr "type" "negnot")
9271 (set_attr "mode" "DI")])
9272
9273
9274 (define_expand "negsi2"
9275 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9276 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9277 (clobber (reg:CC 17))])]
9278 ""
9279 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9280
9281 (define_insn "*negsi2_1"
9282 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9283 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9284 (clobber (reg:CC 17))]
9285 "ix86_unary_operator_ok (NEG, SImode, operands)"
9286 "neg{l}\t%0"
9287 [(set_attr "type" "negnot")
9288 (set_attr "mode" "SI")])
9289
9290 ;; Combine is quite creative about this pattern.
9291 (define_insn "*negsi2_1_zext"
9292 [(set (match_operand:DI 0 "register_operand" "=r")
9293 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9294 (const_int 32)))
9295 (const_int 32)))
9296 (clobber (reg:CC 17))]
9297 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9298 "neg{l}\t%k0"
9299 [(set_attr "type" "negnot")
9300 (set_attr "mode" "SI")])
9301
9302 ;; The problem with neg is that it does not perform (compare x 0),
9303 ;; it really performs (compare 0 x), which leaves us with the zero
9304 ;; flag being the only useful item.
9305
9306 (define_insn "*negsi2_cmpz"
9307 [(set (reg:CCZ 17)
9308 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9309 (const_int 0)))
9310 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9311 (neg:SI (match_dup 1)))]
9312 "ix86_unary_operator_ok (NEG, SImode, operands)"
9313 "neg{l}\t%0"
9314 [(set_attr "type" "negnot")
9315 (set_attr "mode" "SI")])
9316
9317 (define_insn "*negsi2_cmpz_zext"
9318 [(set (reg:CCZ 17)
9319 (compare:CCZ (lshiftrt:DI
9320 (neg:DI (ashift:DI
9321 (match_operand:DI 1 "register_operand" "0")
9322 (const_int 32)))
9323 (const_int 32))
9324 (const_int 0)))
9325 (set (match_operand:DI 0 "register_operand" "=r")
9326 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9327 (const_int 32)))
9328 (const_int 32)))]
9329 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9330 "neg{l}\t%k0"
9331 [(set_attr "type" "negnot")
9332 (set_attr "mode" "SI")])
9333
9334 (define_expand "neghi2"
9335 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9336 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9337 (clobber (reg:CC 17))])]
9338 "TARGET_HIMODE_MATH"
9339 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9340
9341 (define_insn "*neghi2_1"
9342 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9343 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9344 (clobber (reg:CC 17))]
9345 "ix86_unary_operator_ok (NEG, HImode, operands)"
9346 "neg{w}\t%0"
9347 [(set_attr "type" "negnot")
9348 (set_attr "mode" "HI")])
9349
9350 (define_insn "*neghi2_cmpz"
9351 [(set (reg:CCZ 17)
9352 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9353 (const_int 0)))
9354 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9355 (neg:HI (match_dup 1)))]
9356 "ix86_unary_operator_ok (NEG, HImode, operands)"
9357 "neg{w}\t%0"
9358 [(set_attr "type" "negnot")
9359 (set_attr "mode" "HI")])
9360
9361 (define_expand "negqi2"
9362 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9363 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9364 (clobber (reg:CC 17))])]
9365 "TARGET_QIMODE_MATH"
9366 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9367
9368 (define_insn "*negqi2_1"
9369 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9370 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9371 (clobber (reg:CC 17))]
9372 "ix86_unary_operator_ok (NEG, QImode, operands)"
9373 "neg{b}\t%0"
9374 [(set_attr "type" "negnot")
9375 (set_attr "mode" "QI")])
9376
9377 (define_insn "*negqi2_cmpz"
9378 [(set (reg:CCZ 17)
9379 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9380 (const_int 0)))
9381 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9382 (neg:QI (match_dup 1)))]
9383 "ix86_unary_operator_ok (NEG, QImode, operands)"
9384 "neg{b}\t%0"
9385 [(set_attr "type" "negnot")
9386 (set_attr "mode" "QI")])
9387
9388 ;; Changing of sign for FP values is doable using integer unit too.
9389
9390 (define_expand "negsf2"
9391 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9392 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9393 (clobber (reg:CC 17))])]
9394 "TARGET_80387"
9395 "if (TARGET_SSE)
9396 {
9397 /* In case operand is in memory, we will not use SSE. */
9398 if (memory_operand (operands[0], VOIDmode)
9399 && rtx_equal_p (operands[0], operands[1]))
9400 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9401 else
9402 {
9403 /* Using SSE is tricky, since we need bitwise negation of -0
9404 in register. */
9405 rtx reg = gen_reg_rtx (SFmode);
9406 rtx dest = operands[0];
9407 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9408
9409 operands[1] = force_reg (SFmode, operands[1]);
9410 operands[0] = force_reg (SFmode, operands[0]);
9411 reg = force_reg (V4SFmode,
9412 gen_rtx_CONST_VECTOR (V4SFmode,
9413 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9414 CONST0_RTX (SFmode),
9415 CONST0_RTX (SFmode))));
9416 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9417 if (dest != operands[0])
9418 emit_move_insn (dest, operands[0]);
9419 }
9420 DONE;
9421 }
9422 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9423
9424 (define_insn "negsf2_memory"
9425 [(set (match_operand:SF 0 "memory_operand" "=m")
9426 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9427 (clobber (reg:CC 17))]
9428 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9429 "#")
9430
9431 (define_insn "negsf2_ifs"
9432 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9433 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9434 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9435 (clobber (reg:CC 17))]
9436 "TARGET_SSE
9437 && (reload_in_progress || reload_completed
9438 || (register_operand (operands[0], VOIDmode)
9439 && register_operand (operands[1], VOIDmode)))"
9440 "#")
9441
9442 (define_split
9443 [(set (match_operand:SF 0 "memory_operand" "")
9444 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9445 (use (match_operand:SF 2 "" ""))
9446 (clobber (reg:CC 17))]
9447 ""
9448 [(parallel [(set (match_dup 0)
9449 (neg:SF (match_dup 1)))
9450 (clobber (reg:CC 17))])])
9451
9452 (define_split
9453 [(set (match_operand:SF 0 "register_operand" "")
9454 (neg:SF (match_operand:SF 1 "register_operand" "")))
9455 (use (match_operand:V4SF 2 "" ""))
9456 (clobber (reg:CC 17))]
9457 "reload_completed && !SSE_REG_P (operands[0])"
9458 [(parallel [(set (match_dup 0)
9459 (neg:SF (match_dup 1)))
9460 (clobber (reg:CC 17))])])
9461
9462 (define_split
9463 [(set (match_operand:SF 0 "register_operand" "")
9464 (neg:SF (match_operand:SF 1 "register_operand" "")))
9465 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9466 (clobber (reg:CC 17))]
9467 "reload_completed && SSE_REG_P (operands[0])"
9468 [(set (subreg:TI (match_dup 0) 0)
9469 (xor:TI (match_dup 1)
9470 (match_dup 2)))]
9471 {
9472 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9473 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9474 if (operands_match_p (operands[0], operands[2]))
9475 {
9476 rtx tmp;
9477 tmp = operands[1];
9478 operands[1] = operands[2];
9479 operands[2] = tmp;
9480 }
9481 })
9482
9483
9484 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9485 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9486 ;; to itself.
9487 (define_insn "*negsf2_if"
9488 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9489 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9490 (clobber (reg:CC 17))]
9491 "TARGET_80387 && !TARGET_SSE
9492 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9493 "#")
9494
9495 (define_split
9496 [(set (match_operand:SF 0 "fp_register_operand" "")
9497 (neg:SF (match_operand:SF 1 "register_operand" "")))
9498 (clobber (reg:CC 17))]
9499 "TARGET_80387 && reload_completed"
9500 [(set (match_dup 0)
9501 (neg:SF (match_dup 1)))]
9502 "")
9503
9504 (define_split
9505 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9506 (neg:SF (match_operand:SF 1 "register_operand" "")))
9507 (clobber (reg:CC 17))]
9508 "TARGET_80387 && reload_completed"
9509 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9510 (clobber (reg:CC 17))])]
9511 "operands[1] = gen_int_mode (0x80000000, SImode);
9512 operands[0] = gen_lowpart (SImode, operands[0]);")
9513
9514 (define_split
9515 [(set (match_operand 0 "memory_operand" "")
9516 (neg (match_operand 1 "memory_operand" "")))
9517 (clobber (reg:CC 17))]
9518 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9519 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9520 (clobber (reg:CC 17))])]
9521 {
9522 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9523
9524 if (GET_MODE (operands[1]) == XFmode)
9525 size = 10;
9526 operands[0] = adjust_address (operands[0], QImode, size - 1);
9527 operands[1] = gen_int_mode (0x80, QImode);
9528 })
9529
9530 (define_expand "negdf2"
9531 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9532 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9533 (clobber (reg:CC 17))])]
9534 "TARGET_80387"
9535 "if (TARGET_SSE2)
9536 {
9537 /* In case operand is in memory, we will not use SSE. */
9538 if (memory_operand (operands[0], VOIDmode)
9539 && rtx_equal_p (operands[0], operands[1]))
9540 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9541 else
9542 {
9543 /* Using SSE is tricky, since we need bitwise negation of -0
9544 in register. */
9545 rtx reg;
9546 #if HOST_BITS_PER_WIDE_INT >= 64
9547 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9548 #else
9549 rtx imm = immed_double_const (0, 0x80000000, DImode);
9550 #endif
9551 rtx dest = operands[0];
9552
9553 operands[1] = force_reg (DFmode, operands[1]);
9554 operands[0] = force_reg (DFmode, operands[0]);
9555 imm = gen_lowpart (DFmode, imm);
9556 reg = force_reg (V2DFmode,
9557 gen_rtx_CONST_VECTOR (V2DFmode,
9558 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9559 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9560 if (dest != operands[0])
9561 emit_move_insn (dest, operands[0]);
9562 }
9563 DONE;
9564 }
9565 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9566
9567 (define_insn "negdf2_memory"
9568 [(set (match_operand:DF 0 "memory_operand" "=m")
9569 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9570 (clobber (reg:CC 17))]
9571 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9572 "#")
9573
9574 (define_insn "negdf2_ifs"
9575 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9576 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9577 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9578 (clobber (reg:CC 17))]
9579 "!TARGET_64BIT && TARGET_SSE2
9580 && (reload_in_progress || reload_completed
9581 || (register_operand (operands[0], VOIDmode)
9582 && register_operand (operands[1], VOIDmode)))"
9583 "#")
9584
9585 (define_insn "*negdf2_ifs_rex64"
9586 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9587 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9588 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9589 (clobber (reg:CC 17))]
9590 "TARGET_64BIT && TARGET_SSE2
9591 && (reload_in_progress || reload_completed
9592 || (register_operand (operands[0], VOIDmode)
9593 && register_operand (operands[1], VOIDmode)))"
9594 "#")
9595
9596 (define_split
9597 [(set (match_operand:DF 0 "memory_operand" "")
9598 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9599 (use (match_operand:V2DF 2 "" ""))
9600 (clobber (reg:CC 17))]
9601 ""
9602 [(parallel [(set (match_dup 0)
9603 (neg:DF (match_dup 1)))
9604 (clobber (reg:CC 17))])])
9605
9606 (define_split
9607 [(set (match_operand:DF 0 "register_operand" "")
9608 (neg:DF (match_operand:DF 1 "register_operand" "")))
9609 (use (match_operand:V2DF 2 "" ""))
9610 (clobber (reg:CC 17))]
9611 "reload_completed && !SSE_REG_P (operands[0])
9612 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9613 [(parallel [(set (match_dup 0)
9614 (neg:DF (match_dup 1)))
9615 (clobber (reg:CC 17))])])
9616
9617 (define_split
9618 [(set (match_operand:DF 0 "register_operand" "")
9619 (neg:DF (match_operand:DF 1 "register_operand" "")))
9620 (use (match_operand:V2DF 2 "" ""))
9621 (clobber (reg:CC 17))]
9622 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9623 [(parallel [(set (match_dup 0)
9624 (xor:DI (match_dup 1) (match_dup 2)))
9625 (clobber (reg:CC 17))])]
9626 "operands[0] = gen_lowpart (DImode, operands[0]);
9627 operands[1] = gen_lowpart (DImode, operands[1]);
9628 operands[2] = gen_lowpart (DImode, operands[2]);")
9629
9630 (define_split
9631 [(set (match_operand:DF 0 "register_operand" "")
9632 (neg:DF (match_operand:DF 1 "register_operand" "")))
9633 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9634 (clobber (reg:CC 17))]
9635 "reload_completed && SSE_REG_P (operands[0])"
9636 [(set (subreg:TI (match_dup 0) 0)
9637 (xor:TI (match_dup 1)
9638 (match_dup 2)))]
9639 {
9640 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9641 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
9642 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9643 /* Avoid possible reformatting on the operands. */
9644 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9645 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9646 if (operands_match_p (operands[0], operands[2]))
9647 {
9648 rtx tmp;
9649 tmp = operands[1];
9650 operands[1] = operands[2];
9651 operands[2] = tmp;
9652 }
9653 })
9654
9655 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9656 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9657 ;; to itself.
9658 (define_insn "*negdf2_if"
9659 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9660 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9661 (clobber (reg:CC 17))]
9662 "!TARGET_64BIT && TARGET_80387
9663 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9664 "#")
9665
9666 ;; FIXME: We should to allow integer registers here. Problem is that
9667 ;; we need another scratch register to get constant from.
9668 ;; Forcing constant to mem if no register available in peep2 should be
9669 ;; safe even for PIC mode, because of RIP relative addressing.
9670 (define_insn "*negdf2_if_rex64"
9671 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9672 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9673 (clobber (reg:CC 17))]
9674 "TARGET_64BIT && TARGET_80387
9675 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9676 "#")
9677
9678 (define_split
9679 [(set (match_operand:DF 0 "fp_register_operand" "")
9680 (neg:DF (match_operand:DF 1 "register_operand" "")))
9681 (clobber (reg:CC 17))]
9682 "TARGET_80387 && reload_completed"
9683 [(set (match_dup 0)
9684 (neg:DF (match_dup 1)))]
9685 "")
9686
9687 (define_split
9688 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9689 (neg:DF (match_operand:DF 1 "register_operand" "")))
9690 (clobber (reg:CC 17))]
9691 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9692 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9693 (clobber (reg:CC 17))])]
9694 "operands[4] = gen_int_mode (0x80000000, SImode);
9695 split_di (operands+0, 1, operands+2, operands+3);")
9696
9697 (define_expand "negxf2"
9698 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9699 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9700 (clobber (reg:CC 17))])]
9701 "TARGET_80387"
9702 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9703
9704 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9705 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9706 ;; to itself.
9707 (define_insn "*negxf2_if"
9708 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9709 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9710 (clobber (reg:CC 17))]
9711 "TARGET_80387
9712 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9713 "#")
9714
9715 (define_split
9716 [(set (match_operand:XF 0 "fp_register_operand" "")
9717 (neg:XF (match_operand:XF 1 "register_operand" "")))
9718 (clobber (reg:CC 17))]
9719 "TARGET_80387 && reload_completed"
9720 [(set (match_dup 0)
9721 (neg:XF (match_dup 1)))]
9722 "")
9723
9724 (define_split
9725 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9726 (neg:XF (match_operand:XF 1 "register_operand" "")))
9727 (clobber (reg:CC 17))]
9728 "TARGET_80387 && reload_completed"
9729 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9730 (clobber (reg:CC 17))])]
9731 "operands[1] = GEN_INT (0x8000);
9732 operands[0] = gen_rtx_REG (SImode,
9733 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9734
9735 ;; Conditionalize these after reload. If they matches before reload, we
9736 ;; lose the clobber and ability to use integer instructions.
9737
9738 (define_insn "*negsf2_1"
9739 [(set (match_operand:SF 0 "register_operand" "=f")
9740 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9741 "TARGET_80387 && reload_completed"
9742 "fchs"
9743 [(set_attr "type" "fsgn")
9744 (set_attr "mode" "SF")
9745 (set_attr "ppro_uops" "few")])
9746
9747 (define_insn "*negdf2_1"
9748 [(set (match_operand:DF 0 "register_operand" "=f")
9749 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9750 "TARGET_80387 && reload_completed"
9751 "fchs"
9752 [(set_attr "type" "fsgn")
9753 (set_attr "mode" "DF")
9754 (set_attr "ppro_uops" "few")])
9755
9756 (define_insn "*negextendsfdf2"
9757 [(set (match_operand:DF 0 "register_operand" "=f")
9758 (neg:DF (float_extend:DF
9759 (match_operand:SF 1 "register_operand" "0"))))]
9760 "TARGET_80387"
9761 "fchs"
9762 [(set_attr "type" "fsgn")
9763 (set_attr "mode" "DF")
9764 (set_attr "ppro_uops" "few")])
9765
9766 (define_insn "*negxf2_1"
9767 [(set (match_operand:XF 0 "register_operand" "=f")
9768 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9769 "TARGET_80387 && reload_completed"
9770 "fchs"
9771 [(set_attr "type" "fsgn")
9772 (set_attr "mode" "XF")
9773 (set_attr "ppro_uops" "few")])
9774
9775 (define_insn "*negextenddfxf2"
9776 [(set (match_operand:XF 0 "register_operand" "=f")
9777 (neg:XF (float_extend:XF
9778 (match_operand:DF 1 "register_operand" "0"))))]
9779 "TARGET_80387"
9780 "fchs"
9781 [(set_attr "type" "fsgn")
9782 (set_attr "mode" "XF")
9783 (set_attr "ppro_uops" "few")])
9784
9785 (define_insn "*negextendsfxf2"
9786 [(set (match_operand:XF 0 "register_operand" "=f")
9787 (neg:XF (float_extend:XF
9788 (match_operand:SF 1 "register_operand" "0"))))]
9789 "TARGET_80387"
9790 "fchs"
9791 [(set_attr "type" "fsgn")
9792 (set_attr "mode" "XF")
9793 (set_attr "ppro_uops" "few")])
9794 \f
9795 ;; Absolute value instructions
9796
9797 (define_expand "abssf2"
9798 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9799 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9800 (clobber (reg:CC 17))])]
9801 "TARGET_80387"
9802 "if (TARGET_SSE)
9803 {
9804 /* In case operand is in memory, we will not use SSE. */
9805 if (memory_operand (operands[0], VOIDmode)
9806 && rtx_equal_p (operands[0], operands[1]))
9807 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9808 else
9809 {
9810 /* Using SSE is tricky, since we need bitwise negation of -0
9811 in register. */
9812 rtx reg = gen_reg_rtx (V4SFmode);
9813 rtx dest = operands[0];
9814 rtx imm;
9815
9816 operands[1] = force_reg (SFmode, operands[1]);
9817 operands[0] = force_reg (SFmode, operands[0]);
9818 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
9819 reg = force_reg (V4SFmode,
9820 gen_rtx_CONST_VECTOR (V4SFmode,
9821 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9822 CONST0_RTX (SFmode),
9823 CONST0_RTX (SFmode))));
9824 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
9825 if (dest != operands[0])
9826 emit_move_insn (dest, operands[0]);
9827 }
9828 DONE;
9829 }
9830 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
9831
9832 (define_insn "abssf2_memory"
9833 [(set (match_operand:SF 0 "memory_operand" "=m")
9834 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
9835 (clobber (reg:CC 17))]
9836 "ix86_unary_operator_ok (ABS, SFmode, operands)"
9837 "#")
9838
9839 (define_insn "abssf2_ifs"
9840 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9841 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9842 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9843 (clobber (reg:CC 17))]
9844 "TARGET_SSE
9845 && (reload_in_progress || reload_completed
9846 || (register_operand (operands[0], VOIDmode)
9847 && register_operand (operands[1], VOIDmode)))"
9848 "#")
9849
9850 (define_split
9851 [(set (match_operand:SF 0 "memory_operand" "")
9852 (abs:SF (match_operand:SF 1 "memory_operand" "")))
9853 (use (match_operand:V4SF 2 "" ""))
9854 (clobber (reg:CC 17))]
9855 ""
9856 [(parallel [(set (match_dup 0)
9857 (abs:SF (match_dup 1)))
9858 (clobber (reg:CC 17))])])
9859
9860 (define_split
9861 [(set (match_operand:SF 0 "register_operand" "")
9862 (abs:SF (match_operand:SF 1 "register_operand" "")))
9863 (use (match_operand:V4SF 2 "" ""))
9864 (clobber (reg:CC 17))]
9865 "reload_completed && !SSE_REG_P (operands[0])"
9866 [(parallel [(set (match_dup 0)
9867 (abs:SF (match_dup 1)))
9868 (clobber (reg:CC 17))])])
9869
9870 (define_split
9871 [(set (match_operand:SF 0 "register_operand" "")
9872 (abs:SF (match_operand:SF 1 "register_operand" "")))
9873 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9874 (clobber (reg:CC 17))]
9875 "reload_completed && SSE_REG_P (operands[0])"
9876 [(set (subreg:TI (match_dup 0) 0)
9877 (and:TI (match_dup 1)
9878 (match_dup 2)))]
9879 {
9880 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9881 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9882 if (operands_match_p (operands[0], operands[2]))
9883 {
9884 rtx tmp;
9885 tmp = operands[1];
9886 operands[1] = operands[2];
9887 operands[2] = tmp;
9888 }
9889 })
9890
9891 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9892 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9893 ;; to itself.
9894 (define_insn "*abssf2_if"
9895 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9896 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9897 (clobber (reg:CC 17))]
9898 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
9899 "#")
9900
9901 (define_split
9902 [(set (match_operand:SF 0 "fp_register_operand" "")
9903 (abs:SF (match_operand:SF 1 "register_operand" "")))
9904 (clobber (reg:CC 17))]
9905 "TARGET_80387 && reload_completed"
9906 [(set (match_dup 0)
9907 (abs:SF (match_dup 1)))]
9908 "")
9909
9910 (define_split
9911 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9912 (abs:SF (match_operand:SF 1 "register_operand" "")))
9913 (clobber (reg:CC 17))]
9914 "TARGET_80387 && reload_completed"
9915 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
9916 (clobber (reg:CC 17))])]
9917 "operands[1] = gen_int_mode (~0x80000000, SImode);
9918 operands[0] = gen_lowpart (SImode, operands[0]);")
9919
9920 (define_split
9921 [(set (match_operand 0 "memory_operand" "")
9922 (abs (match_operand 1 "memory_operand" "")))
9923 (clobber (reg:CC 17))]
9924 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9925 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
9926 (clobber (reg:CC 17))])]
9927 {
9928 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9929
9930 if (GET_MODE (operands[1]) == XFmode)
9931 size = 10;
9932 operands[0] = adjust_address (operands[0], QImode, size - 1);
9933 operands[1] = gen_int_mode (~0x80, QImode);
9934 })
9935
9936 (define_expand "absdf2"
9937 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9938 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9939 (clobber (reg:CC 17))])]
9940 "TARGET_80387"
9941 "if (TARGET_SSE2)
9942 {
9943 /* In case operand is in memory, we will not use SSE. */
9944 if (memory_operand (operands[0], VOIDmode)
9945 && rtx_equal_p (operands[0], operands[1]))
9946 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
9947 else
9948 {
9949 /* Using SSE is tricky, since we need bitwise negation of -0
9950 in register. */
9951 rtx reg = gen_reg_rtx (V2DFmode);
9952 #if HOST_BITS_PER_WIDE_INT >= 64
9953 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
9954 #else
9955 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
9956 #endif
9957 rtx dest = operands[0];
9958
9959 operands[1] = force_reg (DFmode, operands[1]);
9960 operands[0] = force_reg (DFmode, operands[0]);
9961
9962 /* Produce LONG_DOUBLE with the proper immediate argument. */
9963 imm = gen_lowpart (DFmode, imm);
9964 reg = force_reg (V2DFmode,
9965 gen_rtx_CONST_VECTOR (V2DFmode,
9966 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9967 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
9968 if (dest != operands[0])
9969 emit_move_insn (dest, operands[0]);
9970 }
9971 DONE;
9972 }
9973 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
9974
9975 (define_insn "absdf2_memory"
9976 [(set (match_operand:DF 0 "memory_operand" "=m")
9977 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
9978 (clobber (reg:CC 17))]
9979 "ix86_unary_operator_ok (ABS, DFmode, operands)"
9980 "#")
9981
9982 (define_insn "absdf2_ifs"
9983 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
9984 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9985 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9986 (clobber (reg:CC 17))]
9987 "!TARGET_64BIT && TARGET_SSE2
9988 && (reload_in_progress || reload_completed
9989 || (register_operand (operands[0], VOIDmode)
9990 && register_operand (operands[1], VOIDmode)))"
9991 "#")
9992
9993 (define_insn "*absdf2_ifs_rex64"
9994 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
9995 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9996 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9997 (clobber (reg:CC 17))]
9998 "TARGET_64BIT && TARGET_SSE2
9999 && (reload_in_progress || reload_completed
10000 || (register_operand (operands[0], VOIDmode)
10001 && register_operand (operands[1], VOIDmode)))"
10002 "#")
10003
10004 (define_split
10005 [(set (match_operand:DF 0 "memory_operand" "")
10006 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10007 (use (match_operand:V2DF 2 "" ""))
10008 (clobber (reg:CC 17))]
10009 ""
10010 [(parallel [(set (match_dup 0)
10011 (abs:DF (match_dup 1)))
10012 (clobber (reg:CC 17))])])
10013
10014 (define_split
10015 [(set (match_operand:DF 0 "register_operand" "")
10016 (abs:DF (match_operand:DF 1 "register_operand" "")))
10017 (use (match_operand:V2DF 2 "" ""))
10018 (clobber (reg:CC 17))]
10019 "reload_completed && !SSE_REG_P (operands[0])"
10020 [(parallel [(set (match_dup 0)
10021 (abs:DF (match_dup 1)))
10022 (clobber (reg:CC 17))])])
10023
10024 (define_split
10025 [(set (match_operand:DF 0 "register_operand" "")
10026 (abs:DF (match_operand:DF 1 "register_operand" "")))
10027 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10028 (clobber (reg:CC 17))]
10029 "reload_completed && SSE_REG_P (operands[0])"
10030 [(set (subreg:TI (match_dup 0) 0)
10031 (and:TI (match_dup 1)
10032 (match_dup 2)))]
10033 {
10034 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10035 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10036 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10037 /* Avoid possible reformatting on the operands. */
10038 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10039 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10040 if (operands_match_p (operands[0], operands[2]))
10041 {
10042 rtx tmp;
10043 tmp = operands[1];
10044 operands[1] = operands[2];
10045 operands[2] = tmp;
10046 }
10047 })
10048
10049
10050 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10051 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10052 ;; to itself.
10053 (define_insn "*absdf2_if"
10054 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10055 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10056 (clobber (reg:CC 17))]
10057 "!TARGET_64BIT && TARGET_80387
10058 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10059 "#")
10060
10061 ;; FIXME: We should to allow integer registers here. Problem is that
10062 ;; we need another scratch register to get constant from.
10063 ;; Forcing constant to mem if no register available in peep2 should be
10064 ;; safe even for PIC mode, because of RIP relative addressing.
10065 (define_insn "*absdf2_if_rex64"
10066 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10067 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10068 (clobber (reg:CC 17))]
10069 "TARGET_64BIT && TARGET_80387
10070 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10071 "#")
10072
10073 (define_split
10074 [(set (match_operand:DF 0 "fp_register_operand" "")
10075 (abs:DF (match_operand:DF 1 "register_operand" "")))
10076 (clobber (reg:CC 17))]
10077 "TARGET_80387 && reload_completed"
10078 [(set (match_dup 0)
10079 (abs:DF (match_dup 1)))]
10080 "")
10081
10082 (define_split
10083 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10084 (abs:DF (match_operand:DF 1 "register_operand" "")))
10085 (clobber (reg:CC 17))]
10086 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10087 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10088 (clobber (reg:CC 17))])]
10089 "operands[4] = gen_int_mode (~0x80000000, SImode);
10090 split_di (operands+0, 1, operands+2, operands+3);")
10091
10092 (define_expand "absxf2"
10093 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10094 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10095 (clobber (reg:CC 17))])]
10096 "TARGET_80387"
10097 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10098
10099 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10100 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10101 ;; to itself.
10102 (define_insn "*absxf2_if"
10103 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10104 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10105 (clobber (reg:CC 17))]
10106 "TARGET_80387
10107 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10108 "#")
10109
10110 (define_split
10111 [(set (match_operand:XF 0 "fp_register_operand" "")
10112 (abs:XF (match_operand:XF 1 "register_operand" "")))
10113 (clobber (reg:CC 17))]
10114 "TARGET_80387 && reload_completed"
10115 [(set (match_dup 0)
10116 (abs:XF (match_dup 1)))]
10117 "")
10118
10119 (define_split
10120 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10121 (abs:XF (match_operand:XF 1 "register_operand" "")))
10122 (clobber (reg:CC 17))]
10123 "TARGET_80387 && reload_completed"
10124 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10125 (clobber (reg:CC 17))])]
10126 "operands[1] = GEN_INT (~0x8000);
10127 operands[0] = gen_rtx_REG (SImode,
10128 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10129
10130 (define_insn "*abssf2_1"
10131 [(set (match_operand:SF 0 "register_operand" "=f")
10132 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10133 "TARGET_80387 && reload_completed"
10134 "fabs"
10135 [(set_attr "type" "fsgn")
10136 (set_attr "mode" "SF")])
10137
10138 (define_insn "*absdf2_1"
10139 [(set (match_operand:DF 0 "register_operand" "=f")
10140 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10141 "TARGET_80387 && reload_completed"
10142 "fabs"
10143 [(set_attr "type" "fsgn")
10144 (set_attr "mode" "DF")])
10145
10146 (define_insn "*absextendsfdf2"
10147 [(set (match_operand:DF 0 "register_operand" "=f")
10148 (abs:DF (float_extend:DF
10149 (match_operand:SF 1 "register_operand" "0"))))]
10150 "TARGET_80387"
10151 "fabs"
10152 [(set_attr "type" "fsgn")
10153 (set_attr "mode" "DF")])
10154
10155 (define_insn "*absxf2_1"
10156 [(set (match_operand:XF 0 "register_operand" "=f")
10157 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10158 "TARGET_80387 && reload_completed"
10159 "fabs"
10160 [(set_attr "type" "fsgn")
10161 (set_attr "mode" "DF")])
10162
10163 (define_insn "*absextenddfxf2"
10164 [(set (match_operand:XF 0 "register_operand" "=f")
10165 (abs:XF (float_extend:XF
10166 (match_operand:DF 1 "register_operand" "0"))))]
10167 "TARGET_80387"
10168 "fabs"
10169 [(set_attr "type" "fsgn")
10170 (set_attr "mode" "XF")])
10171
10172 (define_insn "*absextendsfxf2"
10173 [(set (match_operand:XF 0 "register_operand" "=f")
10174 (abs:XF (float_extend:XF
10175 (match_operand:SF 1 "register_operand" "0"))))]
10176 "TARGET_80387"
10177 "fabs"
10178 [(set_attr "type" "fsgn")
10179 (set_attr "mode" "XF")])
10180 \f
10181 ;; One complement instructions
10182
10183 (define_expand "one_cmpldi2"
10184 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10185 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10186 "TARGET_64BIT"
10187 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10188
10189 (define_insn "*one_cmpldi2_1_rex64"
10190 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10191 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10192 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10193 "not{q}\t%0"
10194 [(set_attr "type" "negnot")
10195 (set_attr "mode" "DI")])
10196
10197 (define_insn "*one_cmpldi2_2_rex64"
10198 [(set (reg 17)
10199 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10200 (const_int 0)))
10201 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10202 (not:DI (match_dup 1)))]
10203 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10204 && ix86_unary_operator_ok (NOT, DImode, operands)"
10205 "#"
10206 [(set_attr "type" "alu1")
10207 (set_attr "mode" "DI")])
10208
10209 (define_split
10210 [(set (reg 17)
10211 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10212 (const_int 0)))
10213 (set (match_operand:DI 0 "nonimmediate_operand" "")
10214 (not:DI (match_dup 1)))]
10215 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10216 [(parallel [(set (reg:CCNO 17)
10217 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10218 (const_int 0)))
10219 (set (match_dup 0)
10220 (xor:DI (match_dup 1) (const_int -1)))])]
10221 "")
10222
10223 (define_expand "one_cmplsi2"
10224 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10225 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10226 ""
10227 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10228
10229 (define_insn "*one_cmplsi2_1"
10230 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10231 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10232 "ix86_unary_operator_ok (NOT, SImode, operands)"
10233 "not{l}\t%0"
10234 [(set_attr "type" "negnot")
10235 (set_attr "mode" "SI")])
10236
10237 ;; ??? Currently never generated - xor is used instead.
10238 (define_insn "*one_cmplsi2_1_zext"
10239 [(set (match_operand:DI 0 "register_operand" "=r")
10240 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10241 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10242 "not{l}\t%k0"
10243 [(set_attr "type" "negnot")
10244 (set_attr "mode" "SI")])
10245
10246 (define_insn "*one_cmplsi2_2"
10247 [(set (reg 17)
10248 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10249 (const_int 0)))
10250 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10251 (not:SI (match_dup 1)))]
10252 "ix86_match_ccmode (insn, CCNOmode)
10253 && ix86_unary_operator_ok (NOT, SImode, operands)"
10254 "#"
10255 [(set_attr "type" "alu1")
10256 (set_attr "mode" "SI")])
10257
10258 (define_split
10259 [(set (reg 17)
10260 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10261 (const_int 0)))
10262 (set (match_operand:SI 0 "nonimmediate_operand" "")
10263 (not:SI (match_dup 1)))]
10264 "ix86_match_ccmode (insn, CCNOmode)"
10265 [(parallel [(set (reg:CCNO 17)
10266 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10267 (const_int 0)))
10268 (set (match_dup 0)
10269 (xor:SI (match_dup 1) (const_int -1)))])]
10270 "")
10271
10272 ;; ??? Currently never generated - xor is used instead.
10273 (define_insn "*one_cmplsi2_2_zext"
10274 [(set (reg 17)
10275 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10276 (const_int 0)))
10277 (set (match_operand:DI 0 "register_operand" "=r")
10278 (zero_extend:DI (not:SI (match_dup 1))))]
10279 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10280 && ix86_unary_operator_ok (NOT, SImode, operands)"
10281 "#"
10282 [(set_attr "type" "alu1")
10283 (set_attr "mode" "SI")])
10284
10285 (define_split
10286 [(set (reg 17)
10287 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10288 (const_int 0)))
10289 (set (match_operand:DI 0 "register_operand" "")
10290 (zero_extend:DI (not:SI (match_dup 1))))]
10291 "ix86_match_ccmode (insn, CCNOmode)"
10292 [(parallel [(set (reg:CCNO 17)
10293 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10294 (const_int 0)))
10295 (set (match_dup 0)
10296 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10297 "")
10298
10299 (define_expand "one_cmplhi2"
10300 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10301 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10302 "TARGET_HIMODE_MATH"
10303 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10304
10305 (define_insn "*one_cmplhi2_1"
10306 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10307 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10308 "ix86_unary_operator_ok (NOT, HImode, operands)"
10309 "not{w}\t%0"
10310 [(set_attr "type" "negnot")
10311 (set_attr "mode" "HI")])
10312
10313 (define_insn "*one_cmplhi2_2"
10314 [(set (reg 17)
10315 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10316 (const_int 0)))
10317 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10318 (not:HI (match_dup 1)))]
10319 "ix86_match_ccmode (insn, CCNOmode)
10320 && ix86_unary_operator_ok (NEG, HImode, operands)"
10321 "#"
10322 [(set_attr "type" "alu1")
10323 (set_attr "mode" "HI")])
10324
10325 (define_split
10326 [(set (reg 17)
10327 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10328 (const_int 0)))
10329 (set (match_operand:HI 0 "nonimmediate_operand" "")
10330 (not:HI (match_dup 1)))]
10331 "ix86_match_ccmode (insn, CCNOmode)"
10332 [(parallel [(set (reg:CCNO 17)
10333 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10334 (const_int 0)))
10335 (set (match_dup 0)
10336 (xor:HI (match_dup 1) (const_int -1)))])]
10337 "")
10338
10339 ;; %%% Potential partial reg stall on alternative 1. What to do?
10340 (define_expand "one_cmplqi2"
10341 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10342 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10343 "TARGET_QIMODE_MATH"
10344 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10345
10346 (define_insn "*one_cmplqi2_1"
10347 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10348 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10349 "ix86_unary_operator_ok (NOT, QImode, operands)"
10350 "@
10351 not{b}\t%0
10352 not{l}\t%k0"
10353 [(set_attr "type" "negnot")
10354 (set_attr "mode" "QI,SI")])
10355
10356 (define_insn "*one_cmplqi2_2"
10357 [(set (reg 17)
10358 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10359 (const_int 0)))
10360 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10361 (not:QI (match_dup 1)))]
10362 "ix86_match_ccmode (insn, CCNOmode)
10363 && ix86_unary_operator_ok (NOT, QImode, operands)"
10364 "#"
10365 [(set_attr "type" "alu1")
10366 (set_attr "mode" "QI")])
10367
10368 (define_split
10369 [(set (reg 17)
10370 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10371 (const_int 0)))
10372 (set (match_operand:QI 0 "nonimmediate_operand" "")
10373 (not:QI (match_dup 1)))]
10374 "ix86_match_ccmode (insn, CCNOmode)"
10375 [(parallel [(set (reg:CCNO 17)
10376 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10377 (const_int 0)))
10378 (set (match_dup 0)
10379 (xor:QI (match_dup 1) (const_int -1)))])]
10380 "")
10381 \f
10382 ;; Arithmetic shift instructions
10383
10384 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10385 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10386 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10387 ;; from the assembler input.
10388 ;;
10389 ;; This instruction shifts the target reg/mem as usual, but instead of
10390 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10391 ;; is a left shift double, bits are taken from the high order bits of
10392 ;; reg, else if the insn is a shift right double, bits are taken from the
10393 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10394 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10395 ;;
10396 ;; Since sh[lr]d does not change the `reg' operand, that is done
10397 ;; separately, making all shifts emit pairs of shift double and normal
10398 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10399 ;; support a 63 bit shift, each shift where the count is in a reg expands
10400 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10401 ;;
10402 ;; If the shift count is a constant, we need never emit more than one
10403 ;; shift pair, instead using moves and sign extension for counts greater
10404 ;; than 31.
10405
10406 (define_expand "ashldi3"
10407 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10408 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10409 (match_operand:QI 2 "nonmemory_operand" "")))
10410 (clobber (reg:CC 17))])]
10411 ""
10412 {
10413 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10414 {
10415 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10416 DONE;
10417 }
10418 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10419 DONE;
10420 })
10421
10422 (define_insn "*ashldi3_1_rex64"
10423 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10424 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10425 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10426 (clobber (reg:CC 17))]
10427 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10428 {
10429 switch (get_attr_type (insn))
10430 {
10431 case TYPE_ALU:
10432 if (operands[2] != const1_rtx)
10433 abort ();
10434 if (!rtx_equal_p (operands[0], operands[1]))
10435 abort ();
10436 return "add{q}\t{%0, %0|%0, %0}";
10437
10438 case TYPE_LEA:
10439 if (GET_CODE (operands[2]) != CONST_INT
10440 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10441 abort ();
10442 operands[1] = gen_rtx_MULT (DImode, operands[1],
10443 GEN_INT (1 << INTVAL (operands[2])));
10444 return "lea{q}\t{%a1, %0|%0, %a1}";
10445
10446 default:
10447 if (REG_P (operands[2]))
10448 return "sal{q}\t{%b2, %0|%0, %b2}";
10449 else if (GET_CODE (operands[2]) == CONST_INT
10450 && INTVAL (operands[2]) == 1
10451 && (TARGET_SHIFT1 || optimize_size))
10452 return "sal{q}\t%0";
10453 else
10454 return "sal{q}\t{%2, %0|%0, %2}";
10455 }
10456 }
10457 [(set (attr "type")
10458 (cond [(eq_attr "alternative" "1")
10459 (const_string "lea")
10460 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10461 (const_int 0))
10462 (match_operand 0 "register_operand" ""))
10463 (match_operand 2 "const1_operand" ""))
10464 (const_string "alu")
10465 ]
10466 (const_string "ishift")))
10467 (set_attr "mode" "DI")])
10468
10469 ;; Convert lea to the lea pattern to avoid flags dependency.
10470 (define_split
10471 [(set (match_operand:DI 0 "register_operand" "")
10472 (ashift:DI (match_operand:DI 1 "register_operand" "")
10473 (match_operand:QI 2 "immediate_operand" "")))
10474 (clobber (reg:CC 17))]
10475 "TARGET_64BIT && reload_completed
10476 && true_regnum (operands[0]) != true_regnum (operands[1])"
10477 [(set (match_dup 0)
10478 (mult:DI (match_dup 1)
10479 (match_dup 2)))]
10480 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10481
10482 ;; This pattern can't accept a variable shift count, since shifts by
10483 ;; zero don't affect the flags. We assume that shifts by constant
10484 ;; zero are optimized away.
10485 (define_insn "*ashldi3_cmp_rex64"
10486 [(set (reg 17)
10487 (compare
10488 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10489 (match_operand:QI 2 "immediate_operand" "e"))
10490 (const_int 0)))
10491 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10492 (ashift:DI (match_dup 1) (match_dup 2)))]
10493 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10494 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10495 {
10496 switch (get_attr_type (insn))
10497 {
10498 case TYPE_ALU:
10499 if (operands[2] != const1_rtx)
10500 abort ();
10501 return "add{q}\t{%0, %0|%0, %0}";
10502
10503 default:
10504 if (REG_P (operands[2]))
10505 return "sal{q}\t{%b2, %0|%0, %b2}";
10506 else if (GET_CODE (operands[2]) == CONST_INT
10507 && INTVAL (operands[2]) == 1
10508 && (TARGET_SHIFT1 || optimize_size))
10509 return "sal{q}\t%0";
10510 else
10511 return "sal{q}\t{%2, %0|%0, %2}";
10512 }
10513 }
10514 [(set (attr "type")
10515 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10516 (const_int 0))
10517 (match_operand 0 "register_operand" ""))
10518 (match_operand 2 "const1_operand" ""))
10519 (const_string "alu")
10520 ]
10521 (const_string "ishift")))
10522 (set_attr "mode" "DI")])
10523
10524 (define_insn "ashldi3_1"
10525 [(set (match_operand:DI 0 "register_operand" "=r")
10526 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10527 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10528 (clobber (match_scratch:SI 3 "=&r"))
10529 (clobber (reg:CC 17))]
10530 "!TARGET_64BIT && TARGET_CMOVE"
10531 "#"
10532 [(set_attr "type" "multi")])
10533
10534 (define_insn "*ashldi3_2"
10535 [(set (match_operand:DI 0 "register_operand" "=r")
10536 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10537 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10538 (clobber (reg:CC 17))]
10539 "!TARGET_64BIT"
10540 "#"
10541 [(set_attr "type" "multi")])
10542
10543 (define_split
10544 [(set (match_operand:DI 0 "register_operand" "")
10545 (ashift:DI (match_operand:DI 1 "register_operand" "")
10546 (match_operand:QI 2 "nonmemory_operand" "")))
10547 (clobber (match_scratch:SI 3 ""))
10548 (clobber (reg:CC 17))]
10549 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10550 [(const_int 0)]
10551 "ix86_split_ashldi (operands, operands[3]); DONE;")
10552
10553 (define_split
10554 [(set (match_operand:DI 0 "register_operand" "")
10555 (ashift:DI (match_operand:DI 1 "register_operand" "")
10556 (match_operand:QI 2 "nonmemory_operand" "")))
10557 (clobber (reg:CC 17))]
10558 "!TARGET_64BIT && reload_completed"
10559 [(const_int 0)]
10560 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10561
10562 (define_insn "x86_shld_1"
10563 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10564 (ior:SI (ashift:SI (match_dup 0)
10565 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10566 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10567 (minus:QI (const_int 32) (match_dup 2)))))
10568 (clobber (reg:CC 17))]
10569 ""
10570 "@
10571 shld{l}\t{%2, %1, %0|%0, %1, %2}
10572 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10573 [(set_attr "type" "ishift")
10574 (set_attr "prefix_0f" "1")
10575 (set_attr "mode" "SI")
10576 (set_attr "pent_pair" "np")
10577 (set_attr "athlon_decode" "vector")
10578 (set_attr "ppro_uops" "few")])
10579
10580 (define_expand "x86_shift_adj_1"
10581 [(set (reg:CCZ 17)
10582 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10583 (const_int 32))
10584 (const_int 0)))
10585 (set (match_operand:SI 0 "register_operand" "")
10586 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10587 (match_operand:SI 1 "register_operand" "")
10588 (match_dup 0)))
10589 (set (match_dup 1)
10590 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10591 (match_operand:SI 3 "register_operand" "r")
10592 (match_dup 1)))]
10593 "TARGET_CMOVE"
10594 "")
10595
10596 (define_expand "x86_shift_adj_2"
10597 [(use (match_operand:SI 0 "register_operand" ""))
10598 (use (match_operand:SI 1 "register_operand" ""))
10599 (use (match_operand:QI 2 "register_operand" ""))]
10600 ""
10601 {
10602 rtx label = gen_label_rtx ();
10603 rtx tmp;
10604
10605 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10606
10607 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10608 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10609 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10610 gen_rtx_LABEL_REF (VOIDmode, label),
10611 pc_rtx);
10612 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10613 JUMP_LABEL (tmp) = label;
10614
10615 emit_move_insn (operands[0], operands[1]);
10616 emit_move_insn (operands[1], const0_rtx);
10617
10618 emit_label (label);
10619 LABEL_NUSES (label) = 1;
10620
10621 DONE;
10622 })
10623
10624 (define_expand "ashlsi3"
10625 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10626 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10627 (match_operand:QI 2 "nonmemory_operand" "")))
10628 (clobber (reg:CC 17))]
10629 ""
10630 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10631
10632 (define_insn "*ashlsi3_1"
10633 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10634 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10635 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10636 (clobber (reg:CC 17))]
10637 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10638 {
10639 switch (get_attr_type (insn))
10640 {
10641 case TYPE_ALU:
10642 if (operands[2] != const1_rtx)
10643 abort ();
10644 if (!rtx_equal_p (operands[0], operands[1]))
10645 abort ();
10646 return "add{l}\t{%0, %0|%0, %0}";
10647
10648 case TYPE_LEA:
10649 return "#";
10650
10651 default:
10652 if (REG_P (operands[2]))
10653 return "sal{l}\t{%b2, %0|%0, %b2}";
10654 else if (GET_CODE (operands[2]) == CONST_INT
10655 && INTVAL (operands[2]) == 1
10656 && (TARGET_SHIFT1 || optimize_size))
10657 return "sal{l}\t%0";
10658 else
10659 return "sal{l}\t{%2, %0|%0, %2}";
10660 }
10661 }
10662 [(set (attr "type")
10663 (cond [(eq_attr "alternative" "1")
10664 (const_string "lea")
10665 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10666 (const_int 0))
10667 (match_operand 0 "register_operand" ""))
10668 (match_operand 2 "const1_operand" ""))
10669 (const_string "alu")
10670 ]
10671 (const_string "ishift")))
10672 (set_attr "mode" "SI")])
10673
10674 ;; Convert lea to the lea pattern to avoid flags dependency.
10675 (define_split
10676 [(set (match_operand 0 "register_operand" "")
10677 (ashift (match_operand 1 "index_register_operand" "")
10678 (match_operand:QI 2 "const_int_operand" "")))
10679 (clobber (reg:CC 17))]
10680 "reload_completed
10681 && true_regnum (operands[0]) != true_regnum (operands[1])"
10682 [(const_int 0)]
10683 {
10684 rtx pat;
10685 operands[0] = gen_lowpart (SImode, operands[0]);
10686 operands[1] = gen_lowpart (Pmode, operands[1]);
10687 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10688 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10689 if (Pmode != SImode)
10690 pat = gen_rtx_SUBREG (SImode, pat, 0);
10691 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10692 DONE;
10693 })
10694
10695 ;; Rare case of shifting RSP is handled by generating move and shift
10696 (define_split
10697 [(set (match_operand 0 "register_operand" "")
10698 (ashift (match_operand 1 "register_operand" "")
10699 (match_operand:QI 2 "const_int_operand" "")))
10700 (clobber (reg:CC 17))]
10701 "reload_completed
10702 && true_regnum (operands[0]) != true_regnum (operands[1])"
10703 [(const_int 0)]
10704 {
10705 rtx pat, clob;
10706 emit_move_insn (operands[1], operands[0]);
10707 pat = gen_rtx_SET (VOIDmode, operands[0],
10708 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10709 operands[0], operands[2]));
10710 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10711 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10712 DONE;
10713 })
10714
10715 (define_insn "*ashlsi3_1_zext"
10716 [(set (match_operand:DI 0 "register_operand" "=r,r")
10717 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10718 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10719 (clobber (reg:CC 17))]
10720 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10721 {
10722 switch (get_attr_type (insn))
10723 {
10724 case TYPE_ALU:
10725 if (operands[2] != const1_rtx)
10726 abort ();
10727 return "add{l}\t{%k0, %k0|%k0, %k0}";
10728
10729 case TYPE_LEA:
10730 return "#";
10731
10732 default:
10733 if (REG_P (operands[2]))
10734 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735 else if (GET_CODE (operands[2]) == CONST_INT
10736 && INTVAL (operands[2]) == 1
10737 && (TARGET_SHIFT1 || optimize_size))
10738 return "sal{l}\t%k0";
10739 else
10740 return "sal{l}\t{%2, %k0|%k0, %2}";
10741 }
10742 }
10743 [(set (attr "type")
10744 (cond [(eq_attr "alternative" "1")
10745 (const_string "lea")
10746 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747 (const_int 0))
10748 (match_operand 2 "const1_operand" ""))
10749 (const_string "alu")
10750 ]
10751 (const_string "ishift")))
10752 (set_attr "mode" "SI")])
10753
10754 ;; Convert lea to the lea pattern to avoid flags dependency.
10755 (define_split
10756 [(set (match_operand:DI 0 "register_operand" "")
10757 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10758 (match_operand:QI 2 "const_int_operand" ""))))
10759 (clobber (reg:CC 17))]
10760 "TARGET_64BIT && reload_completed
10761 && true_regnum (operands[0]) != true_regnum (operands[1])"
10762 [(set (match_dup 0) (zero_extend:DI
10763 (subreg:SI (mult:SI (match_dup 1)
10764 (match_dup 2)) 0)))]
10765 {
10766 operands[1] = gen_lowpart (Pmode, operands[1]);
10767 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10768 })
10769
10770 ;; This pattern can't accept a variable shift count, since shifts by
10771 ;; zero don't affect the flags. We assume that shifts by constant
10772 ;; zero are optimized away.
10773 (define_insn "*ashlsi3_cmp"
10774 [(set (reg 17)
10775 (compare
10776 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10777 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10778 (const_int 0)))
10779 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10780 (ashift:SI (match_dup 1) (match_dup 2)))]
10781 "ix86_match_ccmode (insn, CCGOCmode)
10782 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10783 {
10784 switch (get_attr_type (insn))
10785 {
10786 case TYPE_ALU:
10787 if (operands[2] != const1_rtx)
10788 abort ();
10789 return "add{l}\t{%0, %0|%0, %0}";
10790
10791 default:
10792 if (REG_P (operands[2]))
10793 return "sal{l}\t{%b2, %0|%0, %b2}";
10794 else if (GET_CODE (operands[2]) == CONST_INT
10795 && INTVAL (operands[2]) == 1
10796 && (TARGET_SHIFT1 || optimize_size))
10797 return "sal{l}\t%0";
10798 else
10799 return "sal{l}\t{%2, %0|%0, %2}";
10800 }
10801 }
10802 [(set (attr "type")
10803 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10804 (const_int 0))
10805 (match_operand 0 "register_operand" ""))
10806 (match_operand 2 "const1_operand" ""))
10807 (const_string "alu")
10808 ]
10809 (const_string "ishift")))
10810 (set_attr "mode" "SI")])
10811
10812 (define_insn "*ashlsi3_cmp_zext"
10813 [(set (reg 17)
10814 (compare
10815 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10816 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10817 (const_int 0)))
10818 (set (match_operand:DI 0 "register_operand" "=r")
10819 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10820 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10821 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10822 {
10823 switch (get_attr_type (insn))
10824 {
10825 case TYPE_ALU:
10826 if (operands[2] != const1_rtx)
10827 abort ();
10828 return "add{l}\t{%k0, %k0|%k0, %k0}";
10829
10830 default:
10831 if (REG_P (operands[2]))
10832 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10833 else if (GET_CODE (operands[2]) == CONST_INT
10834 && INTVAL (operands[2]) == 1
10835 && (TARGET_SHIFT1 || optimize_size))
10836 return "sal{l}\t%k0";
10837 else
10838 return "sal{l}\t{%2, %k0|%k0, %2}";
10839 }
10840 }
10841 [(set (attr "type")
10842 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10843 (const_int 0))
10844 (match_operand 2 "const1_operand" ""))
10845 (const_string "alu")
10846 ]
10847 (const_string "ishift")))
10848 (set_attr "mode" "SI")])
10849
10850 (define_expand "ashlhi3"
10851 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10852 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10853 (match_operand:QI 2 "nonmemory_operand" "")))
10854 (clobber (reg:CC 17))]
10855 "TARGET_HIMODE_MATH"
10856 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10857
10858 (define_insn "*ashlhi3_1_lea"
10859 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10860 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
10861 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10862 (clobber (reg:CC 17))]
10863 "!TARGET_PARTIAL_REG_STALL
10864 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10865 {
10866 switch (get_attr_type (insn))
10867 {
10868 case TYPE_LEA:
10869 return "#";
10870 case TYPE_ALU:
10871 if (operands[2] != const1_rtx)
10872 abort ();
10873 return "add{w}\t{%0, %0|%0, %0}";
10874
10875 default:
10876 if (REG_P (operands[2]))
10877 return "sal{w}\t{%b2, %0|%0, %b2}";
10878 else if (GET_CODE (operands[2]) == CONST_INT
10879 && INTVAL (operands[2]) == 1
10880 && (TARGET_SHIFT1 || optimize_size))
10881 return "sal{w}\t%0";
10882 else
10883 return "sal{w}\t{%2, %0|%0, %2}";
10884 }
10885 }
10886 [(set (attr "type")
10887 (cond [(eq_attr "alternative" "1")
10888 (const_string "lea")
10889 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890 (const_int 0))
10891 (match_operand 0 "register_operand" ""))
10892 (match_operand 2 "const1_operand" ""))
10893 (const_string "alu")
10894 ]
10895 (const_string "ishift")))
10896 (set_attr "mode" "HI,SI")])
10897
10898 (define_insn "*ashlhi3_1"
10899 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10900 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10901 (match_operand:QI 2 "nonmemory_operand" "cI")))
10902 (clobber (reg:CC 17))]
10903 "TARGET_PARTIAL_REG_STALL
10904 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10905 {
10906 switch (get_attr_type (insn))
10907 {
10908 case TYPE_ALU:
10909 if (operands[2] != const1_rtx)
10910 abort ();
10911 return "add{w}\t{%0, %0|%0, %0}";
10912
10913 default:
10914 if (REG_P (operands[2]))
10915 return "sal{w}\t{%b2, %0|%0, %b2}";
10916 else if (GET_CODE (operands[2]) == CONST_INT
10917 && INTVAL (operands[2]) == 1
10918 && (TARGET_SHIFT1 || optimize_size))
10919 return "sal{w}\t%0";
10920 else
10921 return "sal{w}\t{%2, %0|%0, %2}";
10922 }
10923 }
10924 [(set (attr "type")
10925 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10926 (const_int 0))
10927 (match_operand 0 "register_operand" ""))
10928 (match_operand 2 "const1_operand" ""))
10929 (const_string "alu")
10930 ]
10931 (const_string "ishift")))
10932 (set_attr "mode" "HI")])
10933
10934 ;; This pattern can't accept a variable shift count, since shifts by
10935 ;; zero don't affect the flags. We assume that shifts by constant
10936 ;; zero are optimized away.
10937 (define_insn "*ashlhi3_cmp"
10938 [(set (reg 17)
10939 (compare
10940 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10941 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10942 (const_int 0)))
10943 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944 (ashift:HI (match_dup 1) (match_dup 2)))]
10945 "ix86_match_ccmode (insn, CCGOCmode)
10946 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10947 {
10948 switch (get_attr_type (insn))
10949 {
10950 case TYPE_ALU:
10951 if (operands[2] != const1_rtx)
10952 abort ();
10953 return "add{w}\t{%0, %0|%0, %0}";
10954
10955 default:
10956 if (REG_P (operands[2]))
10957 return "sal{w}\t{%b2, %0|%0, %b2}";
10958 else if (GET_CODE (operands[2]) == CONST_INT
10959 && INTVAL (operands[2]) == 1
10960 && (TARGET_SHIFT1 || optimize_size))
10961 return "sal{w}\t%0";
10962 else
10963 return "sal{w}\t{%2, %0|%0, %2}";
10964 }
10965 }
10966 [(set (attr "type")
10967 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968 (const_int 0))
10969 (match_operand 0 "register_operand" ""))
10970 (match_operand 2 "const1_operand" ""))
10971 (const_string "alu")
10972 ]
10973 (const_string "ishift")))
10974 (set_attr "mode" "HI")])
10975
10976 (define_expand "ashlqi3"
10977 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10978 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10979 (match_operand:QI 2 "nonmemory_operand" "")))
10980 (clobber (reg:CC 17))]
10981 "TARGET_QIMODE_MATH"
10982 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10983
10984 ;; %%% Potential partial reg stall on alternative 2. What to do?
10985
10986 (define_insn "*ashlqi3_1_lea"
10987 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10988 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
10989 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10990 (clobber (reg:CC 17))]
10991 "!TARGET_PARTIAL_REG_STALL
10992 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10993 {
10994 switch (get_attr_type (insn))
10995 {
10996 case TYPE_LEA:
10997 return "#";
10998 case TYPE_ALU:
10999 if (operands[2] != const1_rtx)
11000 abort ();
11001 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11002 return "add{l}\t{%k0, %k0|%k0, %k0}";
11003 else
11004 return "add{b}\t{%0, %0|%0, %0}";
11005
11006 default:
11007 if (REG_P (operands[2]))
11008 {
11009 if (get_attr_mode (insn) == MODE_SI)
11010 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11011 else
11012 return "sal{b}\t{%b2, %0|%0, %b2}";
11013 }
11014 else if (GET_CODE (operands[2]) == CONST_INT
11015 && INTVAL (operands[2]) == 1
11016 && (TARGET_SHIFT1 || optimize_size))
11017 {
11018 if (get_attr_mode (insn) == MODE_SI)
11019 return "sal{l}\t%0";
11020 else
11021 return "sal{b}\t%0";
11022 }
11023 else
11024 {
11025 if (get_attr_mode (insn) == MODE_SI)
11026 return "sal{l}\t{%2, %k0|%k0, %2}";
11027 else
11028 return "sal{b}\t{%2, %0|%0, %2}";
11029 }
11030 }
11031 }
11032 [(set (attr "type")
11033 (cond [(eq_attr "alternative" "2")
11034 (const_string "lea")
11035 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11036 (const_int 0))
11037 (match_operand 0 "register_operand" ""))
11038 (match_operand 2 "const1_operand" ""))
11039 (const_string "alu")
11040 ]
11041 (const_string "ishift")))
11042 (set_attr "mode" "QI,SI,SI")])
11043
11044 (define_insn "*ashlqi3_1"
11045 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11046 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11047 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11048 (clobber (reg:CC 17))]
11049 "TARGET_PARTIAL_REG_STALL
11050 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11051 {
11052 switch (get_attr_type (insn))
11053 {
11054 case TYPE_ALU:
11055 if (operands[2] != const1_rtx)
11056 abort ();
11057 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11058 return "add{l}\t{%k0, %k0|%k0, %k0}";
11059 else
11060 return "add{b}\t{%0, %0|%0, %0}";
11061
11062 default:
11063 if (REG_P (operands[2]))
11064 {
11065 if (get_attr_mode (insn) == MODE_SI)
11066 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11067 else
11068 return "sal{b}\t{%b2, %0|%0, %b2}";
11069 }
11070 else if (GET_CODE (operands[2]) == CONST_INT
11071 && INTVAL (operands[2]) == 1
11072 && (TARGET_SHIFT1 || optimize_size))
11073 {
11074 if (get_attr_mode (insn) == MODE_SI)
11075 return "sal{l}\t%0";
11076 else
11077 return "sal{b}\t%0";
11078 }
11079 else
11080 {
11081 if (get_attr_mode (insn) == MODE_SI)
11082 return "sal{l}\t{%2, %k0|%k0, %2}";
11083 else
11084 return "sal{b}\t{%2, %0|%0, %2}";
11085 }
11086 }
11087 }
11088 [(set (attr "type")
11089 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11090 (const_int 0))
11091 (match_operand 0 "register_operand" ""))
11092 (match_operand 2 "const1_operand" ""))
11093 (const_string "alu")
11094 ]
11095 (const_string "ishift")))
11096 (set_attr "mode" "QI,SI")])
11097
11098 ;; This pattern can't accept a variable shift count, since shifts by
11099 ;; zero don't affect the flags. We assume that shifts by constant
11100 ;; zero are optimized away.
11101 (define_insn "*ashlqi3_cmp"
11102 [(set (reg 17)
11103 (compare
11104 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11105 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11106 (const_int 0)))
11107 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11108 (ashift:QI (match_dup 1) (match_dup 2)))]
11109 "ix86_match_ccmode (insn, CCGOCmode)
11110 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11111 {
11112 switch (get_attr_type (insn))
11113 {
11114 case TYPE_ALU:
11115 if (operands[2] != const1_rtx)
11116 abort ();
11117 return "add{b}\t{%0, %0|%0, %0}";
11118
11119 default:
11120 if (REG_P (operands[2]))
11121 return "sal{b}\t{%b2, %0|%0, %b2}";
11122 else if (GET_CODE (operands[2]) == CONST_INT
11123 && INTVAL (operands[2]) == 1
11124 && (TARGET_SHIFT1 || optimize_size))
11125 return "sal{b}\t%0";
11126 else
11127 return "sal{b}\t{%2, %0|%0, %2}";
11128 }
11129 }
11130 [(set (attr "type")
11131 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11132 (const_int 0))
11133 (match_operand 0 "register_operand" ""))
11134 (match_operand 2 "const1_operand" ""))
11135 (const_string "alu")
11136 ]
11137 (const_string "ishift")))
11138 (set_attr "mode" "QI")])
11139
11140 ;; See comment above `ashldi3' about how this works.
11141
11142 (define_expand "ashrdi3"
11143 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11144 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11145 (match_operand:QI 2 "nonmemory_operand" "")))
11146 (clobber (reg:CC 17))])]
11147 ""
11148 {
11149 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11150 {
11151 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11152 DONE;
11153 }
11154 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11155 DONE;
11156 })
11157
11158 (define_insn "ashrdi3_63_rex64"
11159 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11160 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11161 (match_operand:DI 2 "const_int_operand" "i,i")))
11162 (clobber (reg:CC 17))]
11163 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11164 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11165 "@
11166 {cqto|cqo}
11167 sar{q}\t{%2, %0|%0, %2}"
11168 [(set_attr "type" "imovx,ishift")
11169 (set_attr "prefix_0f" "0,*")
11170 (set_attr "length_immediate" "0,*")
11171 (set_attr "modrm" "0,1")
11172 (set_attr "mode" "DI")])
11173
11174 (define_insn "*ashrdi3_1_one_bit_rex64"
11175 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11176 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11177 (match_operand:QI 2 "const_int_1_operand" "")))
11178 (clobber (reg:CC 17))]
11179 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11180 && (TARGET_SHIFT1 || optimize_size)"
11181 "sar{q}\t%0"
11182 [(set_attr "type" "ishift")
11183 (set (attr "length")
11184 (if_then_else (match_operand:DI 0 "register_operand" "")
11185 (const_string "2")
11186 (const_string "*")))])
11187
11188 (define_insn "*ashrdi3_1_rex64"
11189 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11190 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11191 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11192 (clobber (reg:CC 17))]
11193 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11194 "@
11195 sar{q}\t{%2, %0|%0, %2}
11196 sar{q}\t{%b2, %0|%0, %b2}"
11197 [(set_attr "type" "ishift")
11198 (set_attr "mode" "DI")])
11199
11200 ;; This pattern can't accept a variable shift count, since shifts by
11201 ;; zero don't affect the flags. We assume that shifts by constant
11202 ;; zero are optimized away.
11203 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11204 [(set (reg 17)
11205 (compare
11206 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11207 (match_operand:QI 2 "const_int_1_operand" ""))
11208 (const_int 0)))
11209 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11210 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11211 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11212 && (TARGET_SHIFT1 || optimize_size)
11213 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11214 "sar{q}\t%0"
11215 [(set_attr "type" "ishift")
11216 (set (attr "length")
11217 (if_then_else (match_operand:DI 0 "register_operand" "")
11218 (const_string "2")
11219 (const_string "*")))])
11220
11221 ;; This pattern can't accept a variable shift count, since shifts by
11222 ;; zero don't affect the flags. We assume that shifts by constant
11223 ;; zero are optimized away.
11224 (define_insn "*ashrdi3_cmp_rex64"
11225 [(set (reg 17)
11226 (compare
11227 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11228 (match_operand:QI 2 "const_int_operand" "n"))
11229 (const_int 0)))
11230 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11231 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11232 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11233 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11234 "sar{q}\t{%2, %0|%0, %2}"
11235 [(set_attr "type" "ishift")
11236 (set_attr "mode" "DI")])
11237
11238
11239 (define_insn "ashrdi3_1"
11240 [(set (match_operand:DI 0 "register_operand" "=r")
11241 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11242 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11243 (clobber (match_scratch:SI 3 "=&r"))
11244 (clobber (reg:CC 17))]
11245 "!TARGET_64BIT && TARGET_CMOVE"
11246 "#"
11247 [(set_attr "type" "multi")])
11248
11249 (define_insn "*ashrdi3_2"
11250 [(set (match_operand:DI 0 "register_operand" "=r")
11251 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11252 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11253 (clobber (reg:CC 17))]
11254 "!TARGET_64BIT"
11255 "#"
11256 [(set_attr "type" "multi")])
11257
11258 (define_split
11259 [(set (match_operand:DI 0 "register_operand" "")
11260 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11261 (match_operand:QI 2 "nonmemory_operand" "")))
11262 (clobber (match_scratch:SI 3 ""))
11263 (clobber (reg:CC 17))]
11264 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11265 [(const_int 0)]
11266 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11267
11268 (define_split
11269 [(set (match_operand:DI 0 "register_operand" "")
11270 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11271 (match_operand:QI 2 "nonmemory_operand" "")))
11272 (clobber (reg:CC 17))]
11273 "!TARGET_64BIT && reload_completed"
11274 [(const_int 0)]
11275 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11276
11277 (define_insn "x86_shrd_1"
11278 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11279 (ior:SI (ashiftrt:SI (match_dup 0)
11280 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11281 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11282 (minus:QI (const_int 32) (match_dup 2)))))
11283 (clobber (reg:CC 17))]
11284 ""
11285 "@
11286 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11287 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11288 [(set_attr "type" "ishift")
11289 (set_attr "prefix_0f" "1")
11290 (set_attr "pent_pair" "np")
11291 (set_attr "ppro_uops" "few")
11292 (set_attr "mode" "SI")])
11293
11294 (define_expand "x86_shift_adj_3"
11295 [(use (match_operand:SI 0 "register_operand" ""))
11296 (use (match_operand:SI 1 "register_operand" ""))
11297 (use (match_operand:QI 2 "register_operand" ""))]
11298 ""
11299 {
11300 rtx label = gen_label_rtx ();
11301 rtx tmp;
11302
11303 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11304
11305 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11306 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11307 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11308 gen_rtx_LABEL_REF (VOIDmode, label),
11309 pc_rtx);
11310 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11311 JUMP_LABEL (tmp) = label;
11312
11313 emit_move_insn (operands[0], operands[1]);
11314 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11315
11316 emit_label (label);
11317 LABEL_NUSES (label) = 1;
11318
11319 DONE;
11320 })
11321
11322 (define_insn "ashrsi3_31"
11323 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11324 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11325 (match_operand:SI 2 "const_int_operand" "i,i")))
11326 (clobber (reg:CC 17))]
11327 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11328 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11329 "@
11330 {cltd|cdq}
11331 sar{l}\t{%2, %0|%0, %2}"
11332 [(set_attr "type" "imovx,ishift")
11333 (set_attr "prefix_0f" "0,*")
11334 (set_attr "length_immediate" "0,*")
11335 (set_attr "modrm" "0,1")
11336 (set_attr "mode" "SI")])
11337
11338 (define_insn "*ashrsi3_31_zext"
11339 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11340 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11341 (match_operand:SI 2 "const_int_operand" "i,i"))))
11342 (clobber (reg:CC 17))]
11343 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11344 && INTVAL (operands[2]) == 31
11345 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11346 "@
11347 {cltd|cdq}
11348 sar{l}\t{%2, %k0|%k0, %2}"
11349 [(set_attr "type" "imovx,ishift")
11350 (set_attr "prefix_0f" "0,*")
11351 (set_attr "length_immediate" "0,*")
11352 (set_attr "modrm" "0,1")
11353 (set_attr "mode" "SI")])
11354
11355 (define_expand "ashrsi3"
11356 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11357 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11358 (match_operand:QI 2 "nonmemory_operand" "")))
11359 (clobber (reg:CC 17))]
11360 ""
11361 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11362
11363 (define_insn "*ashrsi3_1_one_bit"
11364 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11365 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11366 (match_operand:QI 2 "const_int_1_operand" "")))
11367 (clobber (reg:CC 17))]
11368 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11369 && (TARGET_SHIFT1 || optimize_size)"
11370 "sar{l}\t%0"
11371 [(set_attr "type" "ishift")
11372 (set (attr "length")
11373 (if_then_else (match_operand:SI 0 "register_operand" "")
11374 (const_string "2")
11375 (const_string "*")))])
11376
11377 (define_insn "*ashrsi3_1_one_bit_zext"
11378 [(set (match_operand:DI 0 "register_operand" "=r")
11379 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11380 (match_operand:QI 2 "const_int_1_operand" ""))))
11381 (clobber (reg:CC 17))]
11382 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11383 && (TARGET_SHIFT1 || optimize_size)"
11384 "sar{l}\t%k0"
11385 [(set_attr "type" "ishift")
11386 (set_attr "length" "2")])
11387
11388 (define_insn "*ashrsi3_1"
11389 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11390 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11391 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11392 (clobber (reg:CC 17))]
11393 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11394 "@
11395 sar{l}\t{%2, %0|%0, %2}
11396 sar{l}\t{%b2, %0|%0, %b2}"
11397 [(set_attr "type" "ishift")
11398 (set_attr "mode" "SI")])
11399
11400 (define_insn "*ashrsi3_1_zext"
11401 [(set (match_operand:DI 0 "register_operand" "=r,r")
11402 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11403 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11404 (clobber (reg:CC 17))]
11405 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11406 "@
11407 sar{l}\t{%2, %k0|%k0, %2}
11408 sar{l}\t{%b2, %k0|%k0, %b2}"
11409 [(set_attr "type" "ishift")
11410 (set_attr "mode" "SI")])
11411
11412 ;; This pattern can't accept a variable shift count, since shifts by
11413 ;; zero don't affect the flags. We assume that shifts by constant
11414 ;; zero are optimized away.
11415 (define_insn "*ashrsi3_one_bit_cmp"
11416 [(set (reg 17)
11417 (compare
11418 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11419 (match_operand:QI 2 "const_int_1_operand" ""))
11420 (const_int 0)))
11421 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11422 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11423 "ix86_match_ccmode (insn, CCGOCmode)
11424 && (TARGET_SHIFT1 || optimize_size)
11425 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11426 "sar{l}\t%0"
11427 [(set_attr "type" "ishift")
11428 (set (attr "length")
11429 (if_then_else (match_operand:SI 0 "register_operand" "")
11430 (const_string "2")
11431 (const_string "*")))])
11432
11433 (define_insn "*ashrsi3_one_bit_cmp_zext"
11434 [(set (reg 17)
11435 (compare
11436 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11437 (match_operand:QI 2 "const_int_1_operand" ""))
11438 (const_int 0)))
11439 (set (match_operand:DI 0 "register_operand" "=r")
11440 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11441 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11442 && (TARGET_SHIFT1 || optimize_size)
11443 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11444 "sar{l}\t%k0"
11445 [(set_attr "type" "ishift")
11446 (set_attr "length" "2")])
11447
11448 ;; This pattern can't accept a variable shift count, since shifts by
11449 ;; zero don't affect the flags. We assume that shifts by constant
11450 ;; zero are optimized away.
11451 (define_insn "*ashrsi3_cmp"
11452 [(set (reg 17)
11453 (compare
11454 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11455 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11456 (const_int 0)))
11457 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11458 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11459 "ix86_match_ccmode (insn, CCGOCmode)
11460 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11461 "sar{l}\t{%2, %0|%0, %2}"
11462 [(set_attr "type" "ishift")
11463 (set_attr "mode" "SI")])
11464
11465 (define_insn "*ashrsi3_cmp_zext"
11466 [(set (reg 17)
11467 (compare
11468 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11469 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11470 (const_int 0)))
11471 (set (match_operand:DI 0 "register_operand" "=r")
11472 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11473 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11474 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11475 "sar{l}\t{%2, %k0|%k0, %2}"
11476 [(set_attr "type" "ishift")
11477 (set_attr "mode" "SI")])
11478
11479 (define_expand "ashrhi3"
11480 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11481 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11482 (match_operand:QI 2 "nonmemory_operand" "")))
11483 (clobber (reg:CC 17))]
11484 "TARGET_HIMODE_MATH"
11485 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11486
11487 (define_insn "*ashrhi3_1_one_bit"
11488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11489 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11490 (match_operand:QI 2 "const_int_1_operand" "")))
11491 (clobber (reg:CC 17))]
11492 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11493 && (TARGET_SHIFT1 || optimize_size)"
11494 "sar{w}\t%0"
11495 [(set_attr "type" "ishift")
11496 (set (attr "length")
11497 (if_then_else (match_operand 0 "register_operand" "")
11498 (const_string "2")
11499 (const_string "*")))])
11500
11501 (define_insn "*ashrhi3_1"
11502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11503 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11504 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11505 (clobber (reg:CC 17))]
11506 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11507 "@
11508 sar{w}\t{%2, %0|%0, %2}
11509 sar{w}\t{%b2, %0|%0, %b2}"
11510 [(set_attr "type" "ishift")
11511 (set_attr "mode" "HI")])
11512
11513 ;; This pattern can't accept a variable shift count, since shifts by
11514 ;; zero don't affect the flags. We assume that shifts by constant
11515 ;; zero are optimized away.
11516 (define_insn "*ashrhi3_one_bit_cmp"
11517 [(set (reg 17)
11518 (compare
11519 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11520 (match_operand:QI 2 "const_int_1_operand" ""))
11521 (const_int 0)))
11522 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11523 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11524 "ix86_match_ccmode (insn, CCGOCmode)
11525 && (TARGET_SHIFT1 || optimize_size)
11526 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11527 "sar{w}\t%0"
11528 [(set_attr "type" "ishift")
11529 (set (attr "length")
11530 (if_then_else (match_operand 0 "register_operand" "")
11531 (const_string "2")
11532 (const_string "*")))])
11533
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags. We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*ashrhi3_cmp"
11538 [(set (reg 17)
11539 (compare
11540 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11541 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11542 (const_int 0)))
11543 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11544 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11545 "ix86_match_ccmode (insn, CCGOCmode)
11546 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11547 "sar{w}\t{%2, %0|%0, %2}"
11548 [(set_attr "type" "ishift")
11549 (set_attr "mode" "HI")])
11550
11551 (define_expand "ashrqi3"
11552 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11553 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11554 (match_operand:QI 2 "nonmemory_operand" "")))
11555 (clobber (reg:CC 17))]
11556 "TARGET_QIMODE_MATH"
11557 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11558
11559 (define_insn "*ashrqi3_1_one_bit"
11560 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11561 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11562 (match_operand:QI 2 "const_int_1_operand" "")))
11563 (clobber (reg:CC 17))]
11564 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11565 && (TARGET_SHIFT1 || optimize_size)"
11566 "sar{b}\t%0"
11567 [(set_attr "type" "ishift")
11568 (set (attr "length")
11569 (if_then_else (match_operand 0 "register_operand" "")
11570 (const_string "2")
11571 (const_string "*")))])
11572
11573 (define_insn "*ashrqi3_1_one_bit_slp"
11574 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11575 (ashiftrt:QI (match_dup 0)
11576 (match_operand:QI 1 "const_int_1_operand" "")))
11577 (clobber (reg:CC 17))]
11578 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11579 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11580 && (TARGET_SHIFT1 || optimize_size)"
11581 "sar{b}\t%0"
11582 [(set_attr "type" "ishift1")
11583 (set (attr "length")
11584 (if_then_else (match_operand 0 "register_operand" "")
11585 (const_string "2")
11586 (const_string "*")))])
11587
11588 (define_insn "*ashrqi3_1"
11589 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11590 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11591 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11592 (clobber (reg:CC 17))]
11593 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11594 "@
11595 sar{b}\t{%2, %0|%0, %2}
11596 sar{b}\t{%b2, %0|%0, %b2}"
11597 [(set_attr "type" "ishift")
11598 (set_attr "mode" "QI")])
11599
11600 (define_insn "*ashrqi3_1_slp"
11601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11602 (ashiftrt:QI (match_dup 0)
11603 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11604 (clobber (reg:CC 17))]
11605 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11607 "@
11608 sar{b}\t{%1, %0|%0, %1}
11609 sar{b}\t{%b1, %0|%0, %b1}"
11610 [(set_attr "type" "ishift1")
11611 (set_attr "mode" "QI")])
11612
11613 ;; This pattern can't accept a variable shift count, since shifts by
11614 ;; zero don't affect the flags. We assume that shifts by constant
11615 ;; zero are optimized away.
11616 (define_insn "*ashrqi3_one_bit_cmp"
11617 [(set (reg 17)
11618 (compare
11619 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11620 (match_operand:QI 2 "const_int_1_operand" "I"))
11621 (const_int 0)))
11622 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11623 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11624 "ix86_match_ccmode (insn, CCGOCmode)
11625 && (TARGET_SHIFT1 || optimize_size)
11626 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11627 "sar{b}\t%0"
11628 [(set_attr "type" "ishift")
11629 (set (attr "length")
11630 (if_then_else (match_operand 0 "register_operand" "")
11631 (const_string "2")
11632 (const_string "*")))])
11633
11634 ;; This pattern can't accept a variable shift count, since shifts by
11635 ;; zero don't affect the flags. We assume that shifts by constant
11636 ;; zero are optimized away.
11637 (define_insn "*ashrqi3_cmp"
11638 [(set (reg 17)
11639 (compare
11640 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11641 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11642 (const_int 0)))
11643 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11644 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11645 "ix86_match_ccmode (insn, CCGOCmode)
11646 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11647 "sar{b}\t{%2, %0|%0, %2}"
11648 [(set_attr "type" "ishift")
11649 (set_attr "mode" "QI")])
11650 \f
11651 ;; Logical shift instructions
11652
11653 ;; See comment above `ashldi3' about how this works.
11654
11655 (define_expand "lshrdi3"
11656 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11657 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11658 (match_operand:QI 2 "nonmemory_operand" "")))
11659 (clobber (reg:CC 17))])]
11660 ""
11661 {
11662 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11663 {
11664 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11665 DONE;
11666 }
11667 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11668 DONE;
11669 })
11670
11671 (define_insn "*lshrdi3_1_one_bit_rex64"
11672 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11673 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11674 (match_operand:QI 2 "const_int_1_operand" "")))
11675 (clobber (reg:CC 17))]
11676 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11677 && (TARGET_SHIFT1 || optimize_size)"
11678 "shr{q}\t%0"
11679 [(set_attr "type" "ishift")
11680 (set (attr "length")
11681 (if_then_else (match_operand:DI 0 "register_operand" "")
11682 (const_string "2")
11683 (const_string "*")))])
11684
11685 (define_insn "*lshrdi3_1_rex64"
11686 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11687 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11688 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11689 (clobber (reg:CC 17))]
11690 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11691 "@
11692 shr{q}\t{%2, %0|%0, %2}
11693 shr{q}\t{%b2, %0|%0, %b2}"
11694 [(set_attr "type" "ishift")
11695 (set_attr "mode" "DI")])
11696
11697 ;; This pattern can't accept a variable shift count, since shifts by
11698 ;; zero don't affect the flags. We assume that shifts by constant
11699 ;; zero are optimized away.
11700 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11701 [(set (reg 17)
11702 (compare
11703 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11704 (match_operand:QI 2 "const_int_1_operand" ""))
11705 (const_int 0)))
11706 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11707 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11708 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11709 && (TARGET_SHIFT1 || optimize_size)
11710 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11711 "shr{q}\t%0"
11712 [(set_attr "type" "ishift")
11713 (set (attr "length")
11714 (if_then_else (match_operand:DI 0 "register_operand" "")
11715 (const_string "2")
11716 (const_string "*")))])
11717
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags. We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*lshrdi3_cmp_rex64"
11722 [(set (reg 17)
11723 (compare
11724 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11725 (match_operand:QI 2 "const_int_operand" "e"))
11726 (const_int 0)))
11727 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11728 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11729 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11730 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11731 "shr{q}\t{%2, %0|%0, %2}"
11732 [(set_attr "type" "ishift")
11733 (set_attr "mode" "DI")])
11734
11735 (define_insn "lshrdi3_1"
11736 [(set (match_operand:DI 0 "register_operand" "=r")
11737 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11738 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11739 (clobber (match_scratch:SI 3 "=&r"))
11740 (clobber (reg:CC 17))]
11741 "!TARGET_64BIT && TARGET_CMOVE"
11742 "#"
11743 [(set_attr "type" "multi")])
11744
11745 (define_insn "*lshrdi3_2"
11746 [(set (match_operand:DI 0 "register_operand" "=r")
11747 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11748 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11749 (clobber (reg:CC 17))]
11750 "!TARGET_64BIT"
11751 "#"
11752 [(set_attr "type" "multi")])
11753
11754 (define_split
11755 [(set (match_operand:DI 0 "register_operand" "")
11756 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11757 (match_operand:QI 2 "nonmemory_operand" "")))
11758 (clobber (match_scratch:SI 3 ""))
11759 (clobber (reg:CC 17))]
11760 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11761 [(const_int 0)]
11762 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11763
11764 (define_split
11765 [(set (match_operand:DI 0 "register_operand" "")
11766 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11767 (match_operand:QI 2 "nonmemory_operand" "")))
11768 (clobber (reg:CC 17))]
11769 "!TARGET_64BIT && reload_completed"
11770 [(const_int 0)]
11771 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11772
11773 (define_expand "lshrsi3"
11774 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11775 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11776 (match_operand:QI 2 "nonmemory_operand" "")))
11777 (clobber (reg:CC 17))]
11778 ""
11779 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11780
11781 (define_insn "*lshrsi3_1_one_bit"
11782 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11783 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const_int_1_operand" "")))
11785 (clobber (reg:CC 17))]
11786 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11787 && (TARGET_SHIFT1 || optimize_size)"
11788 "shr{l}\t%0"
11789 [(set_attr "type" "ishift")
11790 (set (attr "length")
11791 (if_then_else (match_operand:SI 0 "register_operand" "")
11792 (const_string "2")
11793 (const_string "*")))])
11794
11795 (define_insn "*lshrsi3_1_one_bit_zext"
11796 [(set (match_operand:DI 0 "register_operand" "=r")
11797 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11798 (match_operand:QI 2 "const_int_1_operand" "")))
11799 (clobber (reg:CC 17))]
11800 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11801 && (TARGET_SHIFT1 || optimize_size)"
11802 "shr{l}\t%k0"
11803 [(set_attr "type" "ishift")
11804 (set_attr "length" "2")])
11805
11806 (define_insn "*lshrsi3_1"
11807 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11808 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11809 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11810 (clobber (reg:CC 17))]
11811 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11812 "@
11813 shr{l}\t{%2, %0|%0, %2}
11814 shr{l}\t{%b2, %0|%0, %b2}"
11815 [(set_attr "type" "ishift")
11816 (set_attr "mode" "SI")])
11817
11818 (define_insn "*lshrsi3_1_zext"
11819 [(set (match_operand:DI 0 "register_operand" "=r,r")
11820 (zero_extend:DI
11821 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11822 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11823 (clobber (reg:CC 17))]
11824 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11825 "@
11826 shr{l}\t{%2, %k0|%k0, %2}
11827 shr{l}\t{%b2, %k0|%k0, %b2}"
11828 [(set_attr "type" "ishift")
11829 (set_attr "mode" "SI")])
11830
11831 ;; This pattern can't accept a variable shift count, since shifts by
11832 ;; zero don't affect the flags. We assume that shifts by constant
11833 ;; zero are optimized away.
11834 (define_insn "*lshrsi3_one_bit_cmp"
11835 [(set (reg 17)
11836 (compare
11837 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11838 (match_operand:QI 2 "const_int_1_operand" ""))
11839 (const_int 0)))
11840 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11841 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11842 "ix86_match_ccmode (insn, CCGOCmode)
11843 && (TARGET_SHIFT1 || optimize_size)
11844 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11845 "shr{l}\t%0"
11846 [(set_attr "type" "ishift")
11847 (set (attr "length")
11848 (if_then_else (match_operand:SI 0 "register_operand" "")
11849 (const_string "2")
11850 (const_string "*")))])
11851
11852 (define_insn "*lshrsi3_cmp_one_bit_zext"
11853 [(set (reg 17)
11854 (compare
11855 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11856 (match_operand:QI 2 "const_int_1_operand" ""))
11857 (const_int 0)))
11858 (set (match_operand:DI 0 "register_operand" "=r")
11859 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11860 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11861 && (TARGET_SHIFT1 || optimize_size)
11862 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11863 "shr{l}\t%k0"
11864 [(set_attr "type" "ishift")
11865 (set_attr "length" "2")])
11866
11867 ;; This pattern can't accept a variable shift count, since shifts by
11868 ;; zero don't affect the flags. We assume that shifts by constant
11869 ;; zero are optimized away.
11870 (define_insn "*lshrsi3_cmp"
11871 [(set (reg 17)
11872 (compare
11873 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11874 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11875 (const_int 0)))
11876 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11877 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11878 "ix86_match_ccmode (insn, CCGOCmode)
11879 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11880 "shr{l}\t{%2, %0|%0, %2}"
11881 [(set_attr "type" "ishift")
11882 (set_attr "mode" "SI")])
11883
11884 (define_insn "*lshrsi3_cmp_zext"
11885 [(set (reg 17)
11886 (compare
11887 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11888 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11889 (const_int 0)))
11890 (set (match_operand:DI 0 "register_operand" "=r")
11891 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11892 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11893 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894 "shr{l}\t{%2, %k0|%k0, %2}"
11895 [(set_attr "type" "ishift")
11896 (set_attr "mode" "SI")])
11897
11898 (define_expand "lshrhi3"
11899 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11900 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11901 (match_operand:QI 2 "nonmemory_operand" "")))
11902 (clobber (reg:CC 17))]
11903 "TARGET_HIMODE_MATH"
11904 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11905
11906 (define_insn "*lshrhi3_1_one_bit"
11907 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11908 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11909 (match_operand:QI 2 "const_int_1_operand" "")))
11910 (clobber (reg:CC 17))]
11911 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11912 && (TARGET_SHIFT1 || optimize_size)"
11913 "shr{w}\t%0"
11914 [(set_attr "type" "ishift")
11915 (set (attr "length")
11916 (if_then_else (match_operand 0 "register_operand" "")
11917 (const_string "2")
11918 (const_string "*")))])
11919
11920 (define_insn "*lshrhi3_1"
11921 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11922 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11923 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11924 (clobber (reg:CC 17))]
11925 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11926 "@
11927 shr{w}\t{%2, %0|%0, %2}
11928 shr{w}\t{%b2, %0|%0, %b2}"
11929 [(set_attr "type" "ishift")
11930 (set_attr "mode" "HI")])
11931
11932 ;; This pattern can't accept a variable shift count, since shifts by
11933 ;; zero don't affect the flags. We assume that shifts by constant
11934 ;; zero are optimized away.
11935 (define_insn "*lshrhi3_one_bit_cmp"
11936 [(set (reg 17)
11937 (compare
11938 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11939 (match_operand:QI 2 "const_int_1_operand" ""))
11940 (const_int 0)))
11941 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11942 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11943 "ix86_match_ccmode (insn, CCGOCmode)
11944 && (TARGET_SHIFT1 || optimize_size)
11945 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11946 "shr{w}\t%0"
11947 [(set_attr "type" "ishift")
11948 (set (attr "length")
11949 (if_then_else (match_operand:SI 0 "register_operand" "")
11950 (const_string "2")
11951 (const_string "*")))])
11952
11953 ;; This pattern can't accept a variable shift count, since shifts by
11954 ;; zero don't affect the flags. We assume that shifts by constant
11955 ;; zero are optimized away.
11956 (define_insn "*lshrhi3_cmp"
11957 [(set (reg 17)
11958 (compare
11959 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11960 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11961 (const_int 0)))
11962 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11963 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11964 "ix86_match_ccmode (insn, CCGOCmode)
11965 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11966 "shr{w}\t{%2, %0|%0, %2}"
11967 [(set_attr "type" "ishift")
11968 (set_attr "mode" "HI")])
11969
11970 (define_expand "lshrqi3"
11971 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11972 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11973 (match_operand:QI 2 "nonmemory_operand" "")))
11974 (clobber (reg:CC 17))]
11975 "TARGET_QIMODE_MATH"
11976 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11977
11978 (define_insn "*lshrqi3_1_one_bit"
11979 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11980 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11981 (match_operand:QI 2 "const_int_1_operand" "")))
11982 (clobber (reg:CC 17))]
11983 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11984 && (TARGET_SHIFT1 || optimize_size)"
11985 "shr{b}\t%0"
11986 [(set_attr "type" "ishift")
11987 (set (attr "length")
11988 (if_then_else (match_operand 0 "register_operand" "")
11989 (const_string "2")
11990 (const_string "*")))])
11991
11992 (define_insn "*lshrqi3_1_one_bit_slp"
11993 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11994 (lshiftrt:QI (match_dup 0)
11995 (match_operand:QI 1 "const_int_1_operand" "")))
11996 (clobber (reg:CC 17))]
11997 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11998 && (TARGET_SHIFT1 || optimize_size)"
11999 "shr{b}\t%0"
12000 [(set_attr "type" "ishift1")
12001 (set (attr "length")
12002 (if_then_else (match_operand 0 "register_operand" "")
12003 (const_string "2")
12004 (const_string "*")))])
12005
12006 (define_insn "*lshrqi3_1"
12007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12008 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12009 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12010 (clobber (reg:CC 17))]
12011 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12012 "@
12013 shr{b}\t{%2, %0|%0, %2}
12014 shr{b}\t{%b2, %0|%0, %b2}"
12015 [(set_attr "type" "ishift")
12016 (set_attr "mode" "QI")])
12017
12018 (define_insn "*lshrqi3_1_slp"
12019 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12020 (lshiftrt:QI (match_dup 0)
12021 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12022 (clobber (reg:CC 17))]
12023 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12024 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12025 "@
12026 shr{b}\t{%1, %0|%0, %1}
12027 shr{b}\t{%b1, %0|%0, %b1}"
12028 [(set_attr "type" "ishift1")
12029 (set_attr "mode" "QI")])
12030
12031 ;; This pattern can't accept a variable shift count, since shifts by
12032 ;; zero don't affect the flags. We assume that shifts by constant
12033 ;; zero are optimized away.
12034 (define_insn "*lshrqi2_one_bit_cmp"
12035 [(set (reg 17)
12036 (compare
12037 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12038 (match_operand:QI 2 "const_int_1_operand" ""))
12039 (const_int 0)))
12040 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12041 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12042 "ix86_match_ccmode (insn, CCGOCmode)
12043 && (TARGET_SHIFT1 || optimize_size)
12044 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12045 "shr{b}\t%0"
12046 [(set_attr "type" "ishift")
12047 (set (attr "length")
12048 (if_then_else (match_operand:SI 0 "register_operand" "")
12049 (const_string "2")
12050 (const_string "*")))])
12051
12052 ;; This pattern can't accept a variable shift count, since shifts by
12053 ;; zero don't affect the flags. We assume that shifts by constant
12054 ;; zero are optimized away.
12055 (define_insn "*lshrqi2_cmp"
12056 [(set (reg 17)
12057 (compare
12058 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12059 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12060 (const_int 0)))
12061 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12062 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12063 "ix86_match_ccmode (insn, CCGOCmode)
12064 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12065 "shr{b}\t{%2, %0|%0, %2}"
12066 [(set_attr "type" "ishift")
12067 (set_attr "mode" "QI")])
12068 \f
12069 ;; Rotate instructions
12070
12071 (define_expand "rotldi3"
12072 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12073 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12074 (match_operand:QI 2 "nonmemory_operand" "")))
12075 (clobber (reg:CC 17))]
12076 "TARGET_64BIT"
12077 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12078
12079 (define_insn "*rotlsi3_1_one_bit_rex64"
12080 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12081 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12082 (match_operand:QI 2 "const_int_1_operand" "")))
12083 (clobber (reg:CC 17))]
12084 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12085 && (TARGET_SHIFT1 || optimize_size)"
12086 "rol{q}\t%0"
12087 [(set_attr "type" "rotate")
12088 (set (attr "length")
12089 (if_then_else (match_operand:DI 0 "register_operand" "")
12090 (const_string "2")
12091 (const_string "*")))])
12092
12093 (define_insn "*rotldi3_1_rex64"
12094 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12095 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12096 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12097 (clobber (reg:CC 17))]
12098 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12099 "@
12100 rol{q}\t{%2, %0|%0, %2}
12101 rol{q}\t{%b2, %0|%0, %b2}"
12102 [(set_attr "type" "rotate")
12103 (set_attr "mode" "DI")])
12104
12105 (define_expand "rotlsi3"
12106 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12107 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12108 (match_operand:QI 2 "nonmemory_operand" "")))
12109 (clobber (reg:CC 17))]
12110 ""
12111 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12112
12113 (define_insn "*rotlsi3_1_one_bit"
12114 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12115 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12116 (match_operand:QI 2 "const_int_1_operand" "")))
12117 (clobber (reg:CC 17))]
12118 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12119 && (TARGET_SHIFT1 || optimize_size)"
12120 "rol{l}\t%0"
12121 [(set_attr "type" "rotate")
12122 (set (attr "length")
12123 (if_then_else (match_operand:SI 0 "register_operand" "")
12124 (const_string "2")
12125 (const_string "*")))])
12126
12127 (define_insn "*rotlsi3_1_one_bit_zext"
12128 [(set (match_operand:DI 0 "register_operand" "=r")
12129 (zero_extend:DI
12130 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12131 (match_operand:QI 2 "const_int_1_operand" ""))))
12132 (clobber (reg:CC 17))]
12133 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12134 && (TARGET_SHIFT1 || optimize_size)"
12135 "rol{l}\t%k0"
12136 [(set_attr "type" "rotate")
12137 (set_attr "length" "2")])
12138
12139 (define_insn "*rotlsi3_1"
12140 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12141 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12142 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12143 (clobber (reg:CC 17))]
12144 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12145 "@
12146 rol{l}\t{%2, %0|%0, %2}
12147 rol{l}\t{%b2, %0|%0, %b2}"
12148 [(set_attr "type" "rotate")
12149 (set_attr "mode" "SI")])
12150
12151 (define_insn "*rotlsi3_1_zext"
12152 [(set (match_operand:DI 0 "register_operand" "=r,r")
12153 (zero_extend:DI
12154 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12155 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12156 (clobber (reg:CC 17))]
12157 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12158 "@
12159 rol{l}\t{%2, %k0|%k0, %2}
12160 rol{l}\t{%b2, %k0|%k0, %b2}"
12161 [(set_attr "type" "rotate")
12162 (set_attr "mode" "SI")])
12163
12164 (define_expand "rotlhi3"
12165 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12166 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12167 (match_operand:QI 2 "nonmemory_operand" "")))
12168 (clobber (reg:CC 17))]
12169 "TARGET_HIMODE_MATH"
12170 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12171
12172 (define_insn "*rotlhi3_1_one_bit"
12173 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12174 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12175 (match_operand:QI 2 "const_int_1_operand" "")))
12176 (clobber (reg:CC 17))]
12177 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12178 && (TARGET_SHIFT1 || optimize_size)"
12179 "rol{w}\t%0"
12180 [(set_attr "type" "rotate")
12181 (set (attr "length")
12182 (if_then_else (match_operand 0 "register_operand" "")
12183 (const_string "2")
12184 (const_string "*")))])
12185
12186 (define_insn "*rotlhi3_1"
12187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12188 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC 17))]
12191 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12192 "@
12193 rol{w}\t{%2, %0|%0, %2}
12194 rol{w}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "rotate")
12196 (set_attr "mode" "HI")])
12197
12198 (define_expand "rotlqi3"
12199 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12200 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12201 (match_operand:QI 2 "nonmemory_operand" "")))
12202 (clobber (reg:CC 17))]
12203 "TARGET_QIMODE_MATH"
12204 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12205
12206 (define_insn "*rotlqi3_1_one_bit_slp"
12207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12208 (rotate:QI (match_dup 0)
12209 (match_operand:QI 1 "const_int_1_operand" "")))
12210 (clobber (reg:CC 17))]
12211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12212 && (TARGET_SHIFT1 || optimize_size)"
12213 "rol{b}\t%0"
12214 [(set_attr "type" "rotate1")
12215 (set (attr "length")
12216 (if_then_else (match_operand 0 "register_operand" "")
12217 (const_string "2")
12218 (const_string "*")))])
12219
12220 (define_insn "*rotlqi3_1_one_bit"
12221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12223 (match_operand:QI 2 "const_int_1_operand" "")))
12224 (clobber (reg:CC 17))]
12225 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12226 && (TARGET_SHIFT1 || optimize_size)"
12227 "rol{b}\t%0"
12228 [(set_attr "type" "rotate")
12229 (set (attr "length")
12230 (if_then_else (match_operand 0 "register_operand" "")
12231 (const_string "2")
12232 (const_string "*")))])
12233
12234 (define_insn "*rotlqi3_1_slp"
12235 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12236 (rotate:QI (match_dup 0)
12237 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12238 (clobber (reg:CC 17))]
12239 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12240 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12241 "@
12242 rol{b}\t{%1, %0|%0, %1}
12243 rol{b}\t{%b1, %0|%0, %b1}"
12244 [(set_attr "type" "rotate1")
12245 (set_attr "mode" "QI")])
12246
12247 (define_insn "*rotlqi3_1"
12248 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12249 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12250 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12251 (clobber (reg:CC 17))]
12252 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12253 "@
12254 rol{b}\t{%2, %0|%0, %2}
12255 rol{b}\t{%b2, %0|%0, %b2}"
12256 [(set_attr "type" "rotate")
12257 (set_attr "mode" "QI")])
12258
12259 (define_expand "rotrdi3"
12260 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12261 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12262 (match_operand:QI 2 "nonmemory_operand" "")))
12263 (clobber (reg:CC 17))]
12264 "TARGET_64BIT"
12265 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12266
12267 (define_insn "*rotrdi3_1_one_bit_rex64"
12268 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12269 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12270 (match_operand:QI 2 "const_int_1_operand" "")))
12271 (clobber (reg:CC 17))]
12272 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12273 && (TARGET_SHIFT1 || optimize_size)"
12274 "ror{q}\t%0"
12275 [(set_attr "type" "rotate")
12276 (set (attr "length")
12277 (if_then_else (match_operand:DI 0 "register_operand" "")
12278 (const_string "2")
12279 (const_string "*")))])
12280
12281 (define_insn "*rotrdi3_1_rex64"
12282 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12283 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12284 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12285 (clobber (reg:CC 17))]
12286 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12287 "@
12288 ror{q}\t{%2, %0|%0, %2}
12289 ror{q}\t{%b2, %0|%0, %b2}"
12290 [(set_attr "type" "rotate")
12291 (set_attr "mode" "DI")])
12292
12293 (define_expand "rotrsi3"
12294 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12295 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12296 (match_operand:QI 2 "nonmemory_operand" "")))
12297 (clobber (reg:CC 17))]
12298 ""
12299 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12300
12301 (define_insn "*rotrsi3_1_one_bit"
12302 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12303 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12304 (match_operand:QI 2 "const_int_1_operand" "")))
12305 (clobber (reg:CC 17))]
12306 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12307 && (TARGET_SHIFT1 || optimize_size)"
12308 "ror{l}\t%0"
12309 [(set_attr "type" "rotate")
12310 (set (attr "length")
12311 (if_then_else (match_operand:SI 0 "register_operand" "")
12312 (const_string "2")
12313 (const_string "*")))])
12314
12315 (define_insn "*rotrsi3_1_one_bit_zext"
12316 [(set (match_operand:DI 0 "register_operand" "=r")
12317 (zero_extend:DI
12318 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12319 (match_operand:QI 2 "const_int_1_operand" ""))))
12320 (clobber (reg:CC 17))]
12321 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12322 && (TARGET_SHIFT1 || optimize_size)"
12323 "ror{l}\t%k0"
12324 [(set_attr "type" "rotate")
12325 (set (attr "length")
12326 (if_then_else (match_operand:SI 0 "register_operand" "")
12327 (const_string "2")
12328 (const_string "*")))])
12329
12330 (define_insn "*rotrsi3_1"
12331 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12332 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12333 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12334 (clobber (reg:CC 17))]
12335 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12336 "@
12337 ror{l}\t{%2, %0|%0, %2}
12338 ror{l}\t{%b2, %0|%0, %b2}"
12339 [(set_attr "type" "rotate")
12340 (set_attr "mode" "SI")])
12341
12342 (define_insn "*rotrsi3_1_zext"
12343 [(set (match_operand:DI 0 "register_operand" "=r,r")
12344 (zero_extend:DI
12345 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12346 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12347 (clobber (reg:CC 17))]
12348 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12349 "@
12350 ror{l}\t{%2, %k0|%k0, %2}
12351 ror{l}\t{%b2, %k0|%k0, %b2}"
12352 [(set_attr "type" "rotate")
12353 (set_attr "mode" "SI")])
12354
12355 (define_expand "rotrhi3"
12356 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12357 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12358 (match_operand:QI 2 "nonmemory_operand" "")))
12359 (clobber (reg:CC 17))]
12360 "TARGET_HIMODE_MATH"
12361 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12362
12363 (define_insn "*rotrhi3_one_bit"
12364 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12365 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12366 (match_operand:QI 2 "const_int_1_operand" "")))
12367 (clobber (reg:CC 17))]
12368 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12369 && (TARGET_SHIFT1 || optimize_size)"
12370 "ror{w}\t%0"
12371 [(set_attr "type" "rotate")
12372 (set (attr "length")
12373 (if_then_else (match_operand 0 "register_operand" "")
12374 (const_string "2")
12375 (const_string "*")))])
12376
12377 (define_insn "*rotrhi3"
12378 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12379 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12380 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12381 (clobber (reg:CC 17))]
12382 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12383 "@
12384 ror{w}\t{%2, %0|%0, %2}
12385 ror{w}\t{%b2, %0|%0, %b2}"
12386 [(set_attr "type" "rotate")
12387 (set_attr "mode" "HI")])
12388
12389 (define_expand "rotrqi3"
12390 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12391 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12392 (match_operand:QI 2 "nonmemory_operand" "")))
12393 (clobber (reg:CC 17))]
12394 "TARGET_QIMODE_MATH"
12395 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12396
12397 (define_insn "*rotrqi3_1_one_bit"
12398 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12399 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12400 (match_operand:QI 2 "const_int_1_operand" "")))
12401 (clobber (reg:CC 17))]
12402 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12403 && (TARGET_SHIFT1 || optimize_size)"
12404 "ror{b}\t%0"
12405 [(set_attr "type" "rotate")
12406 (set (attr "length")
12407 (if_then_else (match_operand 0 "register_operand" "")
12408 (const_string "2")
12409 (const_string "*")))])
12410
12411 (define_insn "*rotrqi3_1_one_bit_slp"
12412 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12413 (rotatert:QI (match_dup 0)
12414 (match_operand:QI 1 "const_int_1_operand" "")))
12415 (clobber (reg:CC 17))]
12416 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12417 && (TARGET_SHIFT1 || optimize_size)"
12418 "ror{b}\t%0"
12419 [(set_attr "type" "rotate1")
12420 (set (attr "length")
12421 (if_then_else (match_operand 0 "register_operand" "")
12422 (const_string "2")
12423 (const_string "*")))])
12424
12425 (define_insn "*rotrqi3_1"
12426 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12427 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12428 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12429 (clobber (reg:CC 17))]
12430 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12431 "@
12432 ror{b}\t{%2, %0|%0, %2}
12433 ror{b}\t{%b2, %0|%0, %b2}"
12434 [(set_attr "type" "rotate")
12435 (set_attr "mode" "QI")])
12436
12437 (define_insn "*rotrqi3_1_slp"
12438 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12439 (rotatert:QI (match_dup 0)
12440 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12441 (clobber (reg:CC 17))]
12442 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12443 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12444 "@
12445 ror{b}\t{%1, %0|%0, %1}
12446 ror{b}\t{%b1, %0|%0, %b1}"
12447 [(set_attr "type" "rotate1")
12448 (set_attr "mode" "QI")])
12449 \f
12450 ;; Bit set / bit test instructions
12451
12452 (define_expand "extv"
12453 [(set (match_operand:SI 0 "register_operand" "")
12454 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12455 (match_operand:SI 2 "immediate_operand" "")
12456 (match_operand:SI 3 "immediate_operand" "")))]
12457 ""
12458 {
12459 /* Handle extractions from %ah et al. */
12460 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12461 FAIL;
12462
12463 /* From mips.md: extract_bit_field doesn't verify that our source
12464 matches the predicate, so check it again here. */
12465 if (! register_operand (operands[1], VOIDmode))
12466 FAIL;
12467 })
12468
12469 (define_expand "extzv"
12470 [(set (match_operand:SI 0 "register_operand" "")
12471 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12472 (match_operand:SI 2 "immediate_operand" "")
12473 (match_operand:SI 3 "immediate_operand" "")))]
12474 ""
12475 {
12476 /* Handle extractions from %ah et al. */
12477 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12478 FAIL;
12479
12480 /* From mips.md: extract_bit_field doesn't verify that our source
12481 matches the predicate, so check it again here. */
12482 if (! register_operand (operands[1], VOIDmode))
12483 FAIL;
12484 })
12485
12486 (define_expand "insv"
12487 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12488 (match_operand:SI 1 "immediate_operand" "")
12489 (match_operand:SI 2 "immediate_operand" ""))
12490 (match_operand:SI 3 "register_operand" ""))]
12491 ""
12492 {
12493 /* Handle extractions from %ah et al. */
12494 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12495 FAIL;
12496
12497 /* From mips.md: insert_bit_field doesn't verify that our source
12498 matches the predicate, so check it again here. */
12499 if (! register_operand (operands[0], VOIDmode))
12500 FAIL;
12501 })
12502
12503 ;; %%% bts, btr, btc, bt.
12504 \f
12505 ;; Store-flag instructions.
12506
12507 ;; For all sCOND expanders, also expand the compare or test insn that
12508 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12509
12510 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12511 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12512 ;; way, which can later delete the movzx if only QImode is needed.
12513
12514 (define_expand "seq"
12515 [(set (match_operand:QI 0 "register_operand" "")
12516 (eq:QI (reg:CC 17) (const_int 0)))]
12517 ""
12518 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12519
12520 (define_expand "sne"
12521 [(set (match_operand:QI 0 "register_operand" "")
12522 (ne:QI (reg:CC 17) (const_int 0)))]
12523 ""
12524 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12525
12526 (define_expand "sgt"
12527 [(set (match_operand:QI 0 "register_operand" "")
12528 (gt:QI (reg:CC 17) (const_int 0)))]
12529 ""
12530 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12531
12532 (define_expand "sgtu"
12533 [(set (match_operand:QI 0 "register_operand" "")
12534 (gtu:QI (reg:CC 17) (const_int 0)))]
12535 ""
12536 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12537
12538 (define_expand "slt"
12539 [(set (match_operand:QI 0 "register_operand" "")
12540 (lt:QI (reg:CC 17) (const_int 0)))]
12541 ""
12542 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12543
12544 (define_expand "sltu"
12545 [(set (match_operand:QI 0 "register_operand" "")
12546 (ltu:QI (reg:CC 17) (const_int 0)))]
12547 ""
12548 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12549
12550 (define_expand "sge"
12551 [(set (match_operand:QI 0 "register_operand" "")
12552 (ge:QI (reg:CC 17) (const_int 0)))]
12553 ""
12554 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12555
12556 (define_expand "sgeu"
12557 [(set (match_operand:QI 0 "register_operand" "")
12558 (geu:QI (reg:CC 17) (const_int 0)))]
12559 ""
12560 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12561
12562 (define_expand "sle"
12563 [(set (match_operand:QI 0 "register_operand" "")
12564 (le:QI (reg:CC 17) (const_int 0)))]
12565 ""
12566 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12567
12568 (define_expand "sleu"
12569 [(set (match_operand:QI 0 "register_operand" "")
12570 (leu:QI (reg:CC 17) (const_int 0)))]
12571 ""
12572 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12573
12574 (define_expand "sunordered"
12575 [(set (match_operand:QI 0 "register_operand" "")
12576 (unordered:QI (reg:CC 17) (const_int 0)))]
12577 "TARGET_80387 || TARGET_SSE"
12578 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12579
12580 (define_expand "sordered"
12581 [(set (match_operand:QI 0 "register_operand" "")
12582 (ordered:QI (reg:CC 17) (const_int 0)))]
12583 "TARGET_80387"
12584 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12585
12586 (define_expand "suneq"
12587 [(set (match_operand:QI 0 "register_operand" "")
12588 (uneq:QI (reg:CC 17) (const_int 0)))]
12589 "TARGET_80387 || TARGET_SSE"
12590 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12591
12592 (define_expand "sunge"
12593 [(set (match_operand:QI 0 "register_operand" "")
12594 (unge:QI (reg:CC 17) (const_int 0)))]
12595 "TARGET_80387 || TARGET_SSE"
12596 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12597
12598 (define_expand "sungt"
12599 [(set (match_operand:QI 0 "register_operand" "")
12600 (ungt:QI (reg:CC 17) (const_int 0)))]
12601 "TARGET_80387 || TARGET_SSE"
12602 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12603
12604 (define_expand "sunle"
12605 [(set (match_operand:QI 0 "register_operand" "")
12606 (unle:QI (reg:CC 17) (const_int 0)))]
12607 "TARGET_80387 || TARGET_SSE"
12608 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12609
12610 (define_expand "sunlt"
12611 [(set (match_operand:QI 0 "register_operand" "")
12612 (unlt:QI (reg:CC 17) (const_int 0)))]
12613 "TARGET_80387 || TARGET_SSE"
12614 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12615
12616 (define_expand "sltgt"
12617 [(set (match_operand:QI 0 "register_operand" "")
12618 (ltgt:QI (reg:CC 17) (const_int 0)))]
12619 "TARGET_80387 || TARGET_SSE"
12620 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12621
12622 (define_insn "*setcc_1"
12623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12624 (match_operator:QI 1 "ix86_comparison_operator"
12625 [(reg 17) (const_int 0)]))]
12626 ""
12627 "set%C1\t%0"
12628 [(set_attr "type" "setcc")
12629 (set_attr "mode" "QI")])
12630
12631 (define_insn "setcc_2"
12632 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12633 (match_operator:QI 1 "ix86_comparison_operator"
12634 [(reg 17) (const_int 0)]))]
12635 ""
12636 "set%C1\t%0"
12637 [(set_attr "type" "setcc")
12638 (set_attr "mode" "QI")])
12639
12640 ;; In general it is not safe to assume too much about CCmode registers,
12641 ;; so simplify-rtx stops when it sees a second one. Under certain
12642 ;; conditions this is safe on x86, so help combine not create
12643 ;;
12644 ;; seta %al
12645 ;; testb %al, %al
12646 ;; sete %al
12647
12648 (define_split
12649 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12650 (ne:QI (match_operator 1 "ix86_comparison_operator"
12651 [(reg 17) (const_int 0)])
12652 (const_int 0)))]
12653 ""
12654 [(set (match_dup 0) (match_dup 1))]
12655 {
12656 PUT_MODE (operands[1], QImode);
12657 })
12658
12659 (define_split
12660 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12661 (ne:QI (match_operator 1 "ix86_comparison_operator"
12662 [(reg 17) (const_int 0)])
12663 (const_int 0)))]
12664 ""
12665 [(set (match_dup 0) (match_dup 1))]
12666 {
12667 PUT_MODE (operands[1], QImode);
12668 })
12669
12670 (define_split
12671 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12672 (eq:QI (match_operator 1 "ix86_comparison_operator"
12673 [(reg 17) (const_int 0)])
12674 (const_int 0)))]
12675 ""
12676 [(set (match_dup 0) (match_dup 1))]
12677 {
12678 rtx new_op1 = copy_rtx (operands[1]);
12679 operands[1] = new_op1;
12680 PUT_MODE (new_op1, QImode);
12681 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12682 GET_MODE (XEXP (new_op1, 0))));
12683
12684 /* Make sure that (a) the CCmode we have for the flags is strong
12685 enough for the reversed compare or (b) we have a valid FP compare. */
12686 if (! ix86_comparison_operator (new_op1, VOIDmode))
12687 FAIL;
12688 })
12689
12690 (define_split
12691 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12692 (eq:QI (match_operator 1 "ix86_comparison_operator"
12693 [(reg 17) (const_int 0)])
12694 (const_int 0)))]
12695 ""
12696 [(set (match_dup 0) (match_dup 1))]
12697 {
12698 rtx new_op1 = copy_rtx (operands[1]);
12699 operands[1] = new_op1;
12700 PUT_MODE (new_op1, QImode);
12701 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12702 GET_MODE (XEXP (new_op1, 0))));
12703
12704 /* Make sure that (a) the CCmode we have for the flags is strong
12705 enough for the reversed compare or (b) we have a valid FP compare. */
12706 if (! ix86_comparison_operator (new_op1, VOIDmode))
12707 FAIL;
12708 })
12709
12710 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12711 ;; subsequent logical operations are used to imitate conditional moves.
12712 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12713 ;; it directly. Further holding this value in pseudo register might bring
12714 ;; problem in implicit normalization in spill code.
12715 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12716 ;; instructions after reload by splitting the conditional move patterns.
12717
12718 (define_insn "*sse_setccsf"
12719 [(set (match_operand:SF 0 "register_operand" "=x")
12720 (match_operator:SF 1 "sse_comparison_operator"
12721 [(match_operand:SF 2 "register_operand" "0")
12722 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12723 "TARGET_SSE && reload_completed"
12724 "cmp%D1ss\t{%3, %0|%0, %3}"
12725 [(set_attr "type" "ssecmp")
12726 (set_attr "mode" "SF")])
12727
12728 (define_insn "*sse_setccdf"
12729 [(set (match_operand:DF 0 "register_operand" "=Y")
12730 (match_operator:DF 1 "sse_comparison_operator"
12731 [(match_operand:DF 2 "register_operand" "0")
12732 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12733 "TARGET_SSE2 && reload_completed"
12734 "cmp%D1sd\t{%3, %0|%0, %3}"
12735 [(set_attr "type" "ssecmp")
12736 (set_attr "mode" "DF")])
12737 \f
12738 ;; Basic conditional jump instructions.
12739 ;; We ignore the overflow flag for signed branch instructions.
12740
12741 ;; For all bCOND expanders, also expand the compare or test insn that
12742 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12743
12744 (define_expand "beq"
12745 [(set (pc)
12746 (if_then_else (match_dup 1)
12747 (label_ref (match_operand 0 "" ""))
12748 (pc)))]
12749 ""
12750 "ix86_expand_branch (EQ, operands[0]); DONE;")
12751
12752 (define_expand "bne"
12753 [(set (pc)
12754 (if_then_else (match_dup 1)
12755 (label_ref (match_operand 0 "" ""))
12756 (pc)))]
12757 ""
12758 "ix86_expand_branch (NE, operands[0]); DONE;")
12759
12760 (define_expand "bgt"
12761 [(set (pc)
12762 (if_then_else (match_dup 1)
12763 (label_ref (match_operand 0 "" ""))
12764 (pc)))]
12765 ""
12766 "ix86_expand_branch (GT, operands[0]); DONE;")
12767
12768 (define_expand "bgtu"
12769 [(set (pc)
12770 (if_then_else (match_dup 1)
12771 (label_ref (match_operand 0 "" ""))
12772 (pc)))]
12773 ""
12774 "ix86_expand_branch (GTU, operands[0]); DONE;")
12775
12776 (define_expand "blt"
12777 [(set (pc)
12778 (if_then_else (match_dup 1)
12779 (label_ref (match_operand 0 "" ""))
12780 (pc)))]
12781 ""
12782 "ix86_expand_branch (LT, operands[0]); DONE;")
12783
12784 (define_expand "bltu"
12785 [(set (pc)
12786 (if_then_else (match_dup 1)
12787 (label_ref (match_operand 0 "" ""))
12788 (pc)))]
12789 ""
12790 "ix86_expand_branch (LTU, operands[0]); DONE;")
12791
12792 (define_expand "bge"
12793 [(set (pc)
12794 (if_then_else (match_dup 1)
12795 (label_ref (match_operand 0 "" ""))
12796 (pc)))]
12797 ""
12798 "ix86_expand_branch (GE, operands[0]); DONE;")
12799
12800 (define_expand "bgeu"
12801 [(set (pc)
12802 (if_then_else (match_dup 1)
12803 (label_ref (match_operand 0 "" ""))
12804 (pc)))]
12805 ""
12806 "ix86_expand_branch (GEU, operands[0]); DONE;")
12807
12808 (define_expand "ble"
12809 [(set (pc)
12810 (if_then_else (match_dup 1)
12811 (label_ref (match_operand 0 "" ""))
12812 (pc)))]
12813 ""
12814 "ix86_expand_branch (LE, operands[0]); DONE;")
12815
12816 (define_expand "bleu"
12817 [(set (pc)
12818 (if_then_else (match_dup 1)
12819 (label_ref (match_operand 0 "" ""))
12820 (pc)))]
12821 ""
12822 "ix86_expand_branch (LEU, operands[0]); DONE;")
12823
12824 (define_expand "bunordered"
12825 [(set (pc)
12826 (if_then_else (match_dup 1)
12827 (label_ref (match_operand 0 "" ""))
12828 (pc)))]
12829 "TARGET_80387 || TARGET_SSE"
12830 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12831
12832 (define_expand "bordered"
12833 [(set (pc)
12834 (if_then_else (match_dup 1)
12835 (label_ref (match_operand 0 "" ""))
12836 (pc)))]
12837 "TARGET_80387 || TARGET_SSE"
12838 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12839
12840 (define_expand "buneq"
12841 [(set (pc)
12842 (if_then_else (match_dup 1)
12843 (label_ref (match_operand 0 "" ""))
12844 (pc)))]
12845 "TARGET_80387 || TARGET_SSE"
12846 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12847
12848 (define_expand "bunge"
12849 [(set (pc)
12850 (if_then_else (match_dup 1)
12851 (label_ref (match_operand 0 "" ""))
12852 (pc)))]
12853 "TARGET_80387 || TARGET_SSE"
12854 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12855
12856 (define_expand "bungt"
12857 [(set (pc)
12858 (if_then_else (match_dup 1)
12859 (label_ref (match_operand 0 "" ""))
12860 (pc)))]
12861 "TARGET_80387 || TARGET_SSE"
12862 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12863
12864 (define_expand "bunle"
12865 [(set (pc)
12866 (if_then_else (match_dup 1)
12867 (label_ref (match_operand 0 "" ""))
12868 (pc)))]
12869 "TARGET_80387 || TARGET_SSE"
12870 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12871
12872 (define_expand "bunlt"
12873 [(set (pc)
12874 (if_then_else (match_dup 1)
12875 (label_ref (match_operand 0 "" ""))
12876 (pc)))]
12877 "TARGET_80387 || TARGET_SSE"
12878 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12879
12880 (define_expand "bltgt"
12881 [(set (pc)
12882 (if_then_else (match_dup 1)
12883 (label_ref (match_operand 0 "" ""))
12884 (pc)))]
12885 "TARGET_80387 || TARGET_SSE"
12886 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12887
12888 (define_insn "*jcc_1"
12889 [(set (pc)
12890 (if_then_else (match_operator 1 "ix86_comparison_operator"
12891 [(reg 17) (const_int 0)])
12892 (label_ref (match_operand 0 "" ""))
12893 (pc)))]
12894 ""
12895 "%+j%C1\t%l0"
12896 [(set_attr "type" "ibr")
12897 (set_attr "modrm" "0")
12898 (set (attr "length")
12899 (if_then_else (and (ge (minus (match_dup 0) (pc))
12900 (const_int -126))
12901 (lt (minus (match_dup 0) (pc))
12902 (const_int 128)))
12903 (const_int 2)
12904 (const_int 6)))])
12905
12906 (define_insn "*jcc_2"
12907 [(set (pc)
12908 (if_then_else (match_operator 1 "ix86_comparison_operator"
12909 [(reg 17) (const_int 0)])
12910 (pc)
12911 (label_ref (match_operand 0 "" ""))))]
12912 ""
12913 "%+j%c1\t%l0"
12914 [(set_attr "type" "ibr")
12915 (set_attr "modrm" "0")
12916 (set (attr "length")
12917 (if_then_else (and (ge (minus (match_dup 0) (pc))
12918 (const_int -126))
12919 (lt (minus (match_dup 0) (pc))
12920 (const_int 128)))
12921 (const_int 2)
12922 (const_int 6)))])
12923
12924 ;; In general it is not safe to assume too much about CCmode registers,
12925 ;; so simplify-rtx stops when it sees a second one. Under certain
12926 ;; conditions this is safe on x86, so help combine not create
12927 ;;
12928 ;; seta %al
12929 ;; testb %al, %al
12930 ;; je Lfoo
12931
12932 (define_split
12933 [(set (pc)
12934 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12935 [(reg 17) (const_int 0)])
12936 (const_int 0))
12937 (label_ref (match_operand 1 "" ""))
12938 (pc)))]
12939 ""
12940 [(set (pc)
12941 (if_then_else (match_dup 0)
12942 (label_ref (match_dup 1))
12943 (pc)))]
12944 {
12945 PUT_MODE (operands[0], VOIDmode);
12946 })
12947
12948 (define_split
12949 [(set (pc)
12950 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12951 [(reg 17) (const_int 0)])
12952 (const_int 0))
12953 (label_ref (match_operand 1 "" ""))
12954 (pc)))]
12955 ""
12956 [(set (pc)
12957 (if_then_else (match_dup 0)
12958 (label_ref (match_dup 1))
12959 (pc)))]
12960 {
12961 rtx new_op0 = copy_rtx (operands[0]);
12962 operands[0] = new_op0;
12963 PUT_MODE (new_op0, VOIDmode);
12964 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
12965 GET_MODE (XEXP (new_op0, 0))));
12966
12967 /* Make sure that (a) the CCmode we have for the flags is strong
12968 enough for the reversed compare or (b) we have a valid FP compare. */
12969 if (! ix86_comparison_operator (new_op0, VOIDmode))
12970 FAIL;
12971 })
12972
12973 ;; Define combination compare-and-branch fp compare instructions to use
12974 ;; during early optimization. Splitting the operation apart early makes
12975 ;; for bad code when we want to reverse the operation.
12976
12977 (define_insn "*fp_jcc_1"
12978 [(set (pc)
12979 (if_then_else (match_operator 0 "comparison_operator"
12980 [(match_operand 1 "register_operand" "f")
12981 (match_operand 2 "register_operand" "f")])
12982 (label_ref (match_operand 3 "" ""))
12983 (pc)))
12984 (clobber (reg:CCFP 18))
12985 (clobber (reg:CCFP 17))]
12986 "TARGET_CMOVE && TARGET_80387
12987 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12988 && FLOAT_MODE_P (GET_MODE (operands[1]))
12989 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12990 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12991 "#")
12992
12993 (define_insn "*fp_jcc_1_sse"
12994 [(set (pc)
12995 (if_then_else (match_operator 0 "comparison_operator"
12996 [(match_operand 1 "register_operand" "f#x,x#f")
12997 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12998 (label_ref (match_operand 3 "" ""))
12999 (pc)))
13000 (clobber (reg:CCFP 18))
13001 (clobber (reg:CCFP 17))]
13002 "TARGET_80387
13003 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13004 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13005 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13006 "#")
13007
13008 (define_insn "*fp_jcc_1_sse_only"
13009 [(set (pc)
13010 (if_then_else (match_operator 0 "comparison_operator"
13011 [(match_operand 1 "register_operand" "x")
13012 (match_operand 2 "nonimmediate_operand" "xm")])
13013 (label_ref (match_operand 3 "" ""))
13014 (pc)))
13015 (clobber (reg:CCFP 18))
13016 (clobber (reg:CCFP 17))]
13017 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13018 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13019 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13020 "#")
13021
13022 (define_insn "*fp_jcc_2"
13023 [(set (pc)
13024 (if_then_else (match_operator 0 "comparison_operator"
13025 [(match_operand 1 "register_operand" "f")
13026 (match_operand 2 "register_operand" "f")])
13027 (pc)
13028 (label_ref (match_operand 3 "" ""))))
13029 (clobber (reg:CCFP 18))
13030 (clobber (reg:CCFP 17))]
13031 "TARGET_CMOVE && TARGET_80387
13032 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13033 && FLOAT_MODE_P (GET_MODE (operands[1]))
13034 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13035 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13036 "#")
13037
13038 (define_insn "*fp_jcc_2_sse"
13039 [(set (pc)
13040 (if_then_else (match_operator 0 "comparison_operator"
13041 [(match_operand 1 "register_operand" "f#x,x#f")
13042 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13043 (pc)
13044 (label_ref (match_operand 3 "" ""))))
13045 (clobber (reg:CCFP 18))
13046 (clobber (reg:CCFP 17))]
13047 "TARGET_80387
13048 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13049 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13050 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13051 "#")
13052
13053 (define_insn "*fp_jcc_2_sse_only"
13054 [(set (pc)
13055 (if_then_else (match_operator 0 "comparison_operator"
13056 [(match_operand 1 "register_operand" "x")
13057 (match_operand 2 "nonimmediate_operand" "xm")])
13058 (pc)
13059 (label_ref (match_operand 3 "" ""))))
13060 (clobber (reg:CCFP 18))
13061 (clobber (reg:CCFP 17))]
13062 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13063 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13064 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13065 "#")
13066
13067 (define_insn "*fp_jcc_3"
13068 [(set (pc)
13069 (if_then_else (match_operator 0 "comparison_operator"
13070 [(match_operand 1 "register_operand" "f")
13071 (match_operand 2 "nonimmediate_operand" "fm")])
13072 (label_ref (match_operand 3 "" ""))
13073 (pc)))
13074 (clobber (reg:CCFP 18))
13075 (clobber (reg:CCFP 17))
13076 (clobber (match_scratch:HI 4 "=a"))]
13077 "TARGET_80387
13078 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13079 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13080 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13081 && SELECT_CC_MODE (GET_CODE (operands[0]),
13082 operands[1], operands[2]) == CCFPmode
13083 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13084 "#")
13085
13086 (define_insn "*fp_jcc_4"
13087 [(set (pc)
13088 (if_then_else (match_operator 0 "comparison_operator"
13089 [(match_operand 1 "register_operand" "f")
13090 (match_operand 2 "nonimmediate_operand" "fm")])
13091 (pc)
13092 (label_ref (match_operand 3 "" ""))))
13093 (clobber (reg:CCFP 18))
13094 (clobber (reg:CCFP 17))
13095 (clobber (match_scratch:HI 4 "=a"))]
13096 "TARGET_80387
13097 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13098 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13099 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13100 && SELECT_CC_MODE (GET_CODE (operands[0]),
13101 operands[1], operands[2]) == CCFPmode
13102 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13103 "#")
13104
13105 (define_insn "*fp_jcc_5"
13106 [(set (pc)
13107 (if_then_else (match_operator 0 "comparison_operator"
13108 [(match_operand 1 "register_operand" "f")
13109 (match_operand 2 "register_operand" "f")])
13110 (label_ref (match_operand 3 "" ""))
13111 (pc)))
13112 (clobber (reg:CCFP 18))
13113 (clobber (reg:CCFP 17))
13114 (clobber (match_scratch:HI 4 "=a"))]
13115 "TARGET_80387
13116 && FLOAT_MODE_P (GET_MODE (operands[1]))
13117 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13118 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13119 "#")
13120
13121 (define_insn "*fp_jcc_6"
13122 [(set (pc)
13123 (if_then_else (match_operator 0 "comparison_operator"
13124 [(match_operand 1 "register_operand" "f")
13125 (match_operand 2 "register_operand" "f")])
13126 (pc)
13127 (label_ref (match_operand 3 "" ""))))
13128 (clobber (reg:CCFP 18))
13129 (clobber (reg:CCFP 17))
13130 (clobber (match_scratch:HI 4 "=a"))]
13131 "TARGET_80387
13132 && FLOAT_MODE_P (GET_MODE (operands[1]))
13133 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13134 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13135 "#")
13136
13137 (define_split
13138 [(set (pc)
13139 (if_then_else (match_operator 0 "comparison_operator"
13140 [(match_operand 1 "register_operand" "")
13141 (match_operand 2 "nonimmediate_operand" "")])
13142 (match_operand 3 "" "")
13143 (match_operand 4 "" "")))
13144 (clobber (reg:CCFP 18))
13145 (clobber (reg:CCFP 17))]
13146 "reload_completed"
13147 [(const_int 0)]
13148 {
13149 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13150 operands[3], operands[4], NULL_RTX);
13151 DONE;
13152 })
13153
13154 (define_split
13155 [(set (pc)
13156 (if_then_else (match_operator 0 "comparison_operator"
13157 [(match_operand 1 "register_operand" "")
13158 (match_operand 2 "nonimmediate_operand" "")])
13159 (match_operand 3 "" "")
13160 (match_operand 4 "" "")))
13161 (clobber (reg:CCFP 18))
13162 (clobber (reg:CCFP 17))
13163 (clobber (match_scratch:HI 5 "=a"))]
13164 "reload_completed"
13165 [(set (pc)
13166 (if_then_else (match_dup 6)
13167 (match_dup 3)
13168 (match_dup 4)))]
13169 {
13170 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13171 operands[3], operands[4], operands[5]);
13172 DONE;
13173 })
13174 \f
13175 ;; Unconditional and other jump instructions
13176
13177 (define_insn "jump"
13178 [(set (pc)
13179 (label_ref (match_operand 0 "" "")))]
13180 ""
13181 "jmp\t%l0"
13182 [(set_attr "type" "ibr")
13183 (set (attr "length")
13184 (if_then_else (and (ge (minus (match_dup 0) (pc))
13185 (const_int -126))
13186 (lt (minus (match_dup 0) (pc))
13187 (const_int 128)))
13188 (const_int 2)
13189 (const_int 5)))
13190 (set_attr "modrm" "0")])
13191
13192 (define_expand "indirect_jump"
13193 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13194 ""
13195 "")
13196
13197 (define_insn "*indirect_jump"
13198 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13199 "!TARGET_64BIT"
13200 "jmp\t%A0"
13201 [(set_attr "type" "ibr")
13202 (set_attr "length_immediate" "0")])
13203
13204 (define_insn "*indirect_jump_rtx64"
13205 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13206 "TARGET_64BIT"
13207 "jmp\t%A0"
13208 [(set_attr "type" "ibr")
13209 (set_attr "length_immediate" "0")])
13210
13211 (define_expand "tablejump"
13212 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13213 (use (label_ref (match_operand 1 "" "")))])]
13214 ""
13215 {
13216 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13217 relative. Convert the relative address to an absolute address. */
13218 if (flag_pic)
13219 {
13220 rtx op0, op1;
13221 enum rtx_code code;
13222
13223 if (TARGET_64BIT)
13224 {
13225 code = PLUS;
13226 op0 = operands[0];
13227 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13228 }
13229 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13230 {
13231 code = PLUS;
13232 op0 = operands[0];
13233 op1 = pic_offset_table_rtx;
13234 }
13235 else
13236 {
13237 code = MINUS;
13238 op0 = pic_offset_table_rtx;
13239 op1 = operands[0];
13240 }
13241
13242 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13243 OPTAB_DIRECT);
13244 }
13245 })
13246
13247 (define_insn "*tablejump_1"
13248 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13249 (use (label_ref (match_operand 1 "" "")))]
13250 "!TARGET_64BIT"
13251 "jmp\t%A0"
13252 [(set_attr "type" "ibr")
13253 (set_attr "length_immediate" "0")])
13254
13255 (define_insn "*tablejump_1_rtx64"
13256 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13257 (use (label_ref (match_operand 1 "" "")))]
13258 "TARGET_64BIT"
13259 "jmp\t%A0"
13260 [(set_attr "type" "ibr")
13261 (set_attr "length_immediate" "0")])
13262 \f
13263 ;; Loop instruction
13264 ;;
13265 ;; This is all complicated by the fact that since this is a jump insn
13266 ;; we must handle our own reloads.
13267
13268 (define_expand "doloop_end"
13269 [(use (match_operand 0 "" "")) ; loop pseudo
13270 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13271 (use (match_operand 2 "" "")) ; max iterations
13272 (use (match_operand 3 "" "")) ; loop level
13273 (use (match_operand 4 "" ""))] ; label
13274 "!TARGET_64BIT && TARGET_USE_LOOP"
13275 "
13276 {
13277 /* Only use cloop on innermost loops. */
13278 if (INTVAL (operands[3]) > 1)
13279 FAIL;
13280 if (GET_MODE (operands[0]) != SImode)
13281 FAIL;
13282 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13283 operands[0]));
13284 DONE;
13285 }")
13286
13287 (define_insn "doloop_end_internal"
13288 [(set (pc)
13289 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13290 (const_int 1))
13291 (label_ref (match_operand 0 "" ""))
13292 (pc)))
13293 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13294 (plus:SI (match_dup 1)
13295 (const_int -1)))
13296 (clobber (match_scratch:SI 3 "=X,X,r"))
13297 (clobber (reg:CC 17))]
13298 "!TARGET_64BIT && TARGET_USE_LOOP"
13299 {
13300 if (which_alternative != 0)
13301 return "#";
13302 if (get_attr_length (insn) == 2)
13303 return "%+loop\t%l0";
13304 else
13305 return "dec{l}\t%1\;%+jne\t%l0";
13306 }
13307 [(set_attr "ppro_uops" "many")
13308 (set (attr "length")
13309 (if_then_else (and (eq_attr "alternative" "0")
13310 (and (ge (minus (match_dup 0) (pc))
13311 (const_int -126))
13312 (lt (minus (match_dup 0) (pc))
13313 (const_int 128))))
13314 (const_int 2)
13315 (const_int 16)))
13316 ;; We don't know the type before shorten branches. Optimistically expect
13317 ;; the loop instruction to match.
13318 (set (attr "type") (const_string "ibr"))])
13319
13320 (define_split
13321 [(set (pc)
13322 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13323 (const_int 1))
13324 (match_operand 0 "" "")
13325 (pc)))
13326 (set (match_dup 1)
13327 (plus:SI (match_dup 1)
13328 (const_int -1)))
13329 (clobber (match_scratch:SI 2 ""))
13330 (clobber (reg:CC 17))]
13331 "!TARGET_64BIT && TARGET_USE_LOOP
13332 && reload_completed
13333 && REGNO (operands[1]) != 2"
13334 [(parallel [(set (reg:CCZ 17)
13335 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13336 (const_int 0)))
13337 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13338 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13339 (match_dup 0)
13340 (pc)))]
13341 "")
13342
13343 (define_split
13344 [(set (pc)
13345 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13346 (const_int 1))
13347 (match_operand 0 "" "")
13348 (pc)))
13349 (set (match_operand:SI 2 "nonimmediate_operand" "")
13350 (plus:SI (match_dup 1)
13351 (const_int -1)))
13352 (clobber (match_scratch:SI 3 ""))
13353 (clobber (reg:CC 17))]
13354 "!TARGET_64BIT && TARGET_USE_LOOP
13355 && reload_completed
13356 && (! REG_P (operands[2])
13357 || ! rtx_equal_p (operands[1], operands[2]))"
13358 [(set (match_dup 3) (match_dup 1))
13359 (parallel [(set (reg:CCZ 17)
13360 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13361 (const_int 0)))
13362 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13363 (set (match_dup 2) (match_dup 3))
13364 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13365 (match_dup 0)
13366 (pc)))]
13367 "")
13368
13369 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13370
13371 (define_peephole2
13372 [(set (reg 17) (match_operand 0 "" ""))
13373 (set (match_operand:QI 1 "register_operand" "")
13374 (match_operator:QI 2 "ix86_comparison_operator"
13375 [(reg 17) (const_int 0)]))
13376 (set (match_operand 3 "q_regs_operand" "")
13377 (zero_extend (match_dup 1)))]
13378 "(peep2_reg_dead_p (3, operands[1])
13379 || operands_match_p (operands[1], operands[3]))
13380 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13381 [(set (match_dup 4) (match_dup 0))
13382 (set (strict_low_part (match_dup 5))
13383 (match_dup 2))]
13384 {
13385 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13386 operands[5] = gen_lowpart (QImode, operands[3]);
13387 ix86_expand_clear (operands[3]);
13388 })
13389
13390 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13391
13392 (define_peephole2
13393 [(set (reg 17) (match_operand 0 "" ""))
13394 (set (match_operand:QI 1 "register_operand" "")
13395 (match_operator:QI 2 "ix86_comparison_operator"
13396 [(reg 17) (const_int 0)]))
13397 (parallel [(set (match_operand 3 "q_regs_operand" "")
13398 (zero_extend (match_dup 1)))
13399 (clobber (reg:CC 17))])]
13400 "(peep2_reg_dead_p (3, operands[1])
13401 || operands_match_p (operands[1], operands[3]))
13402 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13403 [(set (match_dup 4) (match_dup 0))
13404 (set (strict_low_part (match_dup 5))
13405 (match_dup 2))]
13406 {
13407 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13408 operands[5] = gen_lowpart (QImode, operands[3]);
13409 ix86_expand_clear (operands[3]);
13410 })
13411 \f
13412 ;; Call instructions.
13413
13414 ;; The predicates normally associated with named expanders are not properly
13415 ;; checked for calls. This is a bug in the generic code, but it isn't that
13416 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13417
13418 ;; Call subroutine returning no value.
13419
13420 (define_expand "call_pop"
13421 [(parallel [(call (match_operand:QI 0 "" "")
13422 (match_operand:SI 1 "" ""))
13423 (set (reg:SI 7)
13424 (plus:SI (reg:SI 7)
13425 (match_operand:SI 3 "" "")))])]
13426 "!TARGET_64BIT"
13427 {
13428 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13429 DONE;
13430 })
13431
13432 (define_insn "*call_pop_0"
13433 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13434 (match_operand:SI 1 "" ""))
13435 (set (reg:SI 7) (plus:SI (reg:SI 7)
13436 (match_operand:SI 2 "immediate_operand" "")))]
13437 "!TARGET_64BIT"
13438 {
13439 if (SIBLING_CALL_P (insn))
13440 return "jmp\t%P0";
13441 else
13442 return "call\t%P0";
13443 }
13444 [(set_attr "type" "call")])
13445
13446 (define_insn "*call_pop_1"
13447 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13448 (match_operand:SI 1 "" ""))
13449 (set (reg:SI 7) (plus:SI (reg:SI 7)
13450 (match_operand:SI 2 "immediate_operand" "i")))]
13451 "!TARGET_64BIT"
13452 {
13453 if (constant_call_address_operand (operands[0], Pmode))
13454 {
13455 if (SIBLING_CALL_P (insn))
13456 return "jmp\t%P0";
13457 else
13458 return "call\t%P0";
13459 }
13460 if (SIBLING_CALL_P (insn))
13461 return "jmp\t%A0";
13462 else
13463 return "call\t%A0";
13464 }
13465 [(set_attr "type" "call")])
13466
13467 (define_expand "call"
13468 [(call (match_operand:QI 0 "" "")
13469 (match_operand 1 "" ""))
13470 (use (match_operand 2 "" ""))]
13471 ""
13472 {
13473 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13474 DONE;
13475 })
13476
13477 (define_expand "sibcall"
13478 [(call (match_operand:QI 0 "" "")
13479 (match_operand 1 "" ""))
13480 (use (match_operand 2 "" ""))]
13481 ""
13482 {
13483 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13484 DONE;
13485 })
13486
13487 (define_insn "*call_0"
13488 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13489 (match_operand 1 "" ""))]
13490 ""
13491 {
13492 if (SIBLING_CALL_P (insn))
13493 return "jmp\t%P0";
13494 else
13495 return "call\t%P0";
13496 }
13497 [(set_attr "type" "call")])
13498
13499 (define_insn "*call_1"
13500 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13501 (match_operand 1 "" ""))]
13502 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13503 {
13504 if (constant_call_address_operand (operands[0], QImode))
13505 return "call\t%P0";
13506 return "call\t%A0";
13507 }
13508 [(set_attr "type" "call")])
13509
13510 (define_insn "*sibcall_1"
13511 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13512 (match_operand 1 "" ""))]
13513 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13514 {
13515 if (constant_call_address_operand (operands[0], QImode))
13516 return "jmp\t%P0";
13517 return "jmp\t%A0";
13518 }
13519 [(set_attr "type" "call")])
13520
13521 (define_insn "*call_1_rex64"
13522 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13523 (match_operand 1 "" ""))]
13524 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13525 {
13526 if (constant_call_address_operand (operands[0], QImode))
13527 return "call\t%P0";
13528 return "call\t%A0";
13529 }
13530 [(set_attr "type" "call")])
13531
13532 (define_insn "*sibcall_1_rex64"
13533 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13534 (match_operand 1 "" ""))]
13535 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13536 "jmp\t%P0"
13537 [(set_attr "type" "call")])
13538
13539 (define_insn "*sibcall_1_rex64_v"
13540 [(call (mem:QI (reg:DI 40))
13541 (match_operand 0 "" ""))]
13542 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13543 "jmp\t*%%r11"
13544 [(set_attr "type" "call")])
13545
13546
13547 ;; Call subroutine, returning value in operand 0
13548
13549 (define_expand "call_value_pop"
13550 [(parallel [(set (match_operand 0 "" "")
13551 (call (match_operand:QI 1 "" "")
13552 (match_operand:SI 2 "" "")))
13553 (set (reg:SI 7)
13554 (plus:SI (reg:SI 7)
13555 (match_operand:SI 4 "" "")))])]
13556 "!TARGET_64BIT"
13557 {
13558 ix86_expand_call (operands[0], operands[1], operands[2],
13559 operands[3], operands[4], 0);
13560 DONE;
13561 })
13562
13563 (define_expand "call_value"
13564 [(set (match_operand 0 "" "")
13565 (call (match_operand:QI 1 "" "")
13566 (match_operand:SI 2 "" "")))
13567 (use (match_operand:SI 3 "" ""))]
13568 ;; Operand 2 not used on the i386.
13569 ""
13570 {
13571 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13572 DONE;
13573 })
13574
13575 (define_expand "sibcall_value"
13576 [(set (match_operand 0 "" "")
13577 (call (match_operand:QI 1 "" "")
13578 (match_operand:SI 2 "" "")))
13579 (use (match_operand:SI 3 "" ""))]
13580 ;; Operand 2 not used on the i386.
13581 ""
13582 {
13583 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13584 DONE;
13585 })
13586
13587 ;; Call subroutine returning any type.
13588
13589 (define_expand "untyped_call"
13590 [(parallel [(call (match_operand 0 "" "")
13591 (const_int 0))
13592 (match_operand 1 "" "")
13593 (match_operand 2 "" "")])]
13594 ""
13595 {
13596 int i;
13597
13598 /* In order to give reg-stack an easier job in validating two
13599 coprocessor registers as containing a possible return value,
13600 simply pretend the untyped call returns a complex long double
13601 value. */
13602
13603 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13604 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13605 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13606 NULL, 0);
13607
13608 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13609 {
13610 rtx set = XVECEXP (operands[2], 0, i);
13611 emit_move_insn (SET_DEST (set), SET_SRC (set));
13612 }
13613
13614 /* The optimizer does not know that the call sets the function value
13615 registers we stored in the result block. We avoid problems by
13616 claiming that all hard registers are used and clobbered at this
13617 point. */
13618 emit_insn (gen_blockage (const0_rtx));
13619
13620 DONE;
13621 })
13622 \f
13623 ;; Prologue and epilogue instructions
13624
13625 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13626 ;; all of memory. This blocks insns from being moved across this point.
13627
13628 (define_insn "blockage"
13629 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13630 ""
13631 ""
13632 [(set_attr "length" "0")])
13633
13634 ;; Insn emitted into the body of a function to return from a function.
13635 ;; This is only done if the function's epilogue is known to be simple.
13636 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13637
13638 (define_expand "return"
13639 [(return)]
13640 "ix86_can_use_return_insn_p ()"
13641 {
13642 if (current_function_pops_args)
13643 {
13644 rtx popc = GEN_INT (current_function_pops_args);
13645 emit_jump_insn (gen_return_pop_internal (popc));
13646 DONE;
13647 }
13648 })
13649
13650 (define_insn "return_internal"
13651 [(return)]
13652 "reload_completed"
13653 "ret"
13654 [(set_attr "length" "1")
13655 (set_attr "length_immediate" "0")
13656 (set_attr "modrm" "0")])
13657
13658 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13659 ;; instruction Athlon and K8 have.
13660
13661 (define_insn "return_internal_long"
13662 [(return)
13663 (unspec [(const_int 0)] UNSPEC_REP)]
13664 "reload_completed"
13665 "rep {;} ret"
13666 [(set_attr "length" "1")
13667 (set_attr "length_immediate" "0")
13668 (set_attr "prefix_rep" "1")
13669 (set_attr "modrm" "0")])
13670
13671 (define_insn "return_pop_internal"
13672 [(return)
13673 (use (match_operand:SI 0 "const_int_operand" ""))]
13674 "reload_completed"
13675 "ret\t%0"
13676 [(set_attr "length" "3")
13677 (set_attr "length_immediate" "2")
13678 (set_attr "modrm" "0")])
13679
13680 (define_insn "return_indirect_internal"
13681 [(return)
13682 (use (match_operand:SI 0 "register_operand" "r"))]
13683 "reload_completed"
13684 "jmp\t%A0"
13685 [(set_attr "type" "ibr")
13686 (set_attr "length_immediate" "0")])
13687
13688 (define_insn "nop"
13689 [(const_int 0)]
13690 ""
13691 "nop"
13692 [(set_attr "length" "1")
13693 (set_attr "length_immediate" "0")
13694 (set_attr "modrm" "0")
13695 (set_attr "ppro_uops" "one")])
13696
13697 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13698 ;; branch prediction penalty for the third jump in a 16-byte
13699 ;; block on K8.
13700
13701 (define_insn "align"
13702 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13703 ""
13704 {
13705 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13706 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13707 #else
13708 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13709 The align insn is used to avoid 3 jump instructions in the row to improve
13710 branch prediction and the benefits hardly outweight the cost of extra 8
13711 nops on the average inserted by full alignment pseudo operation. */
13712 #endif
13713 return "";
13714 }
13715 [(set_attr "length" "16")])
13716
13717 (define_expand "prologue"
13718 [(const_int 1)]
13719 ""
13720 "ix86_expand_prologue (); DONE;")
13721
13722 (define_insn "set_got"
13723 [(set (match_operand:SI 0 "register_operand" "=r")
13724 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13725 (clobber (reg:CC 17))]
13726 "!TARGET_64BIT"
13727 { return output_set_got (operands[0]); }
13728 [(set_attr "type" "multi")
13729 (set_attr "length" "12")])
13730
13731 (define_expand "epilogue"
13732 [(const_int 1)]
13733 ""
13734 "ix86_expand_epilogue (1); DONE;")
13735
13736 (define_expand "sibcall_epilogue"
13737 [(const_int 1)]
13738 ""
13739 "ix86_expand_epilogue (0); DONE;")
13740
13741 (define_expand "eh_return"
13742 [(use (match_operand 0 "register_operand" ""))]
13743 ""
13744 {
13745 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13746
13747 /* Tricky bit: we write the address of the handler to which we will
13748 be returning into someone else's stack frame, one word below the
13749 stack address we wish to restore. */
13750 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13751 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13752 tmp = gen_rtx_MEM (Pmode, tmp);
13753 emit_move_insn (tmp, ra);
13754
13755 if (Pmode == SImode)
13756 emit_insn (gen_eh_return_si (sa));
13757 else
13758 emit_insn (gen_eh_return_di (sa));
13759 emit_barrier ();
13760 DONE;
13761 })
13762
13763 (define_insn_and_split "eh_return_si"
13764 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13765 UNSPECV_EH_RETURN)]
13766 "!TARGET_64BIT"
13767 "#"
13768 "reload_completed"
13769 [(const_int 1)]
13770 "ix86_expand_epilogue (2); DONE;")
13771
13772 (define_insn_and_split "eh_return_di"
13773 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13774 UNSPECV_EH_RETURN)]
13775 "TARGET_64BIT"
13776 "#"
13777 "reload_completed"
13778 [(const_int 1)]
13779 "ix86_expand_epilogue (2); DONE;")
13780
13781 (define_insn "leave"
13782 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13783 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13784 (clobber (mem:BLK (scratch)))]
13785 "!TARGET_64BIT"
13786 "leave"
13787 [(set_attr "type" "leave")])
13788
13789 (define_insn "leave_rex64"
13790 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13791 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13792 (clobber (mem:BLK (scratch)))]
13793 "TARGET_64BIT"
13794 "leave"
13795 [(set_attr "type" "leave")])
13796 \f
13797 (define_expand "ffssi2"
13798 [(parallel
13799 [(set (match_operand:SI 0 "register_operand" "")
13800 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13801 (clobber (match_scratch:SI 2 ""))
13802 (clobber (reg:CC 17))])]
13803 ""
13804 "")
13805
13806 (define_insn_and_split "*ffs_cmove"
13807 [(set (match_operand:SI 0 "register_operand" "=r")
13808 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13809 (clobber (match_scratch:SI 2 "=&r"))
13810 (clobber (reg:CC 17))]
13811 "TARGET_CMOVE"
13812 "#"
13813 "&& reload_completed"
13814 [(set (match_dup 2) (const_int -1))
13815 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13816 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13817 (set (match_dup 0) (if_then_else:SI
13818 (eq (reg:CCZ 17) (const_int 0))
13819 (match_dup 2)
13820 (match_dup 0)))
13821 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13822 (clobber (reg:CC 17))])]
13823 "")
13824
13825 (define_insn_and_split "*ffs_no_cmove"
13826 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13827 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13828 (clobber (match_scratch:SI 2 "=&q"))
13829 (clobber (reg:CC 17))]
13830 ""
13831 "#"
13832 "reload_completed"
13833 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13834 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13835 (set (strict_low_part (match_dup 3))
13836 (eq:QI (reg:CCZ 17) (const_int 0)))
13837 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13838 (clobber (reg:CC 17))])
13839 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13840 (clobber (reg:CC 17))])
13841 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13842 (clobber (reg:CC 17))])]
13843 {
13844 operands[3] = gen_lowpart (QImode, operands[2]);
13845 ix86_expand_clear (operands[2]);
13846 })
13847
13848 (define_insn "*ffssi_1"
13849 [(set (reg:CCZ 17)
13850 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13851 (const_int 0)))
13852 (set (match_operand:SI 0 "register_operand" "=r")
13853 (ctz:SI (match_dup 1)))]
13854 ""
13855 "bsf{l}\t{%1, %0|%0, %1}"
13856 [(set_attr "prefix_0f" "1")
13857 (set_attr "ppro_uops" "few")])
13858
13859 (define_insn "ctzsi2"
13860 [(set (match_operand:SI 0 "register_operand" "=r")
13861 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13862 (clobber (reg:CC 17))]
13863 ""
13864 "bsf{l}\t{%1, %0|%0, %1}"
13865 [(set_attr "prefix_0f" "1")
13866 (set_attr "ppro_uops" "few")])
13867
13868 (define_expand "clzsi2"
13869 [(parallel
13870 [(set (match_operand:SI 0 "register_operand" "")
13871 (minus:SI (const_int 31)
13872 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13873 (clobber (reg:CC 17))])
13874 (parallel
13875 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13876 (clobber (reg:CC 17))])]
13877 ""
13878 "")
13879
13880 (define_insn "*bsr"
13881 [(set (match_operand:SI 0 "register_operand" "=r")
13882 (minus:SI (const_int 31)
13883 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13884 (clobber (reg:CC 17))]
13885 ""
13886 "bsr{l}\t{%1, %0|%0, %1}"
13887 [(set_attr "prefix_0f" "1")
13888 (set_attr "ppro_uops" "few")])
13889 \f
13890 ;; Thread-local storage patterns for ELF.
13891 ;;
13892 ;; Note that these code sequences must appear exactly as shown
13893 ;; in order to allow linker relaxation.
13894
13895 (define_insn "*tls_global_dynamic_32_gnu"
13896 [(set (match_operand:SI 0 "register_operand" "=a")
13897 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13898 (match_operand:SI 2 "tls_symbolic_operand" "")
13899 (match_operand:SI 3 "call_insn_operand" "")]
13900 UNSPEC_TLS_GD))
13901 (clobber (match_scratch:SI 4 "=d"))
13902 (clobber (match_scratch:SI 5 "=c"))
13903 (clobber (reg:CC 17))]
13904 "!TARGET_64BIT && TARGET_GNU_TLS"
13905 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13906 [(set_attr "type" "multi")
13907 (set_attr "length" "12")])
13908
13909 (define_insn "*tls_global_dynamic_32_sun"
13910 [(set (match_operand:SI 0 "register_operand" "=a")
13911 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13912 (match_operand:SI 2 "tls_symbolic_operand" "")
13913 (match_operand:SI 3 "call_insn_operand" "")]
13914 UNSPEC_TLS_GD))
13915 (clobber (match_scratch:SI 4 "=d"))
13916 (clobber (match_scratch:SI 5 "=c"))
13917 (clobber (reg:CC 17))]
13918 "!TARGET_64BIT && TARGET_SUN_TLS"
13919 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13920 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13921 [(set_attr "type" "multi")
13922 (set_attr "length" "14")])
13923
13924 (define_expand "tls_global_dynamic_32"
13925 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13926 (unspec:SI
13927 [(match_dup 2)
13928 (match_operand:SI 1 "tls_symbolic_operand" "")
13929 (match_dup 3)]
13930 UNSPEC_TLS_GD))
13931 (clobber (match_scratch:SI 4 ""))
13932 (clobber (match_scratch:SI 5 ""))
13933 (clobber (reg:CC 17))])]
13934 ""
13935 {
13936 if (flag_pic)
13937 operands[2] = pic_offset_table_rtx;
13938 else
13939 {
13940 operands[2] = gen_reg_rtx (Pmode);
13941 emit_insn (gen_set_got (operands[2]));
13942 }
13943 operands[3] = ix86_tls_get_addr ();
13944 })
13945
13946 (define_insn "*tls_global_dynamic_64"
13947 [(set (match_operand:DI 0 "register_operand" "=a")
13948 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13949 (match_operand:DI 3 "" "")))
13950 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13951 UNSPEC_TLS_GD)]
13952 "TARGET_64BIT"
13953 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13954 [(set_attr "type" "multi")
13955 (set_attr "length" "16")])
13956
13957 (define_expand "tls_global_dynamic_64"
13958 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13959 (call (mem:QI (match_dup 2)) (const_int 0)))
13960 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13961 UNSPEC_TLS_GD)])]
13962 ""
13963 {
13964 operands[2] = ix86_tls_get_addr ();
13965 })
13966
13967 (define_insn "*tls_local_dynamic_base_32_gnu"
13968 [(set (match_operand:SI 0 "register_operand" "=a")
13969 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13970 (match_operand:SI 2 "call_insn_operand" "")]
13971 UNSPEC_TLS_LD_BASE))
13972 (clobber (match_scratch:SI 3 "=d"))
13973 (clobber (match_scratch:SI 4 "=c"))
13974 (clobber (reg:CC 17))]
13975 "!TARGET_64BIT && TARGET_GNU_TLS"
13976 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13977 [(set_attr "type" "multi")
13978 (set_attr "length" "11")])
13979
13980 (define_insn "*tls_local_dynamic_base_32_sun"
13981 [(set (match_operand:SI 0 "register_operand" "=a")
13982 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13983 (match_operand:SI 2 "call_insn_operand" "")]
13984 UNSPEC_TLS_LD_BASE))
13985 (clobber (match_scratch:SI 3 "=d"))
13986 (clobber (match_scratch:SI 4 "=c"))
13987 (clobber (reg:CC 17))]
13988 "!TARGET_64BIT && TARGET_SUN_TLS"
13989 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13990 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13991 [(set_attr "type" "multi")
13992 (set_attr "length" "13")])
13993
13994 (define_expand "tls_local_dynamic_base_32"
13995 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13996 (unspec:SI [(match_dup 1) (match_dup 2)]
13997 UNSPEC_TLS_LD_BASE))
13998 (clobber (match_scratch:SI 3 ""))
13999 (clobber (match_scratch:SI 4 ""))
14000 (clobber (reg:CC 17))])]
14001 ""
14002 {
14003 if (flag_pic)
14004 operands[1] = pic_offset_table_rtx;
14005 else
14006 {
14007 operands[1] = gen_reg_rtx (Pmode);
14008 emit_insn (gen_set_got (operands[1]));
14009 }
14010 operands[2] = ix86_tls_get_addr ();
14011 })
14012
14013 (define_insn "*tls_local_dynamic_base_64"
14014 [(set (match_operand:DI 0 "register_operand" "=a")
14015 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14016 (match_operand:DI 2 "" "")))
14017 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14018 "TARGET_64BIT"
14019 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14020 [(set_attr "type" "multi")
14021 (set_attr "length" "12")])
14022
14023 (define_expand "tls_local_dynamic_base_64"
14024 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14025 (call (mem:QI (match_dup 1)) (const_int 0)))
14026 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14027 ""
14028 {
14029 operands[1] = ix86_tls_get_addr ();
14030 })
14031
14032 ;; Local dynamic of a single variable is a lose. Show combine how
14033 ;; to convert that back to global dynamic.
14034
14035 (define_insn_and_split "*tls_local_dynamic_32_once"
14036 [(set (match_operand:SI 0 "register_operand" "=a")
14037 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14038 (match_operand:SI 2 "call_insn_operand" "")]
14039 UNSPEC_TLS_LD_BASE)
14040 (const:SI (unspec:SI
14041 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14042 UNSPEC_DTPOFF))))
14043 (clobber (match_scratch:SI 4 "=d"))
14044 (clobber (match_scratch:SI 5 "=c"))
14045 (clobber (reg:CC 17))]
14046 ""
14047 "#"
14048 ""
14049 [(parallel [(set (match_dup 0)
14050 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14051 UNSPEC_TLS_GD))
14052 (clobber (match_dup 4))
14053 (clobber (match_dup 5))
14054 (clobber (reg:CC 17))])]
14055 "")
14056
14057 ;; Load and add the thread base pointer from %gs:0.
14058
14059 (define_insn "*load_tp_si"
14060 [(set (match_operand:SI 0 "register_operand" "=r")
14061 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14062 "!TARGET_64BIT"
14063 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14064 [(set_attr "type" "imov")
14065 (set_attr "modrm" "0")
14066 (set_attr "length" "7")
14067 (set_attr "memory" "load")
14068 (set_attr "imm_disp" "false")])
14069
14070 (define_insn "*add_tp_si"
14071 [(set (match_operand:SI 0 "register_operand" "=r")
14072 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14073 (match_operand:SI 1 "register_operand" "0")))
14074 (clobber (reg:CC 17))]
14075 "!TARGET_64BIT"
14076 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14077 [(set_attr "type" "alu")
14078 (set_attr "modrm" "0")
14079 (set_attr "length" "7")
14080 (set_attr "memory" "load")
14081 (set_attr "imm_disp" "false")])
14082
14083 (define_insn "*load_tp_di"
14084 [(set (match_operand:DI 0 "register_operand" "=r")
14085 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14086 "TARGET_64BIT"
14087 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14088 [(set_attr "type" "imov")
14089 (set_attr "modrm" "0")
14090 (set_attr "length" "7")
14091 (set_attr "memory" "load")
14092 (set_attr "imm_disp" "false")])
14093
14094 (define_insn "*add_tp_di"
14095 [(set (match_operand:DI 0 "register_operand" "=r")
14096 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14097 (match_operand:DI 1 "register_operand" "0")))
14098 (clobber (reg:CC 17))]
14099 "TARGET_64BIT"
14100 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14101 [(set_attr "type" "alu")
14102 (set_attr "modrm" "0")
14103 (set_attr "length" "7")
14104 (set_attr "memory" "load")
14105 (set_attr "imm_disp" "false")])
14106 \f
14107 ;; These patterns match the binary 387 instructions for addM3, subM3,
14108 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14109 ;; SFmode. The first is the normal insn, the second the same insn but
14110 ;; with one operand a conversion, and the third the same insn but with
14111 ;; the other operand a conversion. The conversion may be SFmode or
14112 ;; SImode if the target mode DFmode, but only SImode if the target mode
14113 ;; is SFmode.
14114
14115 ;; Gcc is slightly more smart about handling normal two address instructions
14116 ;; so use special patterns for add and mull.
14117 (define_insn "*fop_sf_comm_nosse"
14118 [(set (match_operand:SF 0 "register_operand" "=f")
14119 (match_operator:SF 3 "binary_fp_operator"
14120 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14121 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14122 "TARGET_80387 && !TARGET_SSE_MATH
14123 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14124 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14125 "* return output_387_binary_op (insn, operands);"
14126 [(set (attr "type")
14127 (if_then_else (match_operand:SF 3 "mult_operator" "")
14128 (const_string "fmul")
14129 (const_string "fop")))
14130 (set_attr "mode" "SF")])
14131
14132 (define_insn "*fop_sf_comm"
14133 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14134 (match_operator:SF 3 "binary_fp_operator"
14135 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14136 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14137 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14138 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14139 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14140 "* return output_387_binary_op (insn, operands);"
14141 [(set (attr "type")
14142 (if_then_else (eq_attr "alternative" "1")
14143 (if_then_else (match_operand:SF 3 "mult_operator" "")
14144 (const_string "ssemul")
14145 (const_string "sseadd"))
14146 (if_then_else (match_operand:SF 3 "mult_operator" "")
14147 (const_string "fmul")
14148 (const_string "fop"))))
14149 (set_attr "mode" "SF")])
14150
14151 (define_insn "*fop_sf_comm_sse"
14152 [(set (match_operand:SF 0 "register_operand" "=x")
14153 (match_operator:SF 3 "binary_fp_operator"
14154 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14155 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14156 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14157 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14158 "* return output_387_binary_op (insn, operands);"
14159 [(set (attr "type")
14160 (if_then_else (match_operand:SF 3 "mult_operator" "")
14161 (const_string "ssemul")
14162 (const_string "sseadd")))
14163 (set_attr "mode" "SF")])
14164
14165 (define_insn "*fop_df_comm_nosse"
14166 [(set (match_operand:DF 0 "register_operand" "=f")
14167 (match_operator:DF 3 "binary_fp_operator"
14168 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14169 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14170 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14171 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14172 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14173 "* return output_387_binary_op (insn, operands);"
14174 [(set (attr "type")
14175 (if_then_else (match_operand:SF 3 "mult_operator" "")
14176 (const_string "fmul")
14177 (const_string "fop")))
14178 (set_attr "mode" "DF")])
14179
14180 (define_insn "*fop_df_comm"
14181 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14182 (match_operator:DF 3 "binary_fp_operator"
14183 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14184 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14185 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14186 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14187 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14188 "* return output_387_binary_op (insn, operands);"
14189 [(set (attr "type")
14190 (if_then_else (eq_attr "alternative" "1")
14191 (if_then_else (match_operand:SF 3 "mult_operator" "")
14192 (const_string "ssemul")
14193 (const_string "sseadd"))
14194 (if_then_else (match_operand:SF 3 "mult_operator" "")
14195 (const_string "fmul")
14196 (const_string "fop"))))
14197 (set_attr "mode" "DF")])
14198
14199 (define_insn "*fop_df_comm_sse"
14200 [(set (match_operand:DF 0 "register_operand" "=Y")
14201 (match_operator:DF 3 "binary_fp_operator"
14202 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14203 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14204 "TARGET_SSE2 && TARGET_SSE_MATH
14205 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14206 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14207 "* return output_387_binary_op (insn, operands);"
14208 [(set (attr "type")
14209 (if_then_else (match_operand:SF 3 "mult_operator" "")
14210 (const_string "ssemul")
14211 (const_string "sseadd")))
14212 (set_attr "mode" "DF")])
14213
14214 (define_insn "*fop_xf_comm"
14215 [(set (match_operand:XF 0 "register_operand" "=f")
14216 (match_operator:XF 3 "binary_fp_operator"
14217 [(match_operand:XF 1 "register_operand" "%0")
14218 (match_operand:XF 2 "register_operand" "f")]))]
14219 "TARGET_80387
14220 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14221 "* return output_387_binary_op (insn, operands);"
14222 [(set (attr "type")
14223 (if_then_else (match_operand:XF 3 "mult_operator" "")
14224 (const_string "fmul")
14225 (const_string "fop")))
14226 (set_attr "mode" "XF")])
14227
14228 (define_insn "*fop_sf_1_nosse"
14229 [(set (match_operand:SF 0 "register_operand" "=f,f")
14230 (match_operator:SF 3 "binary_fp_operator"
14231 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14232 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14233 "TARGET_80387 && !TARGET_SSE_MATH
14234 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14235 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14236 "* return output_387_binary_op (insn, operands);"
14237 [(set (attr "type")
14238 (cond [(match_operand:SF 3 "mult_operator" "")
14239 (const_string "fmul")
14240 (match_operand:SF 3 "div_operator" "")
14241 (const_string "fdiv")
14242 ]
14243 (const_string "fop")))
14244 (set_attr "mode" "SF")])
14245
14246 (define_insn "*fop_sf_1"
14247 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14248 (match_operator:SF 3 "binary_fp_operator"
14249 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14250 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14251 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14252 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14253 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14254 "* return output_387_binary_op (insn, operands);"
14255 [(set (attr "type")
14256 (cond [(and (eq_attr "alternative" "2")
14257 (match_operand:SF 3 "mult_operator" ""))
14258 (const_string "ssemul")
14259 (and (eq_attr "alternative" "2")
14260 (match_operand:SF 3 "div_operator" ""))
14261 (const_string "ssediv")
14262 (eq_attr "alternative" "2")
14263 (const_string "sseadd")
14264 (match_operand:SF 3 "mult_operator" "")
14265 (const_string "fmul")
14266 (match_operand:SF 3 "div_operator" "")
14267 (const_string "fdiv")
14268 ]
14269 (const_string "fop")))
14270 (set_attr "mode" "SF")])
14271
14272 (define_insn "*fop_sf_1_sse"
14273 [(set (match_operand:SF 0 "register_operand" "=x")
14274 (match_operator:SF 3 "binary_fp_operator"
14275 [(match_operand:SF 1 "register_operand" "0")
14276 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14277 "TARGET_SSE_MATH
14278 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14279 "* return output_387_binary_op (insn, operands);"
14280 [(set (attr "type")
14281 (cond [(match_operand:SF 3 "mult_operator" "")
14282 (const_string "ssemul")
14283 (match_operand:SF 3 "div_operator" "")
14284 (const_string "ssediv")
14285 ]
14286 (const_string "sseadd")))
14287 (set_attr "mode" "SF")])
14288
14289 ;; ??? Add SSE splitters for these!
14290 (define_insn "*fop_sf_2"
14291 [(set (match_operand:SF 0 "register_operand" "=f,f")
14292 (match_operator:SF 3 "binary_fp_operator"
14293 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14294 (match_operand:SF 2 "register_operand" "0,0")]))]
14295 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14296 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14297 [(set (attr "type")
14298 (cond [(match_operand:SF 3 "mult_operator" "")
14299 (const_string "fmul")
14300 (match_operand:SF 3 "div_operator" "")
14301 (const_string "fdiv")
14302 ]
14303 (const_string "fop")))
14304 (set_attr "fp_int_src" "true")
14305 (set_attr "ppro_uops" "many")
14306 (set_attr "mode" "SI")])
14307
14308 (define_insn "*fop_sf_3"
14309 [(set (match_operand:SF 0 "register_operand" "=f,f")
14310 (match_operator:SF 3 "binary_fp_operator"
14311 [(match_operand:SF 1 "register_operand" "0,0")
14312 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14313 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14314 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14315 [(set (attr "type")
14316 (cond [(match_operand:SF 3 "mult_operator" "")
14317 (const_string "fmul")
14318 (match_operand:SF 3 "div_operator" "")
14319 (const_string "fdiv")
14320 ]
14321 (const_string "fop")))
14322 (set_attr "fp_int_src" "true")
14323 (set_attr "ppro_uops" "many")
14324 (set_attr "mode" "SI")])
14325
14326 (define_insn "*fop_df_1_nosse"
14327 [(set (match_operand:DF 0 "register_operand" "=f,f")
14328 (match_operator:DF 3 "binary_fp_operator"
14329 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14330 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14331 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14332 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14333 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14334 "* return output_387_binary_op (insn, operands);"
14335 [(set (attr "type")
14336 (cond [(match_operand:DF 3 "mult_operator" "")
14337 (const_string "fmul")
14338 (match_operand:DF 3 "div_operator" "")
14339 (const_string "fdiv")
14340 ]
14341 (const_string "fop")))
14342 (set_attr "mode" "DF")])
14343
14344
14345 (define_insn "*fop_df_1"
14346 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14347 (match_operator:DF 3 "binary_fp_operator"
14348 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14349 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14350 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14351 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14353 "* return output_387_binary_op (insn, operands);"
14354 [(set (attr "type")
14355 (cond [(and (eq_attr "alternative" "2")
14356 (match_operand:SF 3 "mult_operator" ""))
14357 (const_string "ssemul")
14358 (and (eq_attr "alternative" "2")
14359 (match_operand:SF 3 "div_operator" ""))
14360 (const_string "ssediv")
14361 (eq_attr "alternative" "2")
14362 (const_string "sseadd")
14363 (match_operand:DF 3 "mult_operator" "")
14364 (const_string "fmul")
14365 (match_operand:DF 3 "div_operator" "")
14366 (const_string "fdiv")
14367 ]
14368 (const_string "fop")))
14369 (set_attr "mode" "DF")])
14370
14371 (define_insn "*fop_df_1_sse"
14372 [(set (match_operand:DF 0 "register_operand" "=Y")
14373 (match_operator:DF 3 "binary_fp_operator"
14374 [(match_operand:DF 1 "register_operand" "0")
14375 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14376 "TARGET_SSE2 && TARGET_SSE_MATH
14377 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14378 "* return output_387_binary_op (insn, operands);"
14379 [(set_attr "mode" "DF")
14380 (set (attr "type")
14381 (cond [(match_operand:SF 3 "mult_operator" "")
14382 (const_string "ssemul")
14383 (match_operand:SF 3 "div_operator" "")
14384 (const_string "ssediv")
14385 ]
14386 (const_string "sseadd")))])
14387
14388 ;; ??? Add SSE splitters for these!
14389 (define_insn "*fop_df_2"
14390 [(set (match_operand:DF 0 "register_operand" "=f,f")
14391 (match_operator:DF 3 "binary_fp_operator"
14392 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14393 (match_operand:DF 2 "register_operand" "0,0")]))]
14394 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14395 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14396 [(set (attr "type")
14397 (cond [(match_operand:DF 3 "mult_operator" "")
14398 (const_string "fmul")
14399 (match_operand:DF 3 "div_operator" "")
14400 (const_string "fdiv")
14401 ]
14402 (const_string "fop")))
14403 (set_attr "fp_int_src" "true")
14404 (set_attr "ppro_uops" "many")
14405 (set_attr "mode" "SI")])
14406
14407 (define_insn "*fop_df_3"
14408 [(set (match_operand:DF 0 "register_operand" "=f,f")
14409 (match_operator:DF 3 "binary_fp_operator"
14410 [(match_operand:DF 1 "register_operand" "0,0")
14411 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14412 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14413 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14414 [(set (attr "type")
14415 (cond [(match_operand:DF 3 "mult_operator" "")
14416 (const_string "fmul")
14417 (match_operand:DF 3 "div_operator" "")
14418 (const_string "fdiv")
14419 ]
14420 (const_string "fop")))
14421 (set_attr "fp_int_src" "true")
14422 (set_attr "ppro_uops" "many")
14423 (set_attr "mode" "SI")])
14424
14425 (define_insn "*fop_df_4"
14426 [(set (match_operand:DF 0 "register_operand" "=f,f")
14427 (match_operator:DF 3 "binary_fp_operator"
14428 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14429 (match_operand:DF 2 "register_operand" "0,f")]))]
14430 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14431 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14432 "* return output_387_binary_op (insn, operands);"
14433 [(set (attr "type")
14434 (cond [(match_operand:DF 3 "mult_operator" "")
14435 (const_string "fmul")
14436 (match_operand:DF 3 "div_operator" "")
14437 (const_string "fdiv")
14438 ]
14439 (const_string "fop")))
14440 (set_attr "mode" "SF")])
14441
14442 (define_insn "*fop_df_5"
14443 [(set (match_operand:DF 0 "register_operand" "=f,f")
14444 (match_operator:DF 3 "binary_fp_operator"
14445 [(match_operand:DF 1 "register_operand" "0,f")
14446 (float_extend:DF
14447 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14448 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14449 "* return output_387_binary_op (insn, operands);"
14450 [(set (attr "type")
14451 (cond [(match_operand:DF 3 "mult_operator" "")
14452 (const_string "fmul")
14453 (match_operand:DF 3 "div_operator" "")
14454 (const_string "fdiv")
14455 ]
14456 (const_string "fop")))
14457 (set_attr "mode" "SF")])
14458
14459 (define_insn "*fop_df_6"
14460 [(set (match_operand:DF 0 "register_operand" "=f,f")
14461 (match_operator:DF 3 "binary_fp_operator"
14462 [(float_extend:DF
14463 (match_operand:SF 1 "register_operand" "0,f"))
14464 (float_extend:DF
14465 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14466 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14467 "* return output_387_binary_op (insn, operands);"
14468 [(set (attr "type")
14469 (cond [(match_operand:DF 3 "mult_operator" "")
14470 (const_string "fmul")
14471 (match_operand:DF 3 "div_operator" "")
14472 (const_string "fdiv")
14473 ]
14474 (const_string "fop")))
14475 (set_attr "mode" "SF")])
14476
14477 (define_insn "*fop_xf_1"
14478 [(set (match_operand:XF 0 "register_operand" "=f,f")
14479 (match_operator:XF 3 "binary_fp_operator"
14480 [(match_operand:XF 1 "register_operand" "0,f")
14481 (match_operand:XF 2 "register_operand" "f,0")]))]
14482 "TARGET_80387
14483 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14484 "* return output_387_binary_op (insn, operands);"
14485 [(set (attr "type")
14486 (cond [(match_operand:XF 3 "mult_operator" "")
14487 (const_string "fmul")
14488 (match_operand:XF 3 "div_operator" "")
14489 (const_string "fdiv")
14490 ]
14491 (const_string "fop")))
14492 (set_attr "mode" "XF")])
14493
14494 (define_insn "*fop_xf_2"
14495 [(set (match_operand:XF 0 "register_operand" "=f,f")
14496 (match_operator:XF 3 "binary_fp_operator"
14497 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14498 (match_operand:XF 2 "register_operand" "0,0")]))]
14499 "TARGET_80387 && TARGET_USE_FIOP"
14500 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14501 [(set (attr "type")
14502 (cond [(match_operand:XF 3 "mult_operator" "")
14503 (const_string "fmul")
14504 (match_operand:XF 3 "div_operator" "")
14505 (const_string "fdiv")
14506 ]
14507 (const_string "fop")))
14508 (set_attr "fp_int_src" "true")
14509 (set_attr "mode" "SI")
14510 (set_attr "ppro_uops" "many")])
14511
14512 (define_insn "*fop_xf_3"
14513 [(set (match_operand:XF 0 "register_operand" "=f,f")
14514 (match_operator:XF 3 "binary_fp_operator"
14515 [(match_operand:XF 1 "register_operand" "0,0")
14516 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14517 "TARGET_80387 && TARGET_USE_FIOP"
14518 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14519 [(set (attr "type")
14520 (cond [(match_operand:XF 3 "mult_operator" "")
14521 (const_string "fmul")
14522 (match_operand:XF 3 "div_operator" "")
14523 (const_string "fdiv")
14524 ]
14525 (const_string "fop")))
14526 (set_attr "fp_int_src" "true")
14527 (set_attr "mode" "SI")
14528 (set_attr "ppro_uops" "many")])
14529
14530 (define_insn "*fop_xf_4"
14531 [(set (match_operand:XF 0 "register_operand" "=f,f")
14532 (match_operator:XF 3 "binary_fp_operator"
14533 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14534 (match_operand:XF 2 "register_operand" "0,f")]))]
14535 "TARGET_80387"
14536 "* return output_387_binary_op (insn, operands);"
14537 [(set (attr "type")
14538 (cond [(match_operand:XF 3 "mult_operator" "")
14539 (const_string "fmul")
14540 (match_operand:XF 3 "div_operator" "")
14541 (const_string "fdiv")
14542 ]
14543 (const_string "fop")))
14544 (set_attr "mode" "SF")])
14545
14546 (define_insn "*fop_xf_5"
14547 [(set (match_operand:XF 0 "register_operand" "=f,f")
14548 (match_operator:XF 3 "binary_fp_operator"
14549 [(match_operand:XF 1 "register_operand" "0,f")
14550 (float_extend:XF
14551 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14552 "TARGET_80387"
14553 "* return output_387_binary_op (insn, operands);"
14554 [(set (attr "type")
14555 (cond [(match_operand:XF 3 "mult_operator" "")
14556 (const_string "fmul")
14557 (match_operand:XF 3 "div_operator" "")
14558 (const_string "fdiv")
14559 ]
14560 (const_string "fop")))
14561 (set_attr "mode" "SF")])
14562
14563 (define_insn "*fop_xf_6"
14564 [(set (match_operand:XF 0 "register_operand" "=f,f")
14565 (match_operator:XF 3 "binary_fp_operator"
14566 [(float_extend:XF
14567 (match_operand 1 "register_operand" "0,f"))
14568 (float_extend:XF
14569 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14570 "TARGET_80387"
14571 "* return output_387_binary_op (insn, operands);"
14572 [(set (attr "type")
14573 (cond [(match_operand:XF 3 "mult_operator" "")
14574 (const_string "fmul")
14575 (match_operand:XF 3 "div_operator" "")
14576 (const_string "fdiv")
14577 ]
14578 (const_string "fop")))
14579 (set_attr "mode" "SF")])
14580
14581 (define_split
14582 [(set (match_operand 0 "register_operand" "")
14583 (match_operator 3 "binary_fp_operator"
14584 [(float (match_operand:SI 1 "register_operand" ""))
14585 (match_operand 2 "register_operand" "")]))]
14586 "TARGET_80387 && reload_completed
14587 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14588 [(const_int 0)]
14589 {
14590 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14591 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14592 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14593 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14594 GET_MODE (operands[3]),
14595 operands[4],
14596 operands[2])));
14597 ix86_free_from_memory (GET_MODE (operands[1]));
14598 DONE;
14599 })
14600
14601 (define_split
14602 [(set (match_operand 0 "register_operand" "")
14603 (match_operator 3 "binary_fp_operator"
14604 [(match_operand 1 "register_operand" "")
14605 (float (match_operand:SI 2 "register_operand" ""))]))]
14606 "TARGET_80387 && reload_completed
14607 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14608 [(const_int 0)]
14609 {
14610 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14611 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14612 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14613 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14614 GET_MODE (operands[3]),
14615 operands[1],
14616 operands[4])));
14617 ix86_free_from_memory (GET_MODE (operands[2]));
14618 DONE;
14619 })
14620 \f
14621 ;; FPU special functions.
14622
14623 (define_expand "sqrtsf2"
14624 [(set (match_operand:SF 0 "register_operand" "")
14625 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14626 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14627 {
14628 if (!TARGET_SSE_MATH)
14629 operands[1] = force_reg (SFmode, operands[1]);
14630 })
14631
14632 (define_insn "sqrtsf2_1"
14633 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14634 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14635 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14636 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14637 "@
14638 fsqrt
14639 sqrtss\t{%1, %0|%0, %1}"
14640 [(set_attr "type" "fpspc,sse")
14641 (set_attr "mode" "SF,SF")
14642 (set_attr "athlon_decode" "direct,*")])
14643
14644 (define_insn "sqrtsf2_1_sse_only"
14645 [(set (match_operand:SF 0 "register_operand" "=x")
14646 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14647 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14648 "sqrtss\t{%1, %0|%0, %1}"
14649 [(set_attr "type" "sse")
14650 (set_attr "mode" "SF")
14651 (set_attr "athlon_decode" "*")])
14652
14653 (define_insn "sqrtsf2_i387"
14654 [(set (match_operand:SF 0 "register_operand" "=f")
14655 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14656 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14657 && !TARGET_SSE_MATH"
14658 "fsqrt"
14659 [(set_attr "type" "fpspc")
14660 (set_attr "mode" "SF")
14661 (set_attr "athlon_decode" "direct")])
14662
14663 (define_expand "sqrtdf2"
14664 [(set (match_operand:DF 0 "register_operand" "")
14665 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14666 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14667 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14668 {
14669 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14670 operands[1] = force_reg (DFmode, operands[1]);
14671 })
14672
14673 (define_insn "sqrtdf2_1"
14674 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14675 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14676 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14677 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14678 "@
14679 fsqrt
14680 sqrtsd\t{%1, %0|%0, %1}"
14681 [(set_attr "type" "fpspc,sse")
14682 (set_attr "mode" "DF,DF")
14683 (set_attr "athlon_decode" "direct,*")])
14684
14685 (define_insn "sqrtdf2_1_sse_only"
14686 [(set (match_operand:DF 0 "register_operand" "=Y")
14687 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14688 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14689 "sqrtsd\t{%1, %0|%0, %1}"
14690 [(set_attr "type" "sse")
14691 (set_attr "mode" "DF")
14692 (set_attr "athlon_decode" "*")])
14693
14694 (define_insn "sqrtdf2_i387"
14695 [(set (match_operand:DF 0 "register_operand" "=f")
14696 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14697 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14698 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14699 "fsqrt"
14700 [(set_attr "type" "fpspc")
14701 (set_attr "mode" "DF")
14702 (set_attr "athlon_decode" "direct")])
14703
14704 (define_insn "*sqrtextendsfdf2"
14705 [(set (match_operand:DF 0 "register_operand" "=f")
14706 (sqrt:DF (float_extend:DF
14707 (match_operand:SF 1 "register_operand" "0"))))]
14708 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14709 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14710 "fsqrt"
14711 [(set_attr "type" "fpspc")
14712 (set_attr "mode" "DF")
14713 (set_attr "athlon_decode" "direct")])
14714
14715 (define_insn "sqrtxf2"
14716 [(set (match_operand:XF 0 "register_operand" "=f")
14717 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14718 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14719 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14720 "fsqrt"
14721 [(set_attr "type" "fpspc")
14722 (set_attr "mode" "XF")
14723 (set_attr "athlon_decode" "direct")])
14724
14725 (define_insn "*sqrtextenddfxf2"
14726 [(set (match_operand:XF 0 "register_operand" "=f")
14727 (sqrt:XF (float_extend:XF
14728 (match_operand:DF 1 "register_operand" "0"))))]
14729 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14730 "fsqrt"
14731 [(set_attr "type" "fpspc")
14732 (set_attr "mode" "XF")
14733 (set_attr "athlon_decode" "direct")])
14734
14735 (define_insn "*sqrtextendsfxf2"
14736 [(set (match_operand:XF 0 "register_operand" "=f")
14737 (sqrt:XF (float_extend:XF
14738 (match_operand:SF 1 "register_operand" "0"))))]
14739 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14740 "fsqrt"
14741 [(set_attr "type" "fpspc")
14742 (set_attr "mode" "XF")
14743 (set_attr "athlon_decode" "direct")])
14744
14745 (define_insn "sindf2"
14746 [(set (match_operand:DF 0 "register_operand" "=f")
14747 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14748 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14749 && flag_unsafe_math_optimizations"
14750 "fsin"
14751 [(set_attr "type" "fpspc")
14752 (set_attr "mode" "DF")])
14753
14754 (define_insn "sinsf2"
14755 [(set (match_operand:SF 0 "register_operand" "=f")
14756 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14757 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14758 && flag_unsafe_math_optimizations"
14759 "fsin"
14760 [(set_attr "type" "fpspc")
14761 (set_attr "mode" "SF")])
14762
14763 (define_insn "*sinextendsfdf2"
14764 [(set (match_operand:DF 0 "register_operand" "=f")
14765 (unspec:DF [(float_extend:DF
14766 (match_operand:SF 1 "register_operand" "0"))]
14767 UNSPEC_SIN))]
14768 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14769 && flag_unsafe_math_optimizations"
14770 "fsin"
14771 [(set_attr "type" "fpspc")
14772 (set_attr "mode" "DF")])
14773
14774 (define_insn "sinxf2"
14775 [(set (match_operand:XF 0 "register_operand" "=f")
14776 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14777 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14778 && flag_unsafe_math_optimizations"
14779 "fsin"
14780 [(set_attr "type" "fpspc")
14781 (set_attr "mode" "XF")])
14782
14783 (define_insn "cosdf2"
14784 [(set (match_operand:DF 0 "register_operand" "=f")
14785 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14786 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14787 && flag_unsafe_math_optimizations"
14788 "fcos"
14789 [(set_attr "type" "fpspc")
14790 (set_attr "mode" "DF")])
14791
14792 (define_insn "cossf2"
14793 [(set (match_operand:SF 0 "register_operand" "=f")
14794 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14795 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14796 && flag_unsafe_math_optimizations"
14797 "fcos"
14798 [(set_attr "type" "fpspc")
14799 (set_attr "mode" "SF")])
14800
14801 (define_insn "*cosextendsfdf2"
14802 [(set (match_operand:DF 0 "register_operand" "=f")
14803 (unspec:DF [(float_extend:DF
14804 (match_operand:SF 1 "register_operand" "0"))]
14805 UNSPEC_COS))]
14806 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14807 && flag_unsafe_math_optimizations"
14808 "fcos"
14809 [(set_attr "type" "fpspc")
14810 (set_attr "mode" "DF")])
14811
14812 (define_insn "cosxf2"
14813 [(set (match_operand:XF 0 "register_operand" "=f")
14814 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14815 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14816 && flag_unsafe_math_optimizations"
14817 "fcos"
14818 [(set_attr "type" "fpspc")
14819 (set_attr "mode" "XF")])
14820
14821 (define_insn "atan2df3_1"
14822 [(set (match_operand:DF 0 "register_operand" "=f")
14823 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
14824 (match_operand:DF 1 "register_operand" "u")]
14825 UNSPEC_FPATAN))
14826 (clobber (match_scratch:DF 3 "=1"))]
14827 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14828 && flag_unsafe_math_optimizations"
14829 "fpatan"
14830 [(set_attr "type" "fpspc")
14831 (set_attr "mode" "DF")])
14832
14833 (define_expand "atan2df3"
14834 [(use (match_operand:DF 0 "register_operand" "=f"))
14835 (use (match_operand:DF 2 "register_operand" "0"))
14836 (use (match_operand:DF 1 "register_operand" "u"))]
14837 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14838 && flag_unsafe_math_optimizations"
14839 {
14840 rtx copy = gen_reg_rtx (DFmode);
14841 emit_move_insn (copy, operands[1]);
14842 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
14843 DONE;
14844 })
14845
14846 (define_insn "atan2sf3_1"
14847 [(set (match_operand:SF 0 "register_operand" "=f")
14848 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
14849 (match_operand:SF 1 "register_operand" "u")]
14850 UNSPEC_FPATAN))
14851 (clobber (match_scratch:SF 3 "=1"))]
14852 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14853 && flag_unsafe_math_optimizations"
14854 "fpatan"
14855 [(set_attr "type" "fpspc")
14856 (set_attr "mode" "SF")])
14857
14858 (define_expand "atan2sf3"
14859 [(use (match_operand:SF 0 "register_operand" "=f"))
14860 (use (match_operand:SF 2 "register_operand" "0"))
14861 (use (match_operand:SF 1 "register_operand" "u"))]
14862 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14863 && flag_unsafe_math_optimizations"
14864 {
14865 rtx copy = gen_reg_rtx (SFmode);
14866 emit_move_insn (copy, operands[1]);
14867 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
14868 DONE;
14869 })
14870
14871 (define_insn "atan2xf3_1"
14872 [(set (match_operand:XF 0 "register_operand" "=f")
14873 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14874 (match_operand:XF 1 "register_operand" "u")]
14875 UNSPEC_FPATAN))
14876 (clobber (match_scratch:XF 3 "=1"))]
14877 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14878 && flag_unsafe_math_optimizations"
14879 "fpatan"
14880 [(set_attr "type" "fpspc")
14881 (set_attr "mode" "XF")])
14882
14883 (define_expand "atan2xf3"
14884 [(use (match_operand:XF 0 "register_operand" "=f"))
14885 (use (match_operand:XF 2 "register_operand" "0"))
14886 (use (match_operand:XF 1 "register_operand" "u"))]
14887 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14888 && flag_unsafe_math_optimizations"
14889 {
14890 rtx copy = gen_reg_rtx (XFmode);
14891 emit_move_insn (copy, operands[1]);
14892 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
14893 DONE;
14894 })
14895
14896 (define_insn "*fyl2x_sfxf3"
14897 [(set (match_operand:SF 0 "register_operand" "=f")
14898 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
14899 (match_operand:XF 1 "register_operand" "u")]
14900 UNSPEC_FYL2X))
14901 (clobber (match_scratch:SF 3 "=1"))]
14902 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14903 && flag_unsafe_math_optimizations"
14904 "fyl2x"
14905 [(set_attr "type" "fpspc")
14906 (set_attr "mode" "SF")])
14907
14908 (define_insn "*fyl2x_dfxf3"
14909 [(set (match_operand:DF 0 "register_operand" "=f")
14910 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
14911 (match_operand:XF 1 "register_operand" "u")]
14912 UNSPEC_FYL2X))
14913 (clobber (match_scratch:DF 3 "=1"))]
14914 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14915 && flag_unsafe_math_optimizations"
14916 "fyl2x"
14917 [(set_attr "type" "fpspc")
14918 (set_attr "mode" "DF")])
14919
14920 (define_insn "*fyl2x_xf3"
14921 [(set (match_operand:XF 0 "register_operand" "=f")
14922 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14923 (match_operand:XF 1 "register_operand" "u")]
14924 UNSPEC_FYL2X))
14925 (clobber (match_scratch:XF 3 "=1"))]
14926 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14927 && flag_unsafe_math_optimizations"
14928 "fyl2x"
14929 [(set_attr "type" "fpspc")
14930 (set_attr "mode" "XF")])
14931
14932 (define_expand "logsf2"
14933 [(parallel [(set (match_operand:SF 0 "register_operand" "")
14934 (unspec:SF [(match_operand:SF 1 "register_operand" "")
14935 (match_dup 2)] UNSPEC_FYL2X))
14936 (clobber (match_scratch:SF 3 ""))])]
14937 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14938 && flag_unsafe_math_optimizations"
14939 {
14940 rtx temp;
14941
14942 operands[2] = gen_reg_rtx (XFmode);
14943 temp = standard_80387_constant_rtx (4); /* fldln2 */
14944 emit_move_insn (operands[2], temp);
14945 })
14946
14947 (define_expand "logdf2"
14948 [(parallel [(set (match_operand:DF 0 "register_operand" "")
14949 (unspec:DF [(match_operand:DF 1 "register_operand" "")
14950 (match_dup 2)] UNSPEC_FYL2X))
14951 (clobber (match_scratch:DF 3 ""))])]
14952 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14953 && flag_unsafe_math_optimizations"
14954 {
14955 rtx temp;
14956
14957 operands[2] = gen_reg_rtx (XFmode);
14958 temp = standard_80387_constant_rtx (4); /* fldln2 */
14959 emit_move_insn (operands[2], temp);
14960 })
14961
14962 (define_expand "logxf2"
14963 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14964 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14965 (match_dup 2)] UNSPEC_FYL2X))
14966 (clobber (match_scratch:XF 3 ""))])]
14967 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14968 && flag_unsafe_math_optimizations"
14969 {
14970 rtx temp;
14971
14972 operands[2] = gen_reg_rtx (XFmode);
14973 temp = standard_80387_constant_rtx (4); /* fldln2 */
14974 emit_move_insn (operands[2], temp);
14975 })
14976
14977 (define_insn "*fscale_sfxf3"
14978 [(set (match_operand:SF 0 "register_operand" "=f")
14979 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
14980 (match_operand:XF 1 "register_operand" "u")]
14981 UNSPEC_FSCALE))
14982 (clobber (match_scratch:SF 3 "=1"))]
14983 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14984 && flag_unsafe_math_optimizations"
14985 "fscale\;fstp\t%y1"
14986 [(set_attr "type" "fpspc")
14987 (set_attr "mode" "SF")])
14988
14989 (define_insn "*fscale_dfxf3"
14990 [(set (match_operand:DF 0 "register_operand" "=f")
14991 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
14992 (match_operand:XF 1 "register_operand" "u")]
14993 UNSPEC_FSCALE))
14994 (clobber (match_scratch:DF 3 "=1"))]
14995 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14996 && flag_unsafe_math_optimizations"
14997 "fscale\;fstp\t%y1"
14998 [(set_attr "type" "fpspc")
14999 (set_attr "mode" "DF")])
15000
15001 (define_insn "*fscale_xf3"
15002 [(set (match_operand:XF 0 "register_operand" "=f")
15003 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15004 (match_operand:XF 1 "register_operand" "u")]
15005 UNSPEC_FSCALE))
15006 (clobber (match_scratch:XF 3 "=1"))]
15007 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15008 && flag_unsafe_math_optimizations"
15009 "fscale\;fstp\t%y1"
15010 [(set_attr "type" "fpspc")
15011 (set_attr "mode" "XF")])
15012
15013 (define_insn "*frndintxf2"
15014 [(set (match_operand:XF 0 "register_operand" "=f")
15015 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15016 UNSPEC_FRNDINT))]
15017 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15018 && flag_unsafe_math_optimizations"
15019 "frndint"
15020 [(set_attr "type" "fpspc")
15021 (set_attr "mode" "XF")])
15022
15023 (define_insn "*f2xm1xf2"
15024 [(set (match_operand:XF 0 "register_operand" "=f")
15025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15026 UNSPEC_F2XM1))]
15027 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15028 && flag_unsafe_math_optimizations"
15029 "f2xm1"
15030 [(set_attr "type" "fpspc")
15031 (set_attr "mode" "XF")])
15032
15033 (define_expand "expsf2"
15034 [(set (match_dup 2)
15035 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15036 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15037 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15038 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15039 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15040 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15041 (parallel [(set (match_operand:SF 0 "register_operand" "")
15042 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15043 (clobber (match_scratch:SF 5 ""))])]
15044 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15045 && flag_unsafe_math_optimizations"
15046 {
15047 rtx temp;
15048 int i;
15049
15050 for (i=2; i<10; i++)
15051 operands[i] = gen_reg_rtx (XFmode);
15052 temp = standard_80387_constant_rtx (5); /* fldl2e */
15053 emit_move_insn (operands[3], temp);
15054 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15055 })
15056
15057 (define_expand "expdf2"
15058 [(set (match_dup 2)
15059 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15060 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15061 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15062 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15063 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15064 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15065 (parallel [(set (match_operand:DF 0 "register_operand" "")
15066 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15067 (clobber (match_scratch:DF 5 ""))])]
15068 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15069 && flag_unsafe_math_optimizations"
15070 {
15071 rtx temp;
15072 int i;
15073
15074 for (i=2; i<10; i++)
15075 operands[i] = gen_reg_rtx (XFmode);
15076 temp = standard_80387_constant_rtx (5); /* fldl2e */
15077 emit_move_insn (operands[3], temp);
15078 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15079 })
15080
15081 (define_expand "expxf2"
15082 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15083 (match_dup 2)))
15084 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15085 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15086 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15087 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15088 (parallel [(set (match_operand:XF 0 "register_operand" "")
15089 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15090 (clobber (match_scratch:XF 5 ""))])]
15091 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092 && flag_unsafe_math_optimizations"
15093 {
15094 rtx temp;
15095 int i;
15096
15097 for (i=2; i<9; i++)
15098 operands[i] = gen_reg_rtx (XFmode);
15099 temp = standard_80387_constant_rtx (5); /* fldl2e */
15100 emit_move_insn (operands[2], temp);
15101 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15102 })
15103
15104 (define_expand "atansf2"
15105 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15106 (unspec:SF [(match_dup 2)
15107 (match_operand:SF 1 "register_operand" "")]
15108 UNSPEC_FPATAN))
15109 (clobber (match_scratch:SF 3 ""))])]
15110 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15111 && flag_unsafe_math_optimizations"
15112 {
15113 operands[2] = gen_reg_rtx (SFmode);
15114 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15115 })
15116
15117 (define_expand "atandf2"
15118 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15119 (unspec:DF [(match_dup 2)
15120 (match_operand:DF 1 "register_operand" "")]
15121 UNSPEC_FPATAN))
15122 (clobber (match_scratch:DF 3 ""))])]
15123 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15124 && flag_unsafe_math_optimizations"
15125 {
15126 operands[2] = gen_reg_rtx (DFmode);
15127 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15128 })
15129
15130 (define_expand "atanxf2"
15131 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15132 (unspec:XF [(match_dup 2)
15133 (match_operand:XF 1 "register_operand" "")]
15134 UNSPEC_FPATAN))
15135 (clobber (match_scratch:XF 3 ""))])]
15136 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15137 && flag_unsafe_math_optimizations"
15138 {
15139 operands[2] = gen_reg_rtx (XFmode);
15140 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15141 })
15142 \f
15143 ;; Block operation instructions
15144
15145 (define_insn "cld"
15146 [(set (reg:SI 19) (const_int 0))]
15147 ""
15148 "cld"
15149 [(set_attr "type" "cld")])
15150
15151 (define_expand "movstrsi"
15152 [(use (match_operand:BLK 0 "memory_operand" ""))
15153 (use (match_operand:BLK 1 "memory_operand" ""))
15154 (use (match_operand:SI 2 "nonmemory_operand" ""))
15155 (use (match_operand:SI 3 "const_int_operand" ""))]
15156 "! optimize_size"
15157 {
15158 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15159 DONE;
15160 else
15161 FAIL;
15162 })
15163
15164 (define_expand "movstrdi"
15165 [(use (match_operand:BLK 0 "memory_operand" ""))
15166 (use (match_operand:BLK 1 "memory_operand" ""))
15167 (use (match_operand:DI 2 "nonmemory_operand" ""))
15168 (use (match_operand:DI 3 "const_int_operand" ""))]
15169 "TARGET_64BIT"
15170 {
15171 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15172 DONE;
15173 else
15174 FAIL;
15175 })
15176
15177 ;; Most CPUs don't like single string operations
15178 ;; Handle this case here to simplify previous expander.
15179
15180 (define_expand "strmovdi_rex64"
15181 [(set (match_dup 2)
15182 (mem:DI (match_operand:DI 1 "register_operand" "")))
15183 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15184 (match_dup 2))
15185 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15186 (clobber (reg:CC 17))])
15187 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15188 (clobber (reg:CC 17))])]
15189 "TARGET_64BIT"
15190 {
15191 if (TARGET_SINGLE_STRINGOP || optimize_size)
15192 {
15193 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15194 operands[1]));
15195 DONE;
15196 }
15197 else
15198 operands[2] = gen_reg_rtx (DImode);
15199 })
15200
15201
15202 (define_expand "strmovsi"
15203 [(set (match_dup 2)
15204 (mem:SI (match_operand:SI 1 "register_operand" "")))
15205 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15206 (match_dup 2))
15207 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15208 (clobber (reg:CC 17))])
15209 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15210 (clobber (reg:CC 17))])]
15211 ""
15212 {
15213 if (TARGET_64BIT)
15214 {
15215 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15216 DONE;
15217 }
15218 if (TARGET_SINGLE_STRINGOP || optimize_size)
15219 {
15220 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15221 operands[1]));
15222 DONE;
15223 }
15224 else
15225 operands[2] = gen_reg_rtx (SImode);
15226 })
15227
15228 (define_expand "strmovsi_rex64"
15229 [(set (match_dup 2)
15230 (mem:SI (match_operand:DI 1 "register_operand" "")))
15231 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15232 (match_dup 2))
15233 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15234 (clobber (reg:CC 17))])
15235 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15236 (clobber (reg:CC 17))])]
15237 "TARGET_64BIT"
15238 {
15239 if (TARGET_SINGLE_STRINGOP || optimize_size)
15240 {
15241 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15242 operands[1]));
15243 DONE;
15244 }
15245 else
15246 operands[2] = gen_reg_rtx (SImode);
15247 })
15248
15249 (define_expand "strmovhi"
15250 [(set (match_dup 2)
15251 (mem:HI (match_operand:SI 1 "register_operand" "")))
15252 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15253 (match_dup 2))
15254 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15255 (clobber (reg:CC 17))])
15256 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15257 (clobber (reg:CC 17))])]
15258 ""
15259 {
15260 if (TARGET_64BIT)
15261 {
15262 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15263 DONE;
15264 }
15265 if (TARGET_SINGLE_STRINGOP || optimize_size)
15266 {
15267 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15268 operands[1]));
15269 DONE;
15270 }
15271 else
15272 operands[2] = gen_reg_rtx (HImode);
15273 })
15274
15275 (define_expand "strmovhi_rex64"
15276 [(set (match_dup 2)
15277 (mem:HI (match_operand:DI 1 "register_operand" "")))
15278 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15279 (match_dup 2))
15280 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15281 (clobber (reg:CC 17))])
15282 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15283 (clobber (reg:CC 17))])]
15284 "TARGET_64BIT"
15285 {
15286 if (TARGET_SINGLE_STRINGOP || optimize_size)
15287 {
15288 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15289 operands[1]));
15290 DONE;
15291 }
15292 else
15293 operands[2] = gen_reg_rtx (HImode);
15294 })
15295
15296 (define_expand "strmovqi"
15297 [(set (match_dup 2)
15298 (mem:QI (match_operand:SI 1 "register_operand" "")))
15299 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15300 (match_dup 2))
15301 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15302 (clobber (reg:CC 17))])
15303 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15304 (clobber (reg:CC 17))])]
15305 ""
15306 {
15307 if (TARGET_64BIT)
15308 {
15309 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15310 DONE;
15311 }
15312 if (TARGET_SINGLE_STRINGOP || optimize_size)
15313 {
15314 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15315 operands[1]));
15316 DONE;
15317 }
15318 else
15319 operands[2] = gen_reg_rtx (QImode);
15320 })
15321
15322 (define_expand "strmovqi_rex64"
15323 [(set (match_dup 2)
15324 (mem:QI (match_operand:DI 1 "register_operand" "")))
15325 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15326 (match_dup 2))
15327 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15328 (clobber (reg:CC 17))])
15329 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15330 (clobber (reg:CC 17))])]
15331 "TARGET_64BIT"
15332 {
15333 if (TARGET_SINGLE_STRINGOP || optimize_size)
15334 {
15335 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15336 operands[1]));
15337 DONE;
15338 }
15339 else
15340 operands[2] = gen_reg_rtx (QImode);
15341 })
15342
15343 (define_insn "strmovdi_rex_1"
15344 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15345 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15346 (set (match_operand:DI 0 "register_operand" "=D")
15347 (plus:DI (match_dup 2)
15348 (const_int 8)))
15349 (set (match_operand:DI 1 "register_operand" "=S")
15350 (plus:DI (match_dup 3)
15351 (const_int 8)))
15352 (use (reg:SI 19))]
15353 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15354 "movsq"
15355 [(set_attr "type" "str")
15356 (set_attr "mode" "DI")
15357 (set_attr "memory" "both")])
15358
15359 (define_insn "strmovsi_1"
15360 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15361 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15362 (set (match_operand:SI 0 "register_operand" "=D")
15363 (plus:SI (match_dup 2)
15364 (const_int 4)))
15365 (set (match_operand:SI 1 "register_operand" "=S")
15366 (plus:SI (match_dup 3)
15367 (const_int 4)))
15368 (use (reg:SI 19))]
15369 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15370 "{movsl|movsd}"
15371 [(set_attr "type" "str")
15372 (set_attr "mode" "SI")
15373 (set_attr "memory" "both")])
15374
15375 (define_insn "strmovsi_rex_1"
15376 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15377 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15378 (set (match_operand:DI 0 "register_operand" "=D")
15379 (plus:DI (match_dup 2)
15380 (const_int 4)))
15381 (set (match_operand:DI 1 "register_operand" "=S")
15382 (plus:DI (match_dup 3)
15383 (const_int 4)))
15384 (use (reg:SI 19))]
15385 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15386 "{movsl|movsd}"
15387 [(set_attr "type" "str")
15388 (set_attr "mode" "SI")
15389 (set_attr "memory" "both")])
15390
15391 (define_insn "strmovhi_1"
15392 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15393 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15394 (set (match_operand:SI 0 "register_operand" "=D")
15395 (plus:SI (match_dup 2)
15396 (const_int 2)))
15397 (set (match_operand:SI 1 "register_operand" "=S")
15398 (plus:SI (match_dup 3)
15399 (const_int 2)))
15400 (use (reg:SI 19))]
15401 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15402 "movsw"
15403 [(set_attr "type" "str")
15404 (set_attr "memory" "both")
15405 (set_attr "mode" "HI")])
15406
15407 (define_insn "strmovhi_rex_1"
15408 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15409 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15410 (set (match_operand:DI 0 "register_operand" "=D")
15411 (plus:DI (match_dup 2)
15412 (const_int 2)))
15413 (set (match_operand:DI 1 "register_operand" "=S")
15414 (plus:DI (match_dup 3)
15415 (const_int 2)))
15416 (use (reg:SI 19))]
15417 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15418 "movsw"
15419 [(set_attr "type" "str")
15420 (set_attr "memory" "both")
15421 (set_attr "mode" "HI")])
15422
15423 (define_insn "strmovqi_1"
15424 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15425 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15426 (set (match_operand:SI 0 "register_operand" "=D")
15427 (plus:SI (match_dup 2)
15428 (const_int 1)))
15429 (set (match_operand:SI 1 "register_operand" "=S")
15430 (plus:SI (match_dup 3)
15431 (const_int 1)))
15432 (use (reg:SI 19))]
15433 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15434 "movsb"
15435 [(set_attr "type" "str")
15436 (set_attr "memory" "both")
15437 (set_attr "mode" "QI")])
15438
15439 (define_insn "strmovqi_rex_1"
15440 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15441 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15442 (set (match_operand:DI 0 "register_operand" "=D")
15443 (plus:DI (match_dup 2)
15444 (const_int 1)))
15445 (set (match_operand:DI 1 "register_operand" "=S")
15446 (plus:DI (match_dup 3)
15447 (const_int 1)))
15448 (use (reg:SI 19))]
15449 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15450 "movsb"
15451 [(set_attr "type" "str")
15452 (set_attr "memory" "both")
15453 (set_attr "mode" "QI")])
15454
15455 (define_insn "rep_movdi_rex64"
15456 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15457 (set (match_operand:DI 0 "register_operand" "=D")
15458 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15459 (const_int 3))
15460 (match_operand:DI 3 "register_operand" "0")))
15461 (set (match_operand:DI 1 "register_operand" "=S")
15462 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15463 (match_operand:DI 4 "register_operand" "1")))
15464 (set (mem:BLK (match_dup 3))
15465 (mem:BLK (match_dup 4)))
15466 (use (match_dup 5))
15467 (use (reg:SI 19))]
15468 "TARGET_64BIT"
15469 "{rep\;movsq|rep movsq}"
15470 [(set_attr "type" "str")
15471 (set_attr "prefix_rep" "1")
15472 (set_attr "memory" "both")
15473 (set_attr "mode" "DI")])
15474
15475 (define_insn "rep_movsi"
15476 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15477 (set (match_operand:SI 0 "register_operand" "=D")
15478 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15479 (const_int 2))
15480 (match_operand:SI 3 "register_operand" "0")))
15481 (set (match_operand:SI 1 "register_operand" "=S")
15482 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15483 (match_operand:SI 4 "register_operand" "1")))
15484 (set (mem:BLK (match_dup 3))
15485 (mem:BLK (match_dup 4)))
15486 (use (match_dup 5))
15487 (use (reg:SI 19))]
15488 "!TARGET_64BIT"
15489 "{rep\;movsl|rep movsd}"
15490 [(set_attr "type" "str")
15491 (set_attr "prefix_rep" "1")
15492 (set_attr "memory" "both")
15493 (set_attr "mode" "SI")])
15494
15495 (define_insn "rep_movsi_rex64"
15496 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15497 (set (match_operand:DI 0 "register_operand" "=D")
15498 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15499 (const_int 2))
15500 (match_operand:DI 3 "register_operand" "0")))
15501 (set (match_operand:DI 1 "register_operand" "=S")
15502 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15503 (match_operand:DI 4 "register_operand" "1")))
15504 (set (mem:BLK (match_dup 3))
15505 (mem:BLK (match_dup 4)))
15506 (use (match_dup 5))
15507 (use (reg:SI 19))]
15508 "TARGET_64BIT"
15509 "{rep\;movsl|rep movsd}"
15510 [(set_attr "type" "str")
15511 (set_attr "prefix_rep" "1")
15512 (set_attr "memory" "both")
15513 (set_attr "mode" "SI")])
15514
15515 (define_insn "rep_movqi"
15516 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15517 (set (match_operand:SI 0 "register_operand" "=D")
15518 (plus:SI (match_operand:SI 3 "register_operand" "0")
15519 (match_operand:SI 5 "register_operand" "2")))
15520 (set (match_operand:SI 1 "register_operand" "=S")
15521 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15522 (set (mem:BLK (match_dup 3))
15523 (mem:BLK (match_dup 4)))
15524 (use (match_dup 5))
15525 (use (reg:SI 19))]
15526 "!TARGET_64BIT"
15527 "{rep\;movsb|rep movsb}"
15528 [(set_attr "type" "str")
15529 (set_attr "prefix_rep" "1")
15530 (set_attr "memory" "both")
15531 (set_attr "mode" "SI")])
15532
15533 (define_insn "rep_movqi_rex64"
15534 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15535 (set (match_operand:DI 0 "register_operand" "=D")
15536 (plus:DI (match_operand:DI 3 "register_operand" "0")
15537 (match_operand:DI 5 "register_operand" "2")))
15538 (set (match_operand:DI 1 "register_operand" "=S")
15539 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15540 (set (mem:BLK (match_dup 3))
15541 (mem:BLK (match_dup 4)))
15542 (use (match_dup 5))
15543 (use (reg:SI 19))]
15544 "TARGET_64BIT"
15545 "{rep\;movsb|rep movsb}"
15546 [(set_attr "type" "str")
15547 (set_attr "prefix_rep" "1")
15548 (set_attr "memory" "both")
15549 (set_attr "mode" "SI")])
15550
15551 (define_expand "clrstrsi"
15552 [(use (match_operand:BLK 0 "memory_operand" ""))
15553 (use (match_operand:SI 1 "nonmemory_operand" ""))
15554 (use (match_operand 2 "const_int_operand" ""))]
15555 ""
15556 {
15557 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15558 DONE;
15559 else
15560 FAIL;
15561 })
15562
15563 (define_expand "clrstrdi"
15564 [(use (match_operand:BLK 0 "memory_operand" ""))
15565 (use (match_operand:DI 1 "nonmemory_operand" ""))
15566 (use (match_operand 2 "const_int_operand" ""))]
15567 "TARGET_64BIT"
15568 {
15569 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15570 DONE;
15571 else
15572 FAIL;
15573 })
15574
15575 ;; Most CPUs don't like single string operations
15576 ;; Handle this case here to simplify previous expander.
15577
15578 (define_expand "strsetdi_rex64"
15579 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
15580 (match_operand:DI 1 "register_operand" ""))
15581 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15582 (clobber (reg:CC 17))])]
15583 "TARGET_64BIT"
15584 {
15585 if (TARGET_SINGLE_STRINGOP || optimize_size)
15586 {
15587 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
15588 DONE;
15589 }
15590 })
15591
15592 (define_expand "strsetsi"
15593 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
15594 (match_operand:SI 1 "register_operand" ""))
15595 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15596 (clobber (reg:CC 17))])]
15597 ""
15598 {
15599 if (TARGET_64BIT)
15600 {
15601 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
15602 DONE;
15603 }
15604 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15605 {
15606 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
15607 DONE;
15608 }
15609 })
15610
15611 (define_expand "strsetsi_rex64"
15612 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
15613 (match_operand:SI 1 "register_operand" ""))
15614 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15615 (clobber (reg:CC 17))])]
15616 "TARGET_64BIT"
15617 {
15618 if (TARGET_SINGLE_STRINGOP || optimize_size)
15619 {
15620 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
15621 DONE;
15622 }
15623 })
15624
15625 (define_expand "strsethi"
15626 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
15627 (match_operand:HI 1 "register_operand" ""))
15628 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15629 (clobber (reg:CC 17))])]
15630 ""
15631 {
15632 if (TARGET_64BIT)
15633 {
15634 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
15635 DONE;
15636 }
15637 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15638 {
15639 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
15640 DONE;
15641 }
15642 })
15643
15644 (define_expand "strsethi_rex64"
15645 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
15646 (match_operand:HI 1 "register_operand" ""))
15647 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15648 (clobber (reg:CC 17))])]
15649 "TARGET_64BIT"
15650 {
15651 if (TARGET_SINGLE_STRINGOP || optimize_size)
15652 {
15653 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
15654 DONE;
15655 }
15656 })
15657
15658 (define_expand "strsetqi"
15659 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
15660 (match_operand:QI 1 "register_operand" ""))
15661 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15662 (clobber (reg:CC 17))])]
15663 ""
15664 {
15665 if (TARGET_64BIT)
15666 {
15667 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
15668 DONE;
15669 }
15670 else if (TARGET_SINGLE_STRINGOP || optimize_size)
15671 {
15672 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
15673 DONE;
15674 }
15675 })
15676
15677 (define_expand "strsetqi_rex64"
15678 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
15679 (match_operand:QI 1 "register_operand" ""))
15680 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15681 (clobber (reg:CC 17))])]
15682 "TARGET_64BIT"
15683 {
15684 if (TARGET_SINGLE_STRINGOP || optimize_size)
15685 {
15686 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
15687 DONE;
15688 }
15689 })
15690
15691 (define_insn "strsetdi_rex_1"
15692 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15693 (match_operand:SI 2 "register_operand" "a"))
15694 (set (match_operand:DI 0 "register_operand" "=D")
15695 (plus:DI (match_dup 1)
15696 (const_int 8)))
15697 (use (reg:SI 19))]
15698 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15699 "stosq"
15700 [(set_attr "type" "str")
15701 (set_attr "memory" "store")
15702 (set_attr "mode" "DI")])
15703
15704 (define_insn "strsetsi_1"
15705 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15706 (match_operand:SI 2 "register_operand" "a"))
15707 (set (match_operand:SI 0 "register_operand" "=D")
15708 (plus:SI (match_dup 1)
15709 (const_int 4)))
15710 (use (reg:SI 19))]
15711 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15712 "{stosl|stosd}"
15713 [(set_attr "type" "str")
15714 (set_attr "memory" "store")
15715 (set_attr "mode" "SI")])
15716
15717 (define_insn "strsetsi_rex_1"
15718 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15719 (match_operand:SI 2 "register_operand" "a"))
15720 (set (match_operand:DI 0 "register_operand" "=D")
15721 (plus:DI (match_dup 1)
15722 (const_int 4)))
15723 (use (reg:SI 19))]
15724 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15725 "{stosl|stosd}"
15726 [(set_attr "type" "str")
15727 (set_attr "memory" "store")
15728 (set_attr "mode" "SI")])
15729
15730 (define_insn "strsethi_1"
15731 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15732 (match_operand:HI 2 "register_operand" "a"))
15733 (set (match_operand:SI 0 "register_operand" "=D")
15734 (plus:SI (match_dup 1)
15735 (const_int 2)))
15736 (use (reg:SI 19))]
15737 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15738 "stosw"
15739 [(set_attr "type" "str")
15740 (set_attr "memory" "store")
15741 (set_attr "mode" "HI")])
15742
15743 (define_insn "strsethi_rex_1"
15744 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15745 (match_operand:HI 2 "register_operand" "a"))
15746 (set (match_operand:DI 0 "register_operand" "=D")
15747 (plus:DI (match_dup 1)
15748 (const_int 2)))
15749 (use (reg:SI 19))]
15750 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15751 "stosw"
15752 [(set_attr "type" "str")
15753 (set_attr "memory" "store")
15754 (set_attr "mode" "HI")])
15755
15756 (define_insn "strsetqi_1"
15757 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15758 (match_operand:QI 2 "register_operand" "a"))
15759 (set (match_operand:SI 0 "register_operand" "=D")
15760 (plus:SI (match_dup 1)
15761 (const_int 1)))
15762 (use (reg:SI 19))]
15763 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15764 "stosb"
15765 [(set_attr "type" "str")
15766 (set_attr "memory" "store")
15767 (set_attr "mode" "QI")])
15768
15769 (define_insn "strsetqi_rex_1"
15770 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15771 (match_operand:QI 2 "register_operand" "a"))
15772 (set (match_operand:DI 0 "register_operand" "=D")
15773 (plus:DI (match_dup 1)
15774 (const_int 1)))
15775 (use (reg:SI 19))]
15776 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15777 "stosb"
15778 [(set_attr "type" "str")
15779 (set_attr "memory" "store")
15780 (set_attr "mode" "QI")])
15781
15782 (define_insn "rep_stosdi_rex64"
15783 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15784 (set (match_operand:DI 0 "register_operand" "=D")
15785 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15786 (const_int 3))
15787 (match_operand:DI 3 "register_operand" "0")))
15788 (set (mem:BLK (match_dup 3))
15789 (const_int 0))
15790 (use (match_operand:DI 2 "register_operand" "a"))
15791 (use (match_dup 4))
15792 (use (reg:SI 19))]
15793 "TARGET_64BIT"
15794 "{rep\;stosq|rep stosq}"
15795 [(set_attr "type" "str")
15796 (set_attr "prefix_rep" "1")
15797 (set_attr "memory" "store")
15798 (set_attr "mode" "DI")])
15799
15800 (define_insn "rep_stossi"
15801 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15802 (set (match_operand:SI 0 "register_operand" "=D")
15803 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15804 (const_int 2))
15805 (match_operand:SI 3 "register_operand" "0")))
15806 (set (mem:BLK (match_dup 3))
15807 (const_int 0))
15808 (use (match_operand:SI 2 "register_operand" "a"))
15809 (use (match_dup 4))
15810 (use (reg:SI 19))]
15811 "!TARGET_64BIT"
15812 "{rep\;stosl|rep stosd}"
15813 [(set_attr "type" "str")
15814 (set_attr "prefix_rep" "1")
15815 (set_attr "memory" "store")
15816 (set_attr "mode" "SI")])
15817
15818 (define_insn "rep_stossi_rex64"
15819 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15820 (set (match_operand:DI 0 "register_operand" "=D")
15821 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15822 (const_int 2))
15823 (match_operand:DI 3 "register_operand" "0")))
15824 (set (mem:BLK (match_dup 3))
15825 (const_int 0))
15826 (use (match_operand:SI 2 "register_operand" "a"))
15827 (use (match_dup 4))
15828 (use (reg:SI 19))]
15829 "TARGET_64BIT"
15830 "{rep\;stosl|rep stosd}"
15831 [(set_attr "type" "str")
15832 (set_attr "prefix_rep" "1")
15833 (set_attr "memory" "store")
15834 (set_attr "mode" "SI")])
15835
15836 (define_insn "rep_stosqi"
15837 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15838 (set (match_operand:SI 0 "register_operand" "=D")
15839 (plus:SI (match_operand:SI 3 "register_operand" "0")
15840 (match_operand:SI 4 "register_operand" "1")))
15841 (set (mem:BLK (match_dup 3))
15842 (const_int 0))
15843 (use (match_operand:QI 2 "register_operand" "a"))
15844 (use (match_dup 4))
15845 (use (reg:SI 19))]
15846 "!TARGET_64BIT"
15847 "{rep\;stosb|rep stosb}"
15848 [(set_attr "type" "str")
15849 (set_attr "prefix_rep" "1")
15850 (set_attr "memory" "store")
15851 (set_attr "mode" "QI")])
15852
15853 (define_insn "rep_stosqi_rex64"
15854 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15855 (set (match_operand:DI 0 "register_operand" "=D")
15856 (plus:DI (match_operand:DI 3 "register_operand" "0")
15857 (match_operand:DI 4 "register_operand" "1")))
15858 (set (mem:BLK (match_dup 3))
15859 (const_int 0))
15860 (use (match_operand:QI 2 "register_operand" "a"))
15861 (use (match_dup 4))
15862 (use (reg:DI 19))]
15863 "TARGET_64BIT"
15864 "{rep\;stosb|rep stosb}"
15865 [(set_attr "type" "str")
15866 (set_attr "prefix_rep" "1")
15867 (set_attr "memory" "store")
15868 (set_attr "mode" "QI")])
15869
15870 (define_expand "cmpstrsi"
15871 [(set (match_operand:SI 0 "register_operand" "")
15872 (compare:SI (match_operand:BLK 1 "general_operand" "")
15873 (match_operand:BLK 2 "general_operand" "")))
15874 (use (match_operand 3 "general_operand" ""))
15875 (use (match_operand 4 "immediate_operand" ""))]
15876 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15877 {
15878 rtx addr1, addr2, out, outlow, count, countreg, align;
15879
15880 /* Can't use this if the user has appropriated esi or edi. */
15881 if (global_regs[4] || global_regs[5])
15882 FAIL;
15883
15884 out = operands[0];
15885 if (GET_CODE (out) != REG)
15886 out = gen_reg_rtx (SImode);
15887
15888 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15889 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15890
15891 count = operands[3];
15892 countreg = ix86_zero_extend_to_Pmode (count);
15893
15894 /* %%% Iff we are testing strict equality, we can use known alignment
15895 to good advantage. This may be possible with combine, particularly
15896 once cc0 is dead. */
15897 align = operands[4];
15898
15899 emit_insn (gen_cld ());
15900 if (GET_CODE (count) == CONST_INT)
15901 {
15902 if (INTVAL (count) == 0)
15903 {
15904 emit_move_insn (operands[0], const0_rtx);
15905 DONE;
15906 }
15907 if (TARGET_64BIT)
15908 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
15909 addr1, addr2, countreg));
15910 else
15911 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15912 addr1, addr2, countreg));
15913 }
15914 else
15915 {
15916 if (TARGET_64BIT)
15917 {
15918 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15919 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
15920 addr1, addr2, countreg));
15921 }
15922 else
15923 {
15924 emit_insn (gen_cmpsi_1 (countreg, countreg));
15925 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15926 addr1, addr2, countreg));
15927 }
15928 }
15929
15930 outlow = gen_lowpart (QImode, out);
15931 emit_insn (gen_cmpintqi (outlow));
15932 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15933
15934 if (operands[0] != out)
15935 emit_move_insn (operands[0], out);
15936
15937 DONE;
15938 })
15939
15940 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15941
15942 (define_expand "cmpintqi"
15943 [(set (match_dup 1)
15944 (gtu:QI (reg:CC 17) (const_int 0)))
15945 (set (match_dup 2)
15946 (ltu:QI (reg:CC 17) (const_int 0)))
15947 (parallel [(set (match_operand:QI 0 "register_operand" "")
15948 (minus:QI (match_dup 1)
15949 (match_dup 2)))
15950 (clobber (reg:CC 17))])]
15951 ""
15952 "operands[1] = gen_reg_rtx (QImode);
15953 operands[2] = gen_reg_rtx (QImode);")
15954
15955 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15956 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15957
15958 (define_insn "cmpstrqi_nz_1"
15959 [(set (reg:CC 17)
15960 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15961 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15962 (use (match_operand:SI 6 "register_operand" "2"))
15963 (use (match_operand:SI 3 "immediate_operand" "i"))
15964 (use (reg:SI 19))
15965 (clobber (match_operand:SI 0 "register_operand" "=S"))
15966 (clobber (match_operand:SI 1 "register_operand" "=D"))
15967 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15968 "!TARGET_64BIT"
15969 "repz{\;| }cmpsb"
15970 [(set_attr "type" "str")
15971 (set_attr "mode" "QI")
15972 (set_attr "prefix_rep" "1")])
15973
15974 (define_insn "cmpstrqi_nz_rex_1"
15975 [(set (reg:CC 17)
15976 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15977 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15978 (use (match_operand:DI 6 "register_operand" "2"))
15979 (use (match_operand:SI 3 "immediate_operand" "i"))
15980 (use (reg:SI 19))
15981 (clobber (match_operand:DI 0 "register_operand" "=S"))
15982 (clobber (match_operand:DI 1 "register_operand" "=D"))
15983 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15984 "TARGET_64BIT"
15985 "repz{\;| }cmpsb"
15986 [(set_attr "type" "str")
15987 (set_attr "mode" "QI")
15988 (set_attr "prefix_rep" "1")])
15989
15990 ;; The same, but the count is not known to not be zero.
15991
15992 (define_insn "cmpstrqi_1"
15993 [(set (reg:CC 17)
15994 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15995 (const_int 0))
15996 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15997 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15998 (const_int 0)))
15999 (use (match_operand:SI 3 "immediate_operand" "i"))
16000 (use (reg:CC 17))
16001 (use (reg:SI 19))
16002 (clobber (match_operand:SI 0 "register_operand" "=S"))
16003 (clobber (match_operand:SI 1 "register_operand" "=D"))
16004 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16005 "!TARGET_64BIT"
16006 "repz{\;| }cmpsb"
16007 [(set_attr "type" "str")
16008 (set_attr "mode" "QI")
16009 (set_attr "prefix_rep" "1")])
16010
16011 (define_insn "cmpstrqi_rex_1"
16012 [(set (reg:CC 17)
16013 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16014 (const_int 0))
16015 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16016 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16017 (const_int 0)))
16018 (use (match_operand:SI 3 "immediate_operand" "i"))
16019 (use (reg:CC 17))
16020 (use (reg:SI 19))
16021 (clobber (match_operand:DI 0 "register_operand" "=S"))
16022 (clobber (match_operand:DI 1 "register_operand" "=D"))
16023 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16024 "TARGET_64BIT"
16025 "repz{\;| }cmpsb"
16026 [(set_attr "type" "str")
16027 (set_attr "mode" "QI")
16028 (set_attr "prefix_rep" "1")])
16029
16030 (define_expand "strlensi"
16031 [(set (match_operand:SI 0 "register_operand" "")
16032 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16033 (match_operand:QI 2 "immediate_operand" "")
16034 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16035 ""
16036 {
16037 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16038 DONE;
16039 else
16040 FAIL;
16041 })
16042
16043 (define_expand "strlendi"
16044 [(set (match_operand:DI 0 "register_operand" "")
16045 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16046 (match_operand:QI 2 "immediate_operand" "")
16047 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16048 ""
16049 {
16050 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16051 DONE;
16052 else
16053 FAIL;
16054 })
16055
16056 (define_insn "strlenqi_1"
16057 [(set (match_operand:SI 0 "register_operand" "=&c")
16058 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16059 (match_operand:QI 2 "register_operand" "a")
16060 (match_operand:SI 3 "immediate_operand" "i")
16061 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16062 (use (reg:SI 19))
16063 (clobber (match_operand:SI 1 "register_operand" "=D"))
16064 (clobber (reg:CC 17))]
16065 "!TARGET_64BIT"
16066 "repnz{\;| }scasb"
16067 [(set_attr "type" "str")
16068 (set_attr "mode" "QI")
16069 (set_attr "prefix_rep" "1")])
16070
16071 (define_insn "strlenqi_rex_1"
16072 [(set (match_operand:DI 0 "register_operand" "=&c")
16073 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16074 (match_operand:QI 2 "register_operand" "a")
16075 (match_operand:DI 3 "immediate_operand" "i")
16076 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16077 (use (reg:SI 19))
16078 (clobber (match_operand:DI 1 "register_operand" "=D"))
16079 (clobber (reg:CC 17))]
16080 "TARGET_64BIT"
16081 "repnz{\;| }scasb"
16082 [(set_attr "type" "str")
16083 (set_attr "mode" "QI")
16084 (set_attr "prefix_rep" "1")])
16085
16086 ;; Peephole optimizations to clean up after cmpstr*. This should be
16087 ;; handled in combine, but it is not currently up to the task.
16088 ;; When used for their truth value, the cmpstr* expanders generate
16089 ;; code like this:
16090 ;;
16091 ;; repz cmpsb
16092 ;; seta %al
16093 ;; setb %dl
16094 ;; cmpb %al, %dl
16095 ;; jcc label
16096 ;;
16097 ;; The intermediate three instructions are unnecessary.
16098
16099 ;; This one handles cmpstr*_nz_1...
16100 (define_peephole2
16101 [(parallel[
16102 (set (reg:CC 17)
16103 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16104 (mem:BLK (match_operand 5 "register_operand" ""))))
16105 (use (match_operand 6 "register_operand" ""))
16106 (use (match_operand:SI 3 "immediate_operand" ""))
16107 (use (reg:SI 19))
16108 (clobber (match_operand 0 "register_operand" ""))
16109 (clobber (match_operand 1 "register_operand" ""))
16110 (clobber (match_operand 2 "register_operand" ""))])
16111 (set (match_operand:QI 7 "register_operand" "")
16112 (gtu:QI (reg:CC 17) (const_int 0)))
16113 (set (match_operand:QI 8 "register_operand" "")
16114 (ltu:QI (reg:CC 17) (const_int 0)))
16115 (set (reg 17)
16116 (compare (match_dup 7) (match_dup 8)))
16117 ]
16118 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16119 [(parallel[
16120 (set (reg:CC 17)
16121 (compare:CC (mem:BLK (match_dup 4))
16122 (mem:BLK (match_dup 5))))
16123 (use (match_dup 6))
16124 (use (match_dup 3))
16125 (use (reg:SI 19))
16126 (clobber (match_dup 0))
16127 (clobber (match_dup 1))
16128 (clobber (match_dup 2))])]
16129 "")
16130
16131 ;; ...and this one handles cmpstr*_1.
16132 (define_peephole2
16133 [(parallel[
16134 (set (reg:CC 17)
16135 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16136 (const_int 0))
16137 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16138 (mem:BLK (match_operand 5 "register_operand" "")))
16139 (const_int 0)))
16140 (use (match_operand:SI 3 "immediate_operand" ""))
16141 (use (reg:CC 17))
16142 (use (reg:SI 19))
16143 (clobber (match_operand 0 "register_operand" ""))
16144 (clobber (match_operand 1 "register_operand" ""))
16145 (clobber (match_operand 2 "register_operand" ""))])
16146 (set (match_operand:QI 7 "register_operand" "")
16147 (gtu:QI (reg:CC 17) (const_int 0)))
16148 (set (match_operand:QI 8 "register_operand" "")
16149 (ltu:QI (reg:CC 17) (const_int 0)))
16150 (set (reg 17)
16151 (compare (match_dup 7) (match_dup 8)))
16152 ]
16153 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16154 [(parallel[
16155 (set (reg:CC 17)
16156 (if_then_else:CC (ne (match_dup 6)
16157 (const_int 0))
16158 (compare:CC (mem:BLK (match_dup 4))
16159 (mem:BLK (match_dup 5)))
16160 (const_int 0)))
16161 (use (match_dup 3))
16162 (use (reg:CC 17))
16163 (use (reg:SI 19))
16164 (clobber (match_dup 0))
16165 (clobber (match_dup 1))
16166 (clobber (match_dup 2))])]
16167 "")
16168
16169
16170 \f
16171 ;; Conditional move instructions.
16172
16173 (define_expand "movdicc"
16174 [(set (match_operand:DI 0 "register_operand" "")
16175 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16176 (match_operand:DI 2 "general_operand" "")
16177 (match_operand:DI 3 "general_operand" "")))]
16178 "TARGET_64BIT"
16179 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16180
16181 (define_insn "x86_movdicc_0_m1_rex64"
16182 [(set (match_operand:DI 0 "register_operand" "=r")
16183 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16184 (const_int -1)
16185 (const_int 0)))
16186 (clobber (reg:CC 17))]
16187 "TARGET_64BIT"
16188 "sbb{q}\t%0, %0"
16189 ; Since we don't have the proper number of operands for an alu insn,
16190 ; fill in all the blanks.
16191 [(set_attr "type" "alu")
16192 (set_attr "pent_pair" "pu")
16193 (set_attr "memory" "none")
16194 (set_attr "imm_disp" "false")
16195 (set_attr "mode" "DI")
16196 (set_attr "length_immediate" "0")])
16197
16198 (define_insn "movdicc_c_rex64"
16199 [(set (match_operand:DI 0 "register_operand" "=r,r")
16200 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16201 [(reg 17) (const_int 0)])
16202 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16203 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16204 "TARGET_64BIT && TARGET_CMOVE
16205 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16206 "@
16207 cmov%O2%C1\t{%2, %0|%0, %2}
16208 cmov%O2%c1\t{%3, %0|%0, %3}"
16209 [(set_attr "type" "icmov")
16210 (set_attr "mode" "DI")])
16211
16212 (define_expand "movsicc"
16213 [(set (match_operand:SI 0 "register_operand" "")
16214 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16215 (match_operand:SI 2 "general_operand" "")
16216 (match_operand:SI 3 "general_operand" "")))]
16217 ""
16218 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16219
16220 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16221 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16222 ;; So just document what we're doing explicitly.
16223
16224 (define_insn "x86_movsicc_0_m1"
16225 [(set (match_operand:SI 0 "register_operand" "=r")
16226 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16227 (const_int -1)
16228 (const_int 0)))
16229 (clobber (reg:CC 17))]
16230 ""
16231 "sbb{l}\t%0, %0"
16232 ; Since we don't have the proper number of operands for an alu insn,
16233 ; fill in all the blanks.
16234 [(set_attr "type" "alu")
16235 (set_attr "pent_pair" "pu")
16236 (set_attr "memory" "none")
16237 (set_attr "imm_disp" "false")
16238 (set_attr "mode" "SI")
16239 (set_attr "length_immediate" "0")])
16240
16241 (define_insn "*movsicc_noc"
16242 [(set (match_operand:SI 0 "register_operand" "=r,r")
16243 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16244 [(reg 17) (const_int 0)])
16245 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16246 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16247 "TARGET_CMOVE
16248 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16249 "@
16250 cmov%O2%C1\t{%2, %0|%0, %2}
16251 cmov%O2%c1\t{%3, %0|%0, %3}"
16252 [(set_attr "type" "icmov")
16253 (set_attr "mode" "SI")])
16254
16255 (define_expand "movhicc"
16256 [(set (match_operand:HI 0 "register_operand" "")
16257 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16258 (match_operand:HI 2 "general_operand" "")
16259 (match_operand:HI 3 "general_operand" "")))]
16260 "TARGET_HIMODE_MATH"
16261 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16262
16263 (define_insn "*movhicc_noc"
16264 [(set (match_operand:HI 0 "register_operand" "=r,r")
16265 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16266 [(reg 17) (const_int 0)])
16267 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16268 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16269 "TARGET_CMOVE
16270 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16271 "@
16272 cmov%O2%C1\t{%2, %0|%0, %2}
16273 cmov%O2%c1\t{%3, %0|%0, %3}"
16274 [(set_attr "type" "icmov")
16275 (set_attr "mode" "HI")])
16276
16277 (define_expand "movqicc"
16278 [(set (match_operand:QI 0 "register_operand" "")
16279 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16280 (match_operand:QI 2 "general_operand" "")
16281 (match_operand:QI 3 "general_operand" "")))]
16282 "TARGET_QIMODE_MATH"
16283 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16284
16285 (define_insn_and_split "*movqicc_noc"
16286 [(set (match_operand:QI 0 "register_operand" "=r,r")
16287 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16288 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16289 (match_operand:QI 2 "register_operand" "r,0")
16290 (match_operand:QI 3 "register_operand" "0,r")))]
16291 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16292 "#"
16293 "&& reload_completed"
16294 [(set (match_dup 0)
16295 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16296 (match_dup 2)
16297 (match_dup 3)))]
16298 "operands[0] = gen_lowpart (SImode, operands[0]);
16299 operands[2] = gen_lowpart (SImode, operands[2]);
16300 operands[3] = gen_lowpart (SImode, operands[3]);"
16301 [(set_attr "type" "icmov")
16302 (set_attr "mode" "SI")])
16303
16304 (define_expand "movsfcc"
16305 [(set (match_operand:SF 0 "register_operand" "")
16306 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16307 (match_operand:SF 2 "register_operand" "")
16308 (match_operand:SF 3 "register_operand" "")))]
16309 "TARGET_CMOVE"
16310 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16311
16312 (define_insn "*movsfcc_1"
16313 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16314 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16315 [(reg 17) (const_int 0)])
16316 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16317 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16318 "TARGET_CMOVE
16319 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16320 "@
16321 fcmov%F1\t{%2, %0|%0, %2}
16322 fcmov%f1\t{%3, %0|%0, %3}
16323 cmov%O2%C1\t{%2, %0|%0, %2}
16324 cmov%O2%c1\t{%3, %0|%0, %3}"
16325 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16326 (set_attr "mode" "SF,SF,SI,SI")])
16327
16328 (define_expand "movdfcc"
16329 [(set (match_operand:DF 0 "register_operand" "")
16330 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16331 (match_operand:DF 2 "register_operand" "")
16332 (match_operand:DF 3 "register_operand" "")))]
16333 "TARGET_CMOVE"
16334 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16335
16336 (define_insn "*movdfcc_1"
16337 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16338 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16339 [(reg 17) (const_int 0)])
16340 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16341 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16342 "!TARGET_64BIT && TARGET_CMOVE
16343 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16344 "@
16345 fcmov%F1\t{%2, %0|%0, %2}
16346 fcmov%f1\t{%3, %0|%0, %3}
16347 #
16348 #"
16349 [(set_attr "type" "fcmov,fcmov,multi,multi")
16350 (set_attr "mode" "DF")])
16351
16352 (define_insn "*movdfcc_1_rex64"
16353 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16354 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16355 [(reg 17) (const_int 0)])
16356 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16357 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16358 "TARGET_64BIT && TARGET_CMOVE
16359 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16360 "@
16361 fcmov%F1\t{%2, %0|%0, %2}
16362 fcmov%f1\t{%3, %0|%0, %3}
16363 cmov%O2%C1\t{%2, %0|%0, %2}
16364 cmov%O2%c1\t{%3, %0|%0, %3}"
16365 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16366 (set_attr "mode" "DF")])
16367
16368 (define_split
16369 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16370 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16371 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16372 (match_operand:DF 2 "nonimmediate_operand" "")
16373 (match_operand:DF 3 "nonimmediate_operand" "")))]
16374 "!TARGET_64BIT && reload_completed"
16375 [(set (match_dup 2)
16376 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16377 (match_dup 5)
16378 (match_dup 7)))
16379 (set (match_dup 3)
16380 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16381 (match_dup 6)
16382 (match_dup 8)))]
16383 "split_di (operands+2, 1, operands+5, operands+6);
16384 split_di (operands+3, 1, operands+7, operands+8);
16385 split_di (operands, 1, operands+2, operands+3);")
16386
16387 (define_expand "movxfcc"
16388 [(set (match_operand:XF 0 "register_operand" "")
16389 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16390 (match_operand:XF 2 "register_operand" "")
16391 (match_operand:XF 3 "register_operand" "")))]
16392 "TARGET_CMOVE"
16393 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16394
16395 (define_insn "*movxfcc_1"
16396 [(set (match_operand:XF 0 "register_operand" "=f,f")
16397 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16398 [(reg 17) (const_int 0)])
16399 (match_operand:XF 2 "register_operand" "f,0")
16400 (match_operand:XF 3 "register_operand" "0,f")))]
16401 "TARGET_CMOVE"
16402 "@
16403 fcmov%F1\t{%2, %0|%0, %2}
16404 fcmov%f1\t{%3, %0|%0, %3}"
16405 [(set_attr "type" "fcmov")
16406 (set_attr "mode" "XF")])
16407
16408 (define_expand "minsf3"
16409 [(parallel [
16410 (set (match_operand:SF 0 "register_operand" "")
16411 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16412 (match_operand:SF 2 "nonimmediate_operand" ""))
16413 (match_dup 1)
16414 (match_dup 2)))
16415 (clobber (reg:CC 17))])]
16416 "TARGET_SSE"
16417 "")
16418
16419 (define_insn "*minsf"
16420 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16421 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16422 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16423 (match_dup 1)
16424 (match_dup 2)))
16425 (clobber (reg:CC 17))]
16426 "TARGET_SSE && TARGET_IEEE_FP"
16427 "#")
16428
16429 (define_insn "*minsf_nonieee"
16430 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16431 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16432 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16433 (match_dup 1)
16434 (match_dup 2)))
16435 (clobber (reg:CC 17))]
16436 "TARGET_SSE && !TARGET_IEEE_FP
16437 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16438 "#")
16439
16440 (define_split
16441 [(set (match_operand:SF 0 "register_operand" "")
16442 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16443 (match_operand:SF 2 "nonimmediate_operand" ""))
16444 (match_operand:SF 3 "register_operand" "")
16445 (match_operand:SF 4 "nonimmediate_operand" "")))
16446 (clobber (reg:CC 17))]
16447 "SSE_REG_P (operands[0]) && reload_completed
16448 && ((operands_match_p (operands[1], operands[3])
16449 && operands_match_p (operands[2], operands[4]))
16450 || (operands_match_p (operands[1], operands[4])
16451 && operands_match_p (operands[2], operands[3])))"
16452 [(set (match_dup 0)
16453 (if_then_else:SF (lt (match_dup 1)
16454 (match_dup 2))
16455 (match_dup 1)
16456 (match_dup 2)))])
16457
16458 ;; Conditional addition patterns
16459 (define_expand "addqicc"
16460 [(match_operand:QI 0 "register_operand" "")
16461 (match_operand 1 "comparison_operator" "")
16462 (match_operand:QI 2 "register_operand" "")
16463 (match_operand:QI 3 "const_int_operand" "")]
16464 ""
16465 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16466
16467 (define_expand "addhicc"
16468 [(match_operand:HI 0 "register_operand" "")
16469 (match_operand 1 "comparison_operator" "")
16470 (match_operand:HI 2 "register_operand" "")
16471 (match_operand:HI 3 "const_int_operand" "")]
16472 ""
16473 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16474
16475 (define_expand "addsicc"
16476 [(match_operand:SI 0 "register_operand" "")
16477 (match_operand 1 "comparison_operator" "")
16478 (match_operand:SI 2 "register_operand" "")
16479 (match_operand:SI 3 "const_int_operand" "")]
16480 ""
16481 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16482
16483 (define_expand "adddicc"
16484 [(match_operand:DI 0 "register_operand" "")
16485 (match_operand 1 "comparison_operator" "")
16486 (match_operand:DI 2 "register_operand" "")
16487 (match_operand:DI 3 "const_int_operand" "")]
16488 "TARGET_64BIT"
16489 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16490
16491 ;; We can't represent the LT test directly. Do this by swapping the operands.
16492
16493 (define_split
16494 [(set (match_operand:SF 0 "fp_register_operand" "")
16495 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16496 (match_operand:SF 2 "register_operand" ""))
16497 (match_operand:SF 3 "register_operand" "")
16498 (match_operand:SF 4 "register_operand" "")))
16499 (clobber (reg:CC 17))]
16500 "reload_completed
16501 && ((operands_match_p (operands[1], operands[3])
16502 && operands_match_p (operands[2], operands[4]))
16503 || (operands_match_p (operands[1], operands[4])
16504 && operands_match_p (operands[2], operands[3])))"
16505 [(set (reg:CCFP 17)
16506 (compare:CCFP (match_dup 2)
16507 (match_dup 1)))
16508 (set (match_dup 0)
16509 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16510 (match_dup 1)
16511 (match_dup 2)))])
16512
16513 (define_insn "*minsf_sse"
16514 [(set (match_operand:SF 0 "register_operand" "=x")
16515 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16516 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16517 (match_dup 1)
16518 (match_dup 2)))]
16519 "TARGET_SSE && reload_completed"
16520 "minss\t{%2, %0|%0, %2}"
16521 [(set_attr "type" "sse")
16522 (set_attr "mode" "SF")])
16523
16524 (define_expand "mindf3"
16525 [(parallel [
16526 (set (match_operand:DF 0 "register_operand" "")
16527 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16528 (match_operand:DF 2 "nonimmediate_operand" ""))
16529 (match_dup 1)
16530 (match_dup 2)))
16531 (clobber (reg:CC 17))])]
16532 "TARGET_SSE2 && TARGET_SSE_MATH"
16533 "#")
16534
16535 (define_insn "*mindf"
16536 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16537 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16538 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16539 (match_dup 1)
16540 (match_dup 2)))
16541 (clobber (reg:CC 17))]
16542 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16543 "#")
16544
16545 (define_insn "*mindf_nonieee"
16546 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16547 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16548 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16549 (match_dup 1)
16550 (match_dup 2)))
16551 (clobber (reg:CC 17))]
16552 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16553 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16554 "#")
16555
16556 (define_split
16557 [(set (match_operand:DF 0 "register_operand" "")
16558 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16559 (match_operand:DF 2 "nonimmediate_operand" ""))
16560 (match_operand:DF 3 "register_operand" "")
16561 (match_operand:DF 4 "nonimmediate_operand" "")))
16562 (clobber (reg:CC 17))]
16563 "SSE_REG_P (operands[0]) && reload_completed
16564 && ((operands_match_p (operands[1], operands[3])
16565 && operands_match_p (operands[2], operands[4]))
16566 || (operands_match_p (operands[1], operands[4])
16567 && operands_match_p (operands[2], operands[3])))"
16568 [(set (match_dup 0)
16569 (if_then_else:DF (lt (match_dup 1)
16570 (match_dup 2))
16571 (match_dup 1)
16572 (match_dup 2)))])
16573
16574 ;; We can't represent the LT test directly. Do this by swapping the operands.
16575 (define_split
16576 [(set (match_operand:DF 0 "fp_register_operand" "")
16577 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16578 (match_operand:DF 2 "register_operand" ""))
16579 (match_operand:DF 3 "register_operand" "")
16580 (match_operand:DF 4 "register_operand" "")))
16581 (clobber (reg:CC 17))]
16582 "reload_completed
16583 && ((operands_match_p (operands[1], operands[3])
16584 && operands_match_p (operands[2], operands[4]))
16585 || (operands_match_p (operands[1], operands[4])
16586 && operands_match_p (operands[2], operands[3])))"
16587 [(set (reg:CCFP 17)
16588 (compare:CCFP (match_dup 2)
16589 (match_dup 1)))
16590 (set (match_dup 0)
16591 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16592 (match_dup 1)
16593 (match_dup 2)))])
16594
16595 (define_insn "*mindf_sse"
16596 [(set (match_operand:DF 0 "register_operand" "=Y")
16597 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16598 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16599 (match_dup 1)
16600 (match_dup 2)))]
16601 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16602 "minsd\t{%2, %0|%0, %2}"
16603 [(set_attr "type" "sse")
16604 (set_attr "mode" "DF")])
16605
16606 (define_expand "maxsf3"
16607 [(parallel [
16608 (set (match_operand:SF 0 "register_operand" "")
16609 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16610 (match_operand:SF 2 "nonimmediate_operand" ""))
16611 (match_dup 1)
16612 (match_dup 2)))
16613 (clobber (reg:CC 17))])]
16614 "TARGET_SSE"
16615 "#")
16616
16617 (define_insn "*maxsf"
16618 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16619 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16620 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16621 (match_dup 1)
16622 (match_dup 2)))
16623 (clobber (reg:CC 17))]
16624 "TARGET_SSE && TARGET_IEEE_FP"
16625 "#")
16626
16627 (define_insn "*maxsf_nonieee"
16628 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16629 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16630 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16631 (match_dup 1)
16632 (match_dup 2)))
16633 (clobber (reg:CC 17))]
16634 "TARGET_SSE && !TARGET_IEEE_FP
16635 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16636 "#")
16637
16638 (define_split
16639 [(set (match_operand:SF 0 "register_operand" "")
16640 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16641 (match_operand:SF 2 "nonimmediate_operand" ""))
16642 (match_operand:SF 3 "register_operand" "")
16643 (match_operand:SF 4 "nonimmediate_operand" "")))
16644 (clobber (reg:CC 17))]
16645 "SSE_REG_P (operands[0]) && reload_completed
16646 && ((operands_match_p (operands[1], operands[3])
16647 && operands_match_p (operands[2], operands[4]))
16648 || (operands_match_p (operands[1], operands[4])
16649 && operands_match_p (operands[2], operands[3])))"
16650 [(set (match_dup 0)
16651 (if_then_else:SF (gt (match_dup 1)
16652 (match_dup 2))
16653 (match_dup 1)
16654 (match_dup 2)))])
16655
16656 (define_split
16657 [(set (match_operand:SF 0 "fp_register_operand" "")
16658 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16659 (match_operand:SF 2 "register_operand" ""))
16660 (match_operand:SF 3 "register_operand" "")
16661 (match_operand:SF 4 "register_operand" "")))
16662 (clobber (reg:CC 17))]
16663 "reload_completed
16664 && ((operands_match_p (operands[1], operands[3])
16665 && operands_match_p (operands[2], operands[4]))
16666 || (operands_match_p (operands[1], operands[4])
16667 && operands_match_p (operands[2], operands[3])))"
16668 [(set (reg:CCFP 17)
16669 (compare:CCFP (match_dup 1)
16670 (match_dup 2)))
16671 (set (match_dup 0)
16672 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16673 (match_dup 1)
16674 (match_dup 2)))])
16675
16676 (define_insn "*maxsf_sse"
16677 [(set (match_operand:SF 0 "register_operand" "=x")
16678 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16679 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16680 (match_dup 1)
16681 (match_dup 2)))]
16682 "TARGET_SSE && reload_completed"
16683 "maxss\t{%2, %0|%0, %2}"
16684 [(set_attr "type" "sse")
16685 (set_attr "mode" "SF")])
16686
16687 (define_expand "maxdf3"
16688 [(parallel [
16689 (set (match_operand:DF 0 "register_operand" "")
16690 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16691 (match_operand:DF 2 "nonimmediate_operand" ""))
16692 (match_dup 1)
16693 (match_dup 2)))
16694 (clobber (reg:CC 17))])]
16695 "TARGET_SSE2 && TARGET_SSE_MATH"
16696 "#")
16697
16698 (define_insn "*maxdf"
16699 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16700 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16701 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16702 (match_dup 1)
16703 (match_dup 2)))
16704 (clobber (reg:CC 17))]
16705 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16706 "#")
16707
16708 (define_insn "*maxdf_nonieee"
16709 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16710 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16711 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16712 (match_dup 1)
16713 (match_dup 2)))
16714 (clobber (reg:CC 17))]
16715 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16716 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16717 "#")
16718
16719 (define_split
16720 [(set (match_operand:DF 0 "register_operand" "")
16721 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16722 (match_operand:DF 2 "nonimmediate_operand" ""))
16723 (match_operand:DF 3 "register_operand" "")
16724 (match_operand:DF 4 "nonimmediate_operand" "")))
16725 (clobber (reg:CC 17))]
16726 "SSE_REG_P (operands[0]) && reload_completed
16727 && ((operands_match_p (operands[1], operands[3])
16728 && operands_match_p (operands[2], operands[4]))
16729 || (operands_match_p (operands[1], operands[4])
16730 && operands_match_p (operands[2], operands[3])))"
16731 [(set (match_dup 0)
16732 (if_then_else:DF (gt (match_dup 1)
16733 (match_dup 2))
16734 (match_dup 1)
16735 (match_dup 2)))])
16736
16737 (define_split
16738 [(set (match_operand:DF 0 "fp_register_operand" "")
16739 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16740 (match_operand:DF 2 "register_operand" ""))
16741 (match_operand:DF 3 "register_operand" "")
16742 (match_operand:DF 4 "register_operand" "")))
16743 (clobber (reg:CC 17))]
16744 "reload_completed
16745 && ((operands_match_p (operands[1], operands[3])
16746 && operands_match_p (operands[2], operands[4]))
16747 || (operands_match_p (operands[1], operands[4])
16748 && operands_match_p (operands[2], operands[3])))"
16749 [(set (reg:CCFP 17)
16750 (compare:CCFP (match_dup 1)
16751 (match_dup 2)))
16752 (set (match_dup 0)
16753 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16754 (match_dup 1)
16755 (match_dup 2)))])
16756
16757 (define_insn "*maxdf_sse"
16758 [(set (match_operand:DF 0 "register_operand" "=Y")
16759 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16760 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16761 (match_dup 1)
16762 (match_dup 2)))]
16763 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16764 "maxsd\t{%2, %0|%0, %2}"
16765 [(set_attr "type" "sse")
16766 (set_attr "mode" "DF")])
16767 \f
16768 ;; Misc patterns (?)
16769
16770 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16771 ;; Otherwise there will be nothing to keep
16772 ;;
16773 ;; [(set (reg ebp) (reg esp))]
16774 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16775 ;; (clobber (eflags)]
16776 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16777 ;;
16778 ;; in proper program order.
16779 (define_insn "pro_epilogue_adjust_stack_1"
16780 [(set (match_operand:SI 0 "register_operand" "=r,r")
16781 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16782 (match_operand:SI 2 "immediate_operand" "i,i")))
16783 (clobber (reg:CC 17))
16784 (clobber (mem:BLK (scratch)))]
16785 "!TARGET_64BIT"
16786 {
16787 switch (get_attr_type (insn))
16788 {
16789 case TYPE_IMOV:
16790 return "mov{l}\t{%1, %0|%0, %1}";
16791
16792 case TYPE_ALU:
16793 if (GET_CODE (operands[2]) == CONST_INT
16794 && (INTVAL (operands[2]) == 128
16795 || (INTVAL (operands[2]) < 0
16796 && INTVAL (operands[2]) != -128)))
16797 {
16798 operands[2] = GEN_INT (-INTVAL (operands[2]));
16799 return "sub{l}\t{%2, %0|%0, %2}";
16800 }
16801 return "add{l}\t{%2, %0|%0, %2}";
16802
16803 case TYPE_LEA:
16804 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16805 return "lea{l}\t{%a2, %0|%0, %a2}";
16806
16807 default:
16808 abort ();
16809 }
16810 }
16811 [(set (attr "type")
16812 (cond [(eq_attr "alternative" "0")
16813 (const_string "alu")
16814 (match_operand:SI 2 "const0_operand" "")
16815 (const_string "imov")
16816 ]
16817 (const_string "lea")))
16818 (set_attr "mode" "SI")])
16819
16820 (define_insn "pro_epilogue_adjust_stack_rex64"
16821 [(set (match_operand:DI 0 "register_operand" "=r,r")
16822 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16823 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16824 (clobber (reg:CC 17))
16825 (clobber (mem:BLK (scratch)))]
16826 "TARGET_64BIT"
16827 {
16828 switch (get_attr_type (insn))
16829 {
16830 case TYPE_IMOV:
16831 return "mov{q}\t{%1, %0|%0, %1}";
16832
16833 case TYPE_ALU:
16834 if (GET_CODE (operands[2]) == CONST_INT
16835 /* Avoid overflows. */
16836 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16837 && (INTVAL (operands[2]) == 128
16838 || (INTVAL (operands[2]) < 0
16839 && INTVAL (operands[2]) != -128)))
16840 {
16841 operands[2] = GEN_INT (-INTVAL (operands[2]));
16842 return "sub{q}\t{%2, %0|%0, %2}";
16843 }
16844 return "add{q}\t{%2, %0|%0, %2}";
16845
16846 case TYPE_LEA:
16847 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16848 return "lea{q}\t{%a2, %0|%0, %a2}";
16849
16850 default:
16851 abort ();
16852 }
16853 }
16854 [(set (attr "type")
16855 (cond [(eq_attr "alternative" "0")
16856 (const_string "alu")
16857 (match_operand:DI 2 "const0_operand" "")
16858 (const_string "imov")
16859 ]
16860 (const_string "lea")))
16861 (set_attr "mode" "DI")])
16862
16863 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16864 [(set (match_operand:DI 0 "register_operand" "=r,r")
16865 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16866 (match_operand:DI 3 "immediate_operand" "i,i")))
16867 (use (match_operand:DI 2 "register_operand" "r,r"))
16868 (clobber (reg:CC 17))
16869 (clobber (mem:BLK (scratch)))]
16870 "TARGET_64BIT"
16871 {
16872 switch (get_attr_type (insn))
16873 {
16874 case TYPE_ALU:
16875 return "add{q}\t{%2, %0|%0, %2}";
16876
16877 case TYPE_LEA:
16878 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16879 return "lea{q}\t{%a2, %0|%0, %a2}";
16880
16881 default:
16882 abort ();
16883 }
16884 }
16885 [(set_attr "type" "alu,lea")
16886 (set_attr "mode" "DI")])
16887
16888 ;; Placeholder for the conditional moves. This one is split either to SSE
16889 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16890 ;; fact is that compares supported by the cmp??ss instructions are exactly
16891 ;; swapped of those supported by cmove sequence.
16892 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16893 ;; supported by i387 comparisons and we do need to emit two conditional moves
16894 ;; in tandem.
16895
16896 (define_insn "sse_movsfcc"
16897 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
16898 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16899 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
16900 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
16901 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
16902 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
16903 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16904 (clobber (reg:CC 17))]
16905 "TARGET_SSE
16906 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16907 /* Avoid combine from being smart and converting min/max
16908 instruction patterns into conditional moves. */
16909 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16910 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16911 || !rtx_equal_p (operands[4], operands[2])
16912 || !rtx_equal_p (operands[5], operands[3]))
16913 && (!TARGET_IEEE_FP
16914 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16915 "#")
16916
16917 (define_insn "sse_movsfcc_eq"
16918 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16919 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16920 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16921 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16922 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16923 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16924 (clobber (reg:CC 17))]
16925 "TARGET_SSE
16926 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16927 "#")
16928
16929 (define_insn "sse_movdfcc"
16930 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
16931 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16932 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
16933 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
16934 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
16935 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
16936 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16937 (clobber (reg:CC 17))]
16938 "TARGET_SSE2
16939 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16940 /* Avoid combine from being smart and converting min/max
16941 instruction patterns into conditional moves. */
16942 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16943 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16944 || !rtx_equal_p (operands[4], operands[2])
16945 || !rtx_equal_p (operands[5], operands[3]))
16946 && (!TARGET_IEEE_FP
16947 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16948 "#")
16949
16950 (define_insn "sse_movdfcc_eq"
16951 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16952 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16953 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16954 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16955 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16956 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16957 (clobber (reg:CC 17))]
16958 "TARGET_SSE
16959 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16960 "#")
16961
16962 ;; For non-sse moves just expand the usual cmove sequence.
16963 (define_split
16964 [(set (match_operand 0 "register_operand" "")
16965 (if_then_else (match_operator 1 "comparison_operator"
16966 [(match_operand 4 "nonimmediate_operand" "")
16967 (match_operand 5 "register_operand" "")])
16968 (match_operand 2 "nonimmediate_operand" "")
16969 (match_operand 3 "nonimmediate_operand" "")))
16970 (clobber (match_operand 6 "" ""))
16971 (clobber (reg:CC 17))]
16972 "!SSE_REG_P (operands[0]) && reload_completed
16973 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
16974 [(const_int 0)]
16975 {
16976 ix86_compare_op0 = operands[5];
16977 ix86_compare_op1 = operands[4];
16978 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
16979 VOIDmode, operands[5], operands[4]);
16980 ix86_expand_fp_movcc (operands);
16981 DONE;
16982 })
16983
16984 ;; Split SSE based conditional move into sequence:
16985 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
16986 ;; and op2, op0 - zero op2 if comparison was false
16987 ;; nand op0, op3 - load op3 to op0 if comparison was false
16988 ;; or op2, op0 - get the nonzero one into the result.
16989 (define_split
16990 [(set (match_operand 0 "register_operand" "")
16991 (if_then_else (match_operator 1 "sse_comparison_operator"
16992 [(match_operand 4 "register_operand" "")
16993 (match_operand 5 "nonimmediate_operand" "")])
16994 (match_operand 2 "register_operand" "")
16995 (match_operand 3 "register_operand" "")))
16996 (clobber (match_operand 6 "" ""))
16997 (clobber (reg:CC 17))]
16998 "SSE_REG_P (operands[0]) && reload_completed"
16999 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17000 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17001 (subreg:TI (match_dup 4) 0)))
17002 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17003 (subreg:TI (match_dup 3) 0)))
17004 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17005 (subreg:TI (match_dup 7) 0)))]
17006 {
17007 if (GET_MODE (operands[2]) == DFmode
17008 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17009 {
17010 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17011 emit_insn (gen_sse2_unpcklpd (op, op, op));
17012 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17013 emit_insn (gen_sse2_unpcklpd (op, op, op));
17014 }
17015
17016 /* If op2 == op3, op3 would be clobbered before it is used. */
17017 if (operands_match_p (operands[2], operands[3]))
17018 {
17019 emit_move_insn (operands[0], operands[2]);
17020 DONE;
17021 }
17022
17023 PUT_MODE (operands[1], GET_MODE (operands[0]));
17024 if (operands_match_p (operands[0], operands[4]))
17025 operands[6] = operands[4], operands[7] = operands[2];
17026 else
17027 operands[6] = operands[2], operands[7] = operands[4];
17028 })
17029
17030 ;; Special case of conditional move we can handle effectively.
17031 ;; Do not brother with the integer/floating point case, since these are
17032 ;; bot considerably slower, unlike in the generic case.
17033 (define_insn "*sse_movsfcc_const0_1"
17034 [(set (match_operand:SF 0 "register_operand" "=&x")
17035 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17036 [(match_operand:SF 4 "register_operand" "0")
17037 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17038 (match_operand:SF 2 "register_operand" "x")
17039 (match_operand:SF 3 "const0_operand" "X")))]
17040 "TARGET_SSE"
17041 "#")
17042
17043 (define_insn "*sse_movsfcc_const0_2"
17044 [(set (match_operand:SF 0 "register_operand" "=&x")
17045 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17046 [(match_operand:SF 4 "register_operand" "0")
17047 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17048 (match_operand:SF 2 "const0_operand" "X")
17049 (match_operand:SF 3 "register_operand" "x")))]
17050 "TARGET_SSE"
17051 "#")
17052
17053 (define_insn "*sse_movsfcc_const0_3"
17054 [(set (match_operand:SF 0 "register_operand" "=&x")
17055 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17056 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17057 (match_operand:SF 5 "register_operand" "0")])
17058 (match_operand:SF 2 "register_operand" "x")
17059 (match_operand:SF 3 "const0_operand" "X")))]
17060 "TARGET_SSE"
17061 "#")
17062
17063 (define_insn "*sse_movsfcc_const0_4"
17064 [(set (match_operand:SF 0 "register_operand" "=&x")
17065 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17066 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17067 (match_operand:SF 5 "register_operand" "0")])
17068 (match_operand:SF 2 "const0_operand" "X")
17069 (match_operand:SF 3 "register_operand" "x")))]
17070 "TARGET_SSE"
17071 "#")
17072
17073 (define_insn "*sse_movdfcc_const0_1"
17074 [(set (match_operand:DF 0 "register_operand" "=&Y")
17075 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17076 [(match_operand:DF 4 "register_operand" "0")
17077 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17078 (match_operand:DF 2 "register_operand" "Y")
17079 (match_operand:DF 3 "const0_operand" "X")))]
17080 "TARGET_SSE2"
17081 "#")
17082
17083 (define_insn "*sse_movdfcc_const0_2"
17084 [(set (match_operand:DF 0 "register_operand" "=&Y")
17085 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17086 [(match_operand:DF 4 "register_operand" "0")
17087 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17088 (match_operand:DF 2 "const0_operand" "X")
17089 (match_operand:DF 3 "register_operand" "Y")))]
17090 "TARGET_SSE2"
17091 "#")
17092
17093 (define_insn "*sse_movdfcc_const0_3"
17094 [(set (match_operand:DF 0 "register_operand" "=&Y")
17095 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17096 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17097 (match_operand:DF 5 "register_operand" "0")])
17098 (match_operand:DF 2 "register_operand" "Y")
17099 (match_operand:DF 3 "const0_operand" "X")))]
17100 "TARGET_SSE2"
17101 "#")
17102
17103 (define_insn "*sse_movdfcc_const0_4"
17104 [(set (match_operand:DF 0 "register_operand" "=&Y")
17105 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17106 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17107 (match_operand:DF 5 "register_operand" "0")])
17108 (match_operand:DF 2 "const0_operand" "X")
17109 (match_operand:DF 3 "register_operand" "Y")))]
17110 "TARGET_SSE2"
17111 "#")
17112
17113 (define_split
17114 [(set (match_operand 0 "register_operand" "")
17115 (if_then_else (match_operator 1 "comparison_operator"
17116 [(match_operand 4 "nonimmediate_operand" "")
17117 (match_operand 5 "nonimmediate_operand" "")])
17118 (match_operand 2 "nonmemory_operand" "")
17119 (match_operand 3 "nonmemory_operand" "")))]
17120 "SSE_REG_P (operands[0]) && reload_completed
17121 && (const0_operand (operands[2], GET_MODE (operands[0]))
17122 || const0_operand (operands[3], GET_MODE (operands[0])))"
17123 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17124 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17125 (match_dup 7)))]
17126 {
17127 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17128 && GET_MODE (operands[2]) == DFmode)
17129 {
17130 if (REG_P (operands[2]))
17131 {
17132 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17133 emit_insn (gen_sse2_unpcklpd (op, op, op));
17134 }
17135 if (REG_P (operands[3]))
17136 {
17137 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17138 emit_insn (gen_sse2_unpcklpd (op, op, op));
17139 }
17140 }
17141 PUT_MODE (operands[1], GET_MODE (operands[0]));
17142 if (!sse_comparison_operator (operands[1], VOIDmode)
17143 || !rtx_equal_p (operands[0], operands[4]))
17144 {
17145 rtx tmp = operands[5];
17146 operands[5] = operands[4];
17147 operands[4] = tmp;
17148 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17149 }
17150 if (!rtx_equal_p (operands[0], operands[4]))
17151 abort ();
17152 if (const0_operand (operands[2], GET_MODE (operands[0])))
17153 {
17154 operands[7] = operands[3];
17155 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17156 0));
17157 }
17158 else
17159 {
17160 operands[7] = operands[2];
17161 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17162 }
17163 operands[7] = simplify_gen_subreg (TImode, operands[7],
17164 GET_MODE (operands[7]), 0);
17165 })
17166
17167 (define_expand "allocate_stack_worker"
17168 [(match_operand:SI 0 "register_operand" "")]
17169 "TARGET_STACK_PROBE"
17170 {
17171 if (TARGET_64BIT)
17172 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17173 else
17174 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17175 DONE;
17176 })
17177
17178 (define_insn "allocate_stack_worker_1"
17179 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17180 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17181 (clobber (match_dup 0))
17182 (clobber (reg:CC 17))]
17183 "!TARGET_64BIT && TARGET_STACK_PROBE"
17184 "call\t__alloca"
17185 [(set_attr "type" "multi")
17186 (set_attr "length" "5")])
17187
17188 (define_insn "allocate_stack_worker_rex64"
17189 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17190 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17191 (clobber (match_dup 0))
17192 (clobber (reg:CC 17))]
17193 "TARGET_64BIT && TARGET_STACK_PROBE"
17194 "call\t__alloca"
17195 [(set_attr "type" "multi")
17196 (set_attr "length" "5")])
17197
17198 (define_expand "allocate_stack"
17199 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17200 (minus:SI (reg:SI 7)
17201 (match_operand:SI 1 "general_operand" "")))
17202 (clobber (reg:CC 17))])
17203 (parallel [(set (reg:SI 7)
17204 (minus:SI (reg:SI 7) (match_dup 1)))
17205 (clobber (reg:CC 17))])]
17206 "TARGET_STACK_PROBE"
17207 {
17208 #ifdef CHECK_STACK_LIMIT
17209 if (GET_CODE (operands[1]) == CONST_INT
17210 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17211 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17212 operands[1]));
17213 else
17214 #endif
17215 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17216 operands[1])));
17217
17218 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17219 DONE;
17220 })
17221
17222 (define_expand "builtin_setjmp_receiver"
17223 [(label_ref (match_operand 0 "" ""))]
17224 "!TARGET_64BIT && flag_pic"
17225 {
17226 emit_insn (gen_set_got (pic_offset_table_rtx));
17227 DONE;
17228 })
17229 \f
17230 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17231
17232 (define_split
17233 [(set (match_operand 0 "register_operand" "")
17234 (match_operator 3 "promotable_binary_operator"
17235 [(match_operand 1 "register_operand" "")
17236 (match_operand 2 "aligned_operand" "")]))
17237 (clobber (reg:CC 17))]
17238 "! TARGET_PARTIAL_REG_STALL && reload_completed
17239 && ((GET_MODE (operands[0]) == HImode
17240 && ((!optimize_size && !TARGET_FAST_PREFIX)
17241 || GET_CODE (operands[2]) != CONST_INT
17242 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17243 || (GET_MODE (operands[0]) == QImode
17244 && (TARGET_PROMOTE_QImode || optimize_size)))"
17245 [(parallel [(set (match_dup 0)
17246 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17247 (clobber (reg:CC 17))])]
17248 "operands[0] = gen_lowpart (SImode, operands[0]);
17249 operands[1] = gen_lowpart (SImode, operands[1]);
17250 if (GET_CODE (operands[3]) != ASHIFT)
17251 operands[2] = gen_lowpart (SImode, operands[2]);
17252 PUT_MODE (operands[3], SImode);")
17253
17254 ; Promote the QImode tests, as i386 has encoding of the AND
17255 ; instruction with 32-bit sign-extended immediate and thus the
17256 ; instruction size is unchanged, except in the %eax case for
17257 ; which it is increased by one byte, hence the ! optimize_size.
17258 (define_split
17259 [(set (reg 17)
17260 (compare (and (match_operand 1 "aligned_operand" "")
17261 (match_operand 2 "const_int_operand" ""))
17262 (const_int 0)))
17263 (set (match_operand 0 "register_operand" "")
17264 (and (match_dup 1) (match_dup 2)))]
17265 "! TARGET_PARTIAL_REG_STALL && reload_completed
17266 /* Ensure that the operand will remain sign-extended immediate. */
17267 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17268 && ! optimize_size
17269 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17270 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17271 [(parallel [(set (reg:CCNO 17)
17272 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17273 (const_int 0)))
17274 (set (match_dup 0)
17275 (and:SI (match_dup 1) (match_dup 2)))])]
17276 "operands[2]
17277 = gen_int_mode (INTVAL (operands[2])
17278 & GET_MODE_MASK (GET_MODE (operands[0])),
17279 SImode);
17280 operands[0] = gen_lowpart (SImode, operands[0]);
17281 operands[1] = gen_lowpart (SImode, operands[1]);")
17282
17283 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17284 ; the TEST instruction with 32-bit sign-extended immediate and thus
17285 ; the instruction size would at least double, which is not what we
17286 ; want even with ! optimize_size.
17287 (define_split
17288 [(set (reg 17)
17289 (compare (and (match_operand:HI 0 "aligned_operand" "")
17290 (match_operand:HI 1 "const_int_operand" ""))
17291 (const_int 0)))]
17292 "! TARGET_PARTIAL_REG_STALL && reload_completed
17293 /* Ensure that the operand will remain sign-extended immediate. */
17294 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17295 && ! TARGET_FAST_PREFIX
17296 && ! optimize_size"
17297 [(set (reg:CCNO 17)
17298 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17299 (const_int 0)))]
17300 "operands[1]
17301 = gen_int_mode (INTVAL (operands[1])
17302 & GET_MODE_MASK (GET_MODE (operands[0])),
17303 SImode);
17304 operands[0] = gen_lowpart (SImode, operands[0]);")
17305
17306 (define_split
17307 [(set (match_operand 0 "register_operand" "")
17308 (neg (match_operand 1 "register_operand" "")))
17309 (clobber (reg:CC 17))]
17310 "! TARGET_PARTIAL_REG_STALL && reload_completed
17311 && (GET_MODE (operands[0]) == HImode
17312 || (GET_MODE (operands[0]) == QImode
17313 && (TARGET_PROMOTE_QImode || optimize_size)))"
17314 [(parallel [(set (match_dup 0)
17315 (neg:SI (match_dup 1)))
17316 (clobber (reg:CC 17))])]
17317 "operands[0] = gen_lowpart (SImode, operands[0]);
17318 operands[1] = gen_lowpart (SImode, operands[1]);")
17319
17320 (define_split
17321 [(set (match_operand 0 "register_operand" "")
17322 (not (match_operand 1 "register_operand" "")))]
17323 "! TARGET_PARTIAL_REG_STALL && reload_completed
17324 && (GET_MODE (operands[0]) == HImode
17325 || (GET_MODE (operands[0]) == QImode
17326 && (TARGET_PROMOTE_QImode || optimize_size)))"
17327 [(set (match_dup 0)
17328 (not:SI (match_dup 1)))]
17329 "operands[0] = gen_lowpart (SImode, operands[0]);
17330 operands[1] = gen_lowpart (SImode, operands[1]);")
17331
17332 (define_split
17333 [(set (match_operand 0 "register_operand" "")
17334 (if_then_else (match_operator 1 "comparison_operator"
17335 [(reg 17) (const_int 0)])
17336 (match_operand 2 "register_operand" "")
17337 (match_operand 3 "register_operand" "")))]
17338 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17339 && (GET_MODE (operands[0]) == HImode
17340 || (GET_MODE (operands[0]) == QImode
17341 && (TARGET_PROMOTE_QImode || optimize_size)))"
17342 [(set (match_dup 0)
17343 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17344 "operands[0] = gen_lowpart (SImode, operands[0]);
17345 operands[2] = gen_lowpart (SImode, operands[2]);
17346 operands[3] = gen_lowpart (SImode, operands[3]);")
17347
17348 \f
17349 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17350 ;; transform a complex memory operation into two memory to register operations.
17351
17352 ;; Don't push memory operands
17353 (define_peephole2
17354 [(set (match_operand:SI 0 "push_operand" "")
17355 (match_operand:SI 1 "memory_operand" ""))
17356 (match_scratch:SI 2 "r")]
17357 "! optimize_size && ! TARGET_PUSH_MEMORY"
17358 [(set (match_dup 2) (match_dup 1))
17359 (set (match_dup 0) (match_dup 2))]
17360 "")
17361
17362 (define_peephole2
17363 [(set (match_operand:DI 0 "push_operand" "")
17364 (match_operand:DI 1 "memory_operand" ""))
17365 (match_scratch:DI 2 "r")]
17366 "! optimize_size && ! TARGET_PUSH_MEMORY"
17367 [(set (match_dup 2) (match_dup 1))
17368 (set (match_dup 0) (match_dup 2))]
17369 "")
17370
17371 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17372 ;; SImode pushes.
17373 (define_peephole2
17374 [(set (match_operand:SF 0 "push_operand" "")
17375 (match_operand:SF 1 "memory_operand" ""))
17376 (match_scratch:SF 2 "r")]
17377 "! optimize_size && ! TARGET_PUSH_MEMORY"
17378 [(set (match_dup 2) (match_dup 1))
17379 (set (match_dup 0) (match_dup 2))]
17380 "")
17381
17382 (define_peephole2
17383 [(set (match_operand:HI 0 "push_operand" "")
17384 (match_operand:HI 1 "memory_operand" ""))
17385 (match_scratch:HI 2 "r")]
17386 "! optimize_size && ! TARGET_PUSH_MEMORY"
17387 [(set (match_dup 2) (match_dup 1))
17388 (set (match_dup 0) (match_dup 2))]
17389 "")
17390
17391 (define_peephole2
17392 [(set (match_operand:QI 0 "push_operand" "")
17393 (match_operand:QI 1 "memory_operand" ""))
17394 (match_scratch:QI 2 "q")]
17395 "! optimize_size && ! TARGET_PUSH_MEMORY"
17396 [(set (match_dup 2) (match_dup 1))
17397 (set (match_dup 0) (match_dup 2))]
17398 "")
17399
17400 ;; Don't move an immediate directly to memory when the instruction
17401 ;; gets too big.
17402 (define_peephole2
17403 [(match_scratch:SI 1 "r")
17404 (set (match_operand:SI 0 "memory_operand" "")
17405 (const_int 0))]
17406 "! optimize_size
17407 && ! TARGET_USE_MOV0
17408 && TARGET_SPLIT_LONG_MOVES
17409 && get_attr_length (insn) >= ix86_cost->large_insn
17410 && peep2_regno_dead_p (0, FLAGS_REG)"
17411 [(parallel [(set (match_dup 1) (const_int 0))
17412 (clobber (reg:CC 17))])
17413 (set (match_dup 0) (match_dup 1))]
17414 "")
17415
17416 (define_peephole2
17417 [(match_scratch:HI 1 "r")
17418 (set (match_operand:HI 0 "memory_operand" "")
17419 (const_int 0))]
17420 "! optimize_size
17421 && ! TARGET_USE_MOV0
17422 && TARGET_SPLIT_LONG_MOVES
17423 && get_attr_length (insn) >= ix86_cost->large_insn
17424 && peep2_regno_dead_p (0, FLAGS_REG)"
17425 [(parallel [(set (match_dup 2) (const_int 0))
17426 (clobber (reg:CC 17))])
17427 (set (match_dup 0) (match_dup 1))]
17428 "operands[2] = gen_lowpart (SImode, operands[1]);")
17429
17430 (define_peephole2
17431 [(match_scratch:QI 1 "q")
17432 (set (match_operand:QI 0 "memory_operand" "")
17433 (const_int 0))]
17434 "! optimize_size
17435 && ! TARGET_USE_MOV0
17436 && TARGET_SPLIT_LONG_MOVES
17437 && get_attr_length (insn) >= ix86_cost->large_insn
17438 && peep2_regno_dead_p (0, FLAGS_REG)"
17439 [(parallel [(set (match_dup 2) (const_int 0))
17440 (clobber (reg:CC 17))])
17441 (set (match_dup 0) (match_dup 1))]
17442 "operands[2] = gen_lowpart (SImode, operands[1]);")
17443
17444 (define_peephole2
17445 [(match_scratch:SI 2 "r")
17446 (set (match_operand:SI 0 "memory_operand" "")
17447 (match_operand:SI 1 "immediate_operand" ""))]
17448 "! optimize_size
17449 && get_attr_length (insn) >= ix86_cost->large_insn
17450 && TARGET_SPLIT_LONG_MOVES"
17451 [(set (match_dup 2) (match_dup 1))
17452 (set (match_dup 0) (match_dup 2))]
17453 "")
17454
17455 (define_peephole2
17456 [(match_scratch:HI 2 "r")
17457 (set (match_operand:HI 0 "memory_operand" "")
17458 (match_operand:HI 1 "immediate_operand" ""))]
17459 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17460 && TARGET_SPLIT_LONG_MOVES"
17461 [(set (match_dup 2) (match_dup 1))
17462 (set (match_dup 0) (match_dup 2))]
17463 "")
17464
17465 (define_peephole2
17466 [(match_scratch:QI 2 "q")
17467 (set (match_operand:QI 0 "memory_operand" "")
17468 (match_operand:QI 1 "immediate_operand" ""))]
17469 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17470 && TARGET_SPLIT_LONG_MOVES"
17471 [(set (match_dup 2) (match_dup 1))
17472 (set (match_dup 0) (match_dup 2))]
17473 "")
17474
17475 ;; Don't compare memory with zero, load and use a test instead.
17476 (define_peephole2
17477 [(set (reg 17)
17478 (compare (match_operand:SI 0 "memory_operand" "")
17479 (const_int 0)))
17480 (match_scratch:SI 3 "r")]
17481 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17482 [(set (match_dup 3) (match_dup 0))
17483 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17484 "")
17485
17486 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17487 ;; Don't split NOTs with a displacement operand, because resulting XOR
17488 ;; will not be pairable anyway.
17489 ;;
17490 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17491 ;; represented using a modRM byte. The XOR replacement is long decoded,
17492 ;; so this split helps here as well.
17493 ;;
17494 ;; Note: Can't do this as a regular split because we can't get proper
17495 ;; lifetime information then.
17496
17497 (define_peephole2
17498 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17499 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17500 "!optimize_size
17501 && peep2_regno_dead_p (0, FLAGS_REG)
17502 && ((TARGET_PENTIUM
17503 && (GET_CODE (operands[0]) != MEM
17504 || !memory_displacement_operand (operands[0], SImode)))
17505 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17506 [(parallel [(set (match_dup 0)
17507 (xor:SI (match_dup 1) (const_int -1)))
17508 (clobber (reg:CC 17))])]
17509 "")
17510
17511 (define_peephole2
17512 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17513 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17514 "!optimize_size
17515 && peep2_regno_dead_p (0, FLAGS_REG)
17516 && ((TARGET_PENTIUM
17517 && (GET_CODE (operands[0]) != MEM
17518 || !memory_displacement_operand (operands[0], HImode)))
17519 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17520 [(parallel [(set (match_dup 0)
17521 (xor:HI (match_dup 1) (const_int -1)))
17522 (clobber (reg:CC 17))])]
17523 "")
17524
17525 (define_peephole2
17526 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17527 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17528 "!optimize_size
17529 && peep2_regno_dead_p (0, FLAGS_REG)
17530 && ((TARGET_PENTIUM
17531 && (GET_CODE (operands[0]) != MEM
17532 || !memory_displacement_operand (operands[0], QImode)))
17533 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17534 [(parallel [(set (match_dup 0)
17535 (xor:QI (match_dup 1) (const_int -1)))
17536 (clobber (reg:CC 17))])]
17537 "")
17538
17539 ;; Non pairable "test imm, reg" instructions can be translated to
17540 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17541 ;; byte opcode instead of two, have a short form for byte operands),
17542 ;; so do it for other CPUs as well. Given that the value was dead,
17543 ;; this should not create any new dependencies. Pass on the sub-word
17544 ;; versions if we're concerned about partial register stalls.
17545
17546 (define_peephole2
17547 [(set (reg 17)
17548 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17549 (match_operand:SI 1 "immediate_operand" ""))
17550 (const_int 0)))]
17551 "ix86_match_ccmode (insn, CCNOmode)
17552 && (true_regnum (operands[0]) != 0
17553 || (GET_CODE (operands[1]) == CONST_INT
17554 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17555 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17556 [(parallel
17557 [(set (reg:CCNO 17)
17558 (compare:CCNO (and:SI (match_dup 0)
17559 (match_dup 1))
17560 (const_int 0)))
17561 (set (match_dup 0)
17562 (and:SI (match_dup 0) (match_dup 1)))])]
17563 "")
17564
17565 ;; We don't need to handle HImode case, because it will be promoted to SImode
17566 ;; on ! TARGET_PARTIAL_REG_STALL
17567
17568 (define_peephole2
17569 [(set (reg 17)
17570 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17571 (match_operand:QI 1 "immediate_operand" ""))
17572 (const_int 0)))]
17573 "! TARGET_PARTIAL_REG_STALL
17574 && ix86_match_ccmode (insn, CCNOmode)
17575 && true_regnum (operands[0]) != 0
17576 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17577 [(parallel
17578 [(set (reg:CCNO 17)
17579 (compare:CCNO (and:QI (match_dup 0)
17580 (match_dup 1))
17581 (const_int 0)))
17582 (set (match_dup 0)
17583 (and:QI (match_dup 0) (match_dup 1)))])]
17584 "")
17585
17586 (define_peephole2
17587 [(set (reg 17)
17588 (compare
17589 (and:SI
17590 (zero_extract:SI
17591 (match_operand 0 "ext_register_operand" "")
17592 (const_int 8)
17593 (const_int 8))
17594 (match_operand 1 "const_int_operand" ""))
17595 (const_int 0)))]
17596 "! TARGET_PARTIAL_REG_STALL
17597 && ix86_match_ccmode (insn, CCNOmode)
17598 && true_regnum (operands[0]) != 0
17599 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17600 [(parallel [(set (reg:CCNO 17)
17601 (compare:CCNO
17602 (and:SI
17603 (zero_extract:SI
17604 (match_dup 0)
17605 (const_int 8)
17606 (const_int 8))
17607 (match_dup 1))
17608 (const_int 0)))
17609 (set (zero_extract:SI (match_dup 0)
17610 (const_int 8)
17611 (const_int 8))
17612 (and:SI
17613 (zero_extract:SI
17614 (match_dup 0)
17615 (const_int 8)
17616 (const_int 8))
17617 (match_dup 1)))])]
17618 "")
17619
17620 ;; Don't do logical operations with memory inputs.
17621 (define_peephole2
17622 [(match_scratch:SI 2 "r")
17623 (parallel [(set (match_operand:SI 0 "register_operand" "")
17624 (match_operator:SI 3 "arith_or_logical_operator"
17625 [(match_dup 0)
17626 (match_operand:SI 1 "memory_operand" "")]))
17627 (clobber (reg:CC 17))])]
17628 "! optimize_size && ! TARGET_READ_MODIFY"
17629 [(set (match_dup 2) (match_dup 1))
17630 (parallel [(set (match_dup 0)
17631 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17632 (clobber (reg:CC 17))])]
17633 "")
17634
17635 (define_peephole2
17636 [(match_scratch:SI 2 "r")
17637 (parallel [(set (match_operand:SI 0 "register_operand" "")
17638 (match_operator:SI 3 "arith_or_logical_operator"
17639 [(match_operand:SI 1 "memory_operand" "")
17640 (match_dup 0)]))
17641 (clobber (reg:CC 17))])]
17642 "! optimize_size && ! TARGET_READ_MODIFY"
17643 [(set (match_dup 2) (match_dup 1))
17644 (parallel [(set (match_dup 0)
17645 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17646 (clobber (reg:CC 17))])]
17647 "")
17648
17649 ; Don't do logical operations with memory outputs
17650 ;
17651 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17652 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17653 ; the same decoder scheduling characteristics as the original.
17654
17655 (define_peephole2
17656 [(match_scratch:SI 2 "r")
17657 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17658 (match_operator:SI 3 "arith_or_logical_operator"
17659 [(match_dup 0)
17660 (match_operand:SI 1 "nonmemory_operand" "")]))
17661 (clobber (reg:CC 17))])]
17662 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17663 [(set (match_dup 2) (match_dup 0))
17664 (parallel [(set (match_dup 2)
17665 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17666 (clobber (reg:CC 17))])
17667 (set (match_dup 0) (match_dup 2))]
17668 "")
17669
17670 (define_peephole2
17671 [(match_scratch:SI 2 "r")
17672 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17673 (match_operator:SI 3 "arith_or_logical_operator"
17674 [(match_operand:SI 1 "nonmemory_operand" "")
17675 (match_dup 0)]))
17676 (clobber (reg:CC 17))])]
17677 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17678 [(set (match_dup 2) (match_dup 0))
17679 (parallel [(set (match_dup 2)
17680 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17681 (clobber (reg:CC 17))])
17682 (set (match_dup 0) (match_dup 2))]
17683 "")
17684
17685 ;; Attempt to always use XOR for zeroing registers.
17686 (define_peephole2
17687 [(set (match_operand 0 "register_operand" "")
17688 (const_int 0))]
17689 "(GET_MODE (operands[0]) == QImode
17690 || GET_MODE (operands[0]) == HImode
17691 || GET_MODE (operands[0]) == SImode
17692 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17693 && (! TARGET_USE_MOV0 || optimize_size)
17694 && peep2_regno_dead_p (0, FLAGS_REG)"
17695 [(parallel [(set (match_dup 0) (const_int 0))
17696 (clobber (reg:CC 17))])]
17697 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17698 operands[0]);")
17699
17700 (define_peephole2
17701 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17702 (const_int 0))]
17703 "(GET_MODE (operands[0]) == QImode
17704 || GET_MODE (operands[0]) == HImode)
17705 && (! TARGET_USE_MOV0 || optimize_size)
17706 && peep2_regno_dead_p (0, FLAGS_REG)"
17707 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17708 (clobber (reg:CC 17))])])
17709
17710 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17711 (define_peephole2
17712 [(set (match_operand 0 "register_operand" "")
17713 (const_int -1))]
17714 "(GET_MODE (operands[0]) == HImode
17715 || GET_MODE (operands[0]) == SImode
17716 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17717 && (optimize_size || TARGET_PENTIUM)
17718 && peep2_regno_dead_p (0, FLAGS_REG)"
17719 [(parallel [(set (match_dup 0) (const_int -1))
17720 (clobber (reg:CC 17))])]
17721 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17722 operands[0]);")
17723
17724 ;; Attempt to convert simple leas to adds. These can be created by
17725 ;; move expanders.
17726 (define_peephole2
17727 [(set (match_operand:SI 0 "register_operand" "")
17728 (plus:SI (match_dup 0)
17729 (match_operand:SI 1 "nonmemory_operand" "")))]
17730 "peep2_regno_dead_p (0, FLAGS_REG)"
17731 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17732 (clobber (reg:CC 17))])]
17733 "")
17734
17735 (define_peephole2
17736 [(set (match_operand:SI 0 "register_operand" "")
17737 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17738 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17739 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17740 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17741 (clobber (reg:CC 17))])]
17742 "operands[2] = gen_lowpart (SImode, operands[2]);")
17743
17744 (define_peephole2
17745 [(set (match_operand:DI 0 "register_operand" "")
17746 (plus:DI (match_dup 0)
17747 (match_operand:DI 1 "x86_64_general_operand" "")))]
17748 "peep2_regno_dead_p (0, FLAGS_REG)"
17749 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17750 (clobber (reg:CC 17))])]
17751 "")
17752
17753 (define_peephole2
17754 [(set (match_operand:SI 0 "register_operand" "")
17755 (mult:SI (match_dup 0)
17756 (match_operand:SI 1 "const_int_operand" "")))]
17757 "exact_log2 (INTVAL (operands[1])) >= 0
17758 && peep2_regno_dead_p (0, FLAGS_REG)"
17759 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17760 (clobber (reg:CC 17))])]
17761 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17762
17763 (define_peephole2
17764 [(set (match_operand:DI 0 "register_operand" "")
17765 (mult:DI (match_dup 0)
17766 (match_operand:DI 1 "const_int_operand" "")))]
17767 "exact_log2 (INTVAL (operands[1])) >= 0
17768 && peep2_regno_dead_p (0, FLAGS_REG)"
17769 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17770 (clobber (reg:CC 17))])]
17771 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17772
17773 (define_peephole2
17774 [(set (match_operand:SI 0 "register_operand" "")
17775 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17776 (match_operand:DI 2 "const_int_operand" "")) 0))]
17777 "exact_log2 (INTVAL (operands[2])) >= 0
17778 && REGNO (operands[0]) == REGNO (operands[1])
17779 && peep2_regno_dead_p (0, FLAGS_REG)"
17780 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17781 (clobber (reg:CC 17))])]
17782 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17783
17784 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17785 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17786 ;; many CPUs it is also faster, since special hardware to avoid esp
17787 ;; dependencies is present.
17788
17789 ;; While some of these conversions may be done using splitters, we use peepholes
17790 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17791
17792 ;; Convert prologue esp subtractions to push.
17793 ;; We need register to push. In order to keep verify_flow_info happy we have
17794 ;; two choices
17795 ;; - use scratch and clobber it in order to avoid dependencies
17796 ;; - use already live register
17797 ;; We can't use the second way right now, since there is no reliable way how to
17798 ;; verify that given register is live. First choice will also most likely in
17799 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17800 ;; call clobbered registers are dead. We may want to use base pointer as an
17801 ;; alternative when no register is available later.
17802
17803 (define_peephole2
17804 [(match_scratch:SI 0 "r")
17805 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17806 (clobber (reg:CC 17))
17807 (clobber (mem:BLK (scratch)))])]
17808 "optimize_size || !TARGET_SUB_ESP_4"
17809 [(clobber (match_dup 0))
17810 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17811 (clobber (mem:BLK (scratch)))])])
17812
17813 (define_peephole2
17814 [(match_scratch:SI 0 "r")
17815 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17816 (clobber (reg:CC 17))
17817 (clobber (mem:BLK (scratch)))])]
17818 "optimize_size || !TARGET_SUB_ESP_8"
17819 [(clobber (match_dup 0))
17820 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17821 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17822 (clobber (mem:BLK (scratch)))])])
17823
17824 ;; Convert esp subtractions to push.
17825 (define_peephole2
17826 [(match_scratch:SI 0 "r")
17827 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17828 (clobber (reg:CC 17))])]
17829 "optimize_size || !TARGET_SUB_ESP_4"
17830 [(clobber (match_dup 0))
17831 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17832
17833 (define_peephole2
17834 [(match_scratch:SI 0 "r")
17835 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17836 (clobber (reg:CC 17))])]
17837 "optimize_size || !TARGET_SUB_ESP_8"
17838 [(clobber (match_dup 0))
17839 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17840 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17841
17842 ;; Convert epilogue deallocator to pop.
17843 (define_peephole2
17844 [(match_scratch:SI 0 "r")
17845 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17846 (clobber (reg:CC 17))
17847 (clobber (mem:BLK (scratch)))])]
17848 "optimize_size || !TARGET_ADD_ESP_4"
17849 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17850 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17851 (clobber (mem:BLK (scratch)))])]
17852 "")
17853
17854 ;; Two pops case is tricky, since pop causes dependency on destination register.
17855 ;; We use two registers if available.
17856 (define_peephole2
17857 [(match_scratch:SI 0 "r")
17858 (match_scratch:SI 1 "r")
17859 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17860 (clobber (reg:CC 17))
17861 (clobber (mem:BLK (scratch)))])]
17862 "optimize_size || !TARGET_ADD_ESP_8"
17863 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17864 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17865 (clobber (mem:BLK (scratch)))])
17866 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17867 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17868 "")
17869
17870 (define_peephole2
17871 [(match_scratch:SI 0 "r")
17872 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17873 (clobber (reg:CC 17))
17874 (clobber (mem:BLK (scratch)))])]
17875 "optimize_size"
17876 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17877 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17878 (clobber (mem:BLK (scratch)))])
17879 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17880 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17881 "")
17882
17883 ;; Convert esp additions to pop.
17884 (define_peephole2
17885 [(match_scratch:SI 0 "r")
17886 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17887 (clobber (reg:CC 17))])]
17888 ""
17889 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17890 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17891 "")
17892
17893 ;; Two pops case is tricky, since pop causes dependency on destination register.
17894 ;; We use two registers if available.
17895 (define_peephole2
17896 [(match_scratch:SI 0 "r")
17897 (match_scratch:SI 1 "r")
17898 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17899 (clobber (reg:CC 17))])]
17900 ""
17901 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17902 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17903 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17904 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17905 "")
17906
17907 (define_peephole2
17908 [(match_scratch:SI 0 "r")
17909 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17910 (clobber (reg:CC 17))])]
17911 "optimize_size"
17912 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17913 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17914 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17915 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17916 "")
17917 \f
17918 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17919 ;; required and register dies.
17920 (define_peephole2
17921 [(set (reg 17)
17922 (compare (match_operand:SI 0 "register_operand" "")
17923 (match_operand:SI 1 "incdec_operand" "")))]
17924 "ix86_match_ccmode (insn, CCGCmode)
17925 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17926 [(parallel [(set (reg:CCGC 17)
17927 (compare:CCGC (match_dup 0)
17928 (match_dup 1)))
17929 (clobber (match_dup 0))])]
17930 "")
17931
17932 (define_peephole2
17933 [(set (reg 17)
17934 (compare (match_operand:HI 0 "register_operand" "")
17935 (match_operand:HI 1 "incdec_operand" "")))]
17936 "ix86_match_ccmode (insn, CCGCmode)
17937 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17938 [(parallel [(set (reg:CCGC 17)
17939 (compare:CCGC (match_dup 0)
17940 (match_dup 1)))
17941 (clobber (match_dup 0))])]
17942 "")
17943
17944 (define_peephole2
17945 [(set (reg 17)
17946 (compare (match_operand:QI 0 "register_operand" "")
17947 (match_operand:QI 1 "incdec_operand" "")))]
17948 "ix86_match_ccmode (insn, CCGCmode)
17949 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17950 [(parallel [(set (reg:CCGC 17)
17951 (compare:CCGC (match_dup 0)
17952 (match_dup 1)))
17953 (clobber (match_dup 0))])]
17954 "")
17955
17956 ;; Convert compares with 128 to shorter add -128
17957 (define_peephole2
17958 [(set (reg 17)
17959 (compare (match_operand:SI 0 "register_operand" "")
17960 (const_int 128)))]
17961 "ix86_match_ccmode (insn, CCGCmode)
17962 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17963 [(parallel [(set (reg:CCGC 17)
17964 (compare:CCGC (match_dup 0)
17965 (const_int 128)))
17966 (clobber (match_dup 0))])]
17967 "")
17968
17969 (define_peephole2
17970 [(set (reg 17)
17971 (compare (match_operand:HI 0 "register_operand" "")
17972 (const_int 128)))]
17973 "ix86_match_ccmode (insn, CCGCmode)
17974 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17975 [(parallel [(set (reg:CCGC 17)
17976 (compare:CCGC (match_dup 0)
17977 (const_int 128)))
17978 (clobber (match_dup 0))])]
17979 "")
17980 \f
17981 (define_peephole2
17982 [(match_scratch:DI 0 "r")
17983 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
17984 (clobber (reg:CC 17))
17985 (clobber (mem:BLK (scratch)))])]
17986 "optimize_size || !TARGET_SUB_ESP_4"
17987 [(clobber (match_dup 0))
17988 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17989 (clobber (mem:BLK (scratch)))])])
17990
17991 (define_peephole2
17992 [(match_scratch:DI 0 "r")
17993 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
17994 (clobber (reg:CC 17))
17995 (clobber (mem:BLK (scratch)))])]
17996 "optimize_size || !TARGET_SUB_ESP_8"
17997 [(clobber (match_dup 0))
17998 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
17999 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18000 (clobber (mem:BLK (scratch)))])])
18001
18002 ;; Convert esp subtractions to push.
18003 (define_peephole2
18004 [(match_scratch:DI 0 "r")
18005 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18006 (clobber (reg:CC 17))])]
18007 "optimize_size || !TARGET_SUB_ESP_4"
18008 [(clobber (match_dup 0))
18009 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18010
18011 (define_peephole2
18012 [(match_scratch:DI 0 "r")
18013 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18014 (clobber (reg:CC 17))])]
18015 "optimize_size || !TARGET_SUB_ESP_8"
18016 [(clobber (match_dup 0))
18017 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18018 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18019
18020 ;; Convert epilogue deallocator to pop.
18021 (define_peephole2
18022 [(match_scratch:DI 0 "r")
18023 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18024 (clobber (reg:CC 17))
18025 (clobber (mem:BLK (scratch)))])]
18026 "optimize_size || !TARGET_ADD_ESP_4"
18027 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18028 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18029 (clobber (mem:BLK (scratch)))])]
18030 "")
18031
18032 ;; Two pops case is tricky, since pop causes dependency on destination register.
18033 ;; We use two registers if available.
18034 (define_peephole2
18035 [(match_scratch:DI 0 "r")
18036 (match_scratch:DI 1 "r")
18037 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18038 (clobber (reg:CC 17))
18039 (clobber (mem:BLK (scratch)))])]
18040 "optimize_size || !TARGET_ADD_ESP_8"
18041 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18042 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18043 (clobber (mem:BLK (scratch)))])
18044 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18045 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18046 "")
18047
18048 (define_peephole2
18049 [(match_scratch:DI 0 "r")
18050 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18051 (clobber (reg:CC 17))
18052 (clobber (mem:BLK (scratch)))])]
18053 "optimize_size"
18054 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18055 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18056 (clobber (mem:BLK (scratch)))])
18057 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18058 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18059 "")
18060
18061 ;; Convert esp additions to pop.
18062 (define_peephole2
18063 [(match_scratch:DI 0 "r")
18064 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18065 (clobber (reg:CC 17))])]
18066 ""
18067 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18068 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18069 "")
18070
18071 ;; Two pops case is tricky, since pop causes dependency on destination register.
18072 ;; We use two registers if available.
18073 (define_peephole2
18074 [(match_scratch:DI 0 "r")
18075 (match_scratch:DI 1 "r")
18076 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18077 (clobber (reg:CC 17))])]
18078 ""
18079 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18080 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18081 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18082 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18083 "")
18084
18085 (define_peephole2
18086 [(match_scratch:DI 0 "r")
18087 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18088 (clobber (reg:CC 17))])]
18089 "optimize_size"
18090 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18091 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18092 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18093 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18094 "")
18095 \f
18096 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18097 ;; imul $32bit_imm, reg, reg is direct decoded.
18098 (define_peephole2
18099 [(match_scratch:DI 3 "r")
18100 (parallel [(set (match_operand:DI 0 "register_operand" "")
18101 (mult:DI (match_operand:DI 1 "memory_operand" "")
18102 (match_operand:DI 2 "immediate_operand" "")))
18103 (clobber (reg:CC 17))])]
18104 "TARGET_K8 && !optimize_size
18105 && (GET_CODE (operands[2]) != CONST_INT
18106 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18107 [(set (match_dup 3) (match_dup 1))
18108 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18109 (clobber (reg:CC 17))])]
18110 "")
18111
18112 (define_peephole2
18113 [(match_scratch:SI 3 "r")
18114 (parallel [(set (match_operand:SI 0 "register_operand" "")
18115 (mult:SI (match_operand:SI 1 "memory_operand" "")
18116 (match_operand:SI 2 "immediate_operand" "")))
18117 (clobber (reg:CC 17))])]
18118 "TARGET_K8 && !optimize_size
18119 && (GET_CODE (operands[2]) != CONST_INT
18120 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18121 [(set (match_dup 3) (match_dup 1))
18122 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18123 (clobber (reg:CC 17))])]
18124 "")
18125
18126 (define_peephole2
18127 [(match_scratch:SI 3 "r")
18128 (parallel [(set (match_operand:DI 0 "register_operand" "")
18129 (zero_extend:DI
18130 (mult:SI (match_operand:SI 1 "memory_operand" "")
18131 (match_operand:SI 2 "immediate_operand" ""))))
18132 (clobber (reg:CC 17))])]
18133 "TARGET_K8 && !optimize_size
18134 && (GET_CODE (operands[2]) != CONST_INT
18135 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18136 [(set (match_dup 3) (match_dup 1))
18137 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18138 (clobber (reg:CC 17))])]
18139 "")
18140
18141 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18142 ;; Convert it into imul reg, reg
18143 ;; It would be better to force assembler to encode instruction using long
18144 ;; immediate, but there is apparently no way to do so.
18145 (define_peephole2
18146 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18147 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18148 (match_operand:DI 2 "const_int_operand" "")))
18149 (clobber (reg:CC 17))])
18150 (match_scratch:DI 3 "r")]
18151 "TARGET_K8 && !optimize_size
18152 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18153 [(set (match_dup 3) (match_dup 2))
18154 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18155 (clobber (reg:CC 17))])]
18156 {
18157 if (!rtx_equal_p (operands[0], operands[1]))
18158 emit_move_insn (operands[0], operands[1]);
18159 })
18160
18161 (define_peephole2
18162 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18163 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18164 (match_operand:SI 2 "const_int_operand" "")))
18165 (clobber (reg:CC 17))])
18166 (match_scratch:SI 3 "r")]
18167 "TARGET_K8 && !optimize_size
18168 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18169 [(set (match_dup 3) (match_dup 2))
18170 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18171 (clobber (reg:CC 17))])]
18172 {
18173 if (!rtx_equal_p (operands[0], operands[1]))
18174 emit_move_insn (operands[0], operands[1]);
18175 })
18176
18177 (define_peephole2
18178 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18179 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18180 (match_operand:HI 2 "immediate_operand" "")))
18181 (clobber (reg:CC 17))])
18182 (match_scratch:HI 3 "r")]
18183 "TARGET_K8 && !optimize_size"
18184 [(set (match_dup 3) (match_dup 2))
18185 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18186 (clobber (reg:CC 17))])]
18187 {
18188 if (!rtx_equal_p (operands[0], operands[1]))
18189 emit_move_insn (operands[0], operands[1]);
18190 })
18191 \f
18192 ;; Call-value patterns last so that the wildcard operand does not
18193 ;; disrupt insn-recog's switch tables.
18194
18195 (define_insn "*call_value_pop_0"
18196 [(set (match_operand 0 "" "")
18197 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18198 (match_operand:SI 2 "" "")))
18199 (set (reg:SI 7) (plus:SI (reg:SI 7)
18200 (match_operand:SI 3 "immediate_operand" "")))]
18201 "!TARGET_64BIT"
18202 {
18203 if (SIBLING_CALL_P (insn))
18204 return "jmp\t%P1";
18205 else
18206 return "call\t%P1";
18207 }
18208 [(set_attr "type" "callv")])
18209
18210 (define_insn "*call_value_pop_1"
18211 [(set (match_operand 0 "" "")
18212 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18213 (match_operand:SI 2 "" "")))
18214 (set (reg:SI 7) (plus:SI (reg:SI 7)
18215 (match_operand:SI 3 "immediate_operand" "i")))]
18216 "!TARGET_64BIT"
18217 {
18218 if (constant_call_address_operand (operands[1], QImode))
18219 {
18220 if (SIBLING_CALL_P (insn))
18221 return "jmp\t%P1";
18222 else
18223 return "call\t%P1";
18224 }
18225 if (SIBLING_CALL_P (insn))
18226 return "jmp\t%A1";
18227 else
18228 return "call\t%A1";
18229 }
18230 [(set_attr "type" "callv")])
18231
18232 (define_insn "*call_value_0"
18233 [(set (match_operand 0 "" "")
18234 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18235 (match_operand:SI 2 "" "")))]
18236 "!TARGET_64BIT"
18237 {
18238 if (SIBLING_CALL_P (insn))
18239 return "jmp\t%P1";
18240 else
18241 return "call\t%P1";
18242 }
18243 [(set_attr "type" "callv")])
18244
18245 (define_insn "*call_value_0_rex64"
18246 [(set (match_operand 0 "" "")
18247 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18248 (match_operand:DI 2 "const_int_operand" "")))]
18249 "TARGET_64BIT"
18250 {
18251 if (SIBLING_CALL_P (insn))
18252 return "jmp\t%P1";
18253 else
18254 return "call\t%P1";
18255 }
18256 [(set_attr "type" "callv")])
18257
18258 (define_insn "*call_value_1"
18259 [(set (match_operand 0 "" "")
18260 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18261 (match_operand:SI 2 "" "")))]
18262 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18263 {
18264 if (constant_call_address_operand (operands[1], QImode))
18265 return "call\t%P1";
18266 return "call\t%*%1";
18267 }
18268 [(set_attr "type" "callv")])
18269
18270 (define_insn "*sibcall_value_1"
18271 [(set (match_operand 0 "" "")
18272 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18273 (match_operand:SI 2 "" "")))]
18274 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18275 {
18276 if (constant_call_address_operand (operands[1], QImode))
18277 return "jmp\t%P1";
18278 return "jmp\t%*%1";
18279 }
18280 [(set_attr "type" "callv")])
18281
18282 (define_insn "*call_value_1_rex64"
18283 [(set (match_operand 0 "" "")
18284 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18285 (match_operand:DI 2 "" "")))]
18286 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18287 {
18288 if (constant_call_address_operand (operands[1], QImode))
18289 return "call\t%P1";
18290 return "call\t%A1";
18291 }
18292 [(set_attr "type" "callv")])
18293
18294 (define_insn "*sibcall_value_1_rex64"
18295 [(set (match_operand 0 "" "")
18296 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18297 (match_operand:DI 2 "" "")))]
18298 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18299 "jmp\t%P1"
18300 [(set_attr "type" "callv")])
18301
18302 (define_insn "*sibcall_value_1_rex64_v"
18303 [(set (match_operand 0 "" "")
18304 (call (mem:QI (reg:DI 40))
18305 (match_operand:DI 1 "" "")))]
18306 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18307 "jmp\t*%%r11"
18308 [(set_attr "type" "callv")])
18309 \f
18310 (define_insn "trap"
18311 [(trap_if (const_int 1) (const_int 5))]
18312 ""
18313 "int\t$5")
18314
18315 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18316 ;;; for the sake of bounds checking. By emitting bounds checks as
18317 ;;; conditional traps rather than as conditional jumps around
18318 ;;; unconditional traps we avoid introducing spurious basic-block
18319 ;;; boundaries and facilitate elimination of redundant checks. In
18320 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18321 ;;; interrupt 5.
18322 ;;;
18323 ;;; FIXME: Static branch prediction rules for ix86 are such that
18324 ;;; forward conditional branches predict as untaken. As implemented
18325 ;;; below, pseudo conditional traps violate that rule. We should use
18326 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18327 ;;; section loaded at the end of the text segment and branch forward
18328 ;;; there on bounds-failure, and then jump back immediately (in case
18329 ;;; the system chooses to ignore bounds violations, or to report
18330 ;;; violations and continue execution).
18331
18332 (define_expand "conditional_trap"
18333 [(trap_if (match_operator 0 "comparison_operator"
18334 [(match_dup 2) (const_int 0)])
18335 (match_operand 1 "const_int_operand" ""))]
18336 ""
18337 {
18338 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18339 ix86_expand_compare (GET_CODE (operands[0]),
18340 NULL, NULL),
18341 operands[1]));
18342 DONE;
18343 })
18344
18345 (define_insn "*conditional_trap_1"
18346 [(trap_if (match_operator 0 "comparison_operator"
18347 [(reg 17) (const_int 0)])
18348 (match_operand 1 "const_int_operand" ""))]
18349 ""
18350 {
18351 operands[2] = gen_label_rtx ();
18352 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18353 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18354 CODE_LABEL_NUMBER (operands[2]));
18355 RET;
18356 })
18357
18358 ;; Pentium III SIMD instructions.
18359
18360 ;; Moves for SSE/MMX regs.
18361
18362 (define_insn "movv4sf_internal"
18363 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18364 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18365 "TARGET_SSE"
18366 "@
18367 xorps\t%0, %0
18368 movaps\t{%1, %0|%0, %1}
18369 movaps\t{%1, %0|%0, %1}"
18370 [(set_attr "type" "ssemov")
18371 (set_attr "mode" "V4SF")])
18372
18373 (define_split
18374 [(set (match_operand:V4SF 0 "register_operand" "")
18375 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18376 "TARGET_SSE"
18377 [(set (match_dup 0)
18378 (vec_merge:V4SF
18379 (vec_duplicate:V4SF (match_dup 1))
18380 (match_dup 2)
18381 (const_int 1)))]
18382 {
18383 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18384 operands[2] = CONST0_RTX (V4SFmode);
18385 })
18386
18387 (define_insn "movv4si_internal"
18388 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18389 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18390 "TARGET_SSE"
18391 {
18392 switch (which_alternative)
18393 {
18394 case 0:
18395 if (get_attr_mode (insn) == MODE_V4SF)
18396 return "xorps\t%0, %0";
18397 else
18398 return "pxor\t%0, %0";
18399 case 1:
18400 case 2:
18401 if (get_attr_mode (insn) == MODE_V4SF)
18402 return "movaps\t{%1, %0|%0, %1}";
18403 else
18404 return "movdqa\t{%1, %0|%0, %1}";
18405 default:
18406 abort ();
18407 }
18408 }
18409 [(set_attr "type" "ssemov")
18410 (set (attr "mode")
18411 (cond [(eq_attr "alternative" "0,1")
18412 (if_then_else
18413 (ne (symbol_ref "optimize_size")
18414 (const_int 0))
18415 (const_string "V4SF")
18416 (const_string "TI"))
18417 (eq_attr "alternative" "2")
18418 (if_then_else
18419 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18420 (const_int 0))
18421 (ne (symbol_ref "optimize_size")
18422 (const_int 0)))
18423 (const_string "V4SF")
18424 (const_string "TI"))]
18425 (const_string "TI")))])
18426
18427 (define_insn "movv2di_internal"
18428 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18429 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18430 "TARGET_SSE2"
18431 {
18432 switch (which_alternative)
18433 {
18434 case 0:
18435 if (get_attr_mode (insn) == MODE_V4SF)
18436 return "xorps\t%0, %0";
18437 else
18438 return "pxor\t%0, %0";
18439 case 1:
18440 case 2:
18441 if (get_attr_mode (insn) == MODE_V4SF)
18442 return "movaps\t{%1, %0|%0, %1}";
18443 else
18444 return "movdqa\t{%1, %0|%0, %1}";
18445 default:
18446 abort ();
18447 }
18448 }
18449 [(set_attr "type" "ssemov")
18450 (set (attr "mode")
18451 (cond [(eq_attr "alternative" "0,1")
18452 (if_then_else
18453 (ne (symbol_ref "optimize_size")
18454 (const_int 0))
18455 (const_string "V4SF")
18456 (const_string "TI"))
18457 (eq_attr "alternative" "2")
18458 (if_then_else
18459 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18460 (const_int 0))
18461 (ne (symbol_ref "optimize_size")
18462 (const_int 0)))
18463 (const_string "V4SF")
18464 (const_string "TI"))]
18465 (const_string "TI")))])
18466
18467 (define_split
18468 [(set (match_operand:V2DF 0 "register_operand" "")
18469 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18470 "TARGET_SSE2"
18471 [(set (match_dup 0)
18472 (vec_merge:V2DF
18473 (vec_duplicate:V2DF (match_dup 1))
18474 (match_dup 2)
18475 (const_int 1)))]
18476 {
18477 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18478 operands[2] = CONST0_RTX (V2DFmode);
18479 })
18480
18481 (define_insn "movv8qi_internal"
18482 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18483 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18484 "TARGET_MMX
18485 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18486 "@
18487 pxor\t%0, %0
18488 movq\t{%1, %0|%0, %1}
18489 movq\t{%1, %0|%0, %1}"
18490 [(set_attr "type" "mmxmov")
18491 (set_attr "mode" "DI")])
18492
18493 (define_insn "movv4hi_internal"
18494 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18495 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18496 "TARGET_MMX
18497 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18498 "@
18499 pxor\t%0, %0
18500 movq\t{%1, %0|%0, %1}
18501 movq\t{%1, %0|%0, %1}"
18502 [(set_attr "type" "mmxmov")
18503 (set_attr "mode" "DI")])
18504
18505 (define_insn "movv2si_internal"
18506 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18507 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18508 "TARGET_MMX
18509 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18510 "@
18511 pxor\t%0, %0
18512 movq\t{%1, %0|%0, %1}
18513 movq\t{%1, %0|%0, %1}"
18514 [(set_attr "type" "mmxcvt")
18515 (set_attr "mode" "DI")])
18516
18517 (define_insn "movv2sf_internal"
18518 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18519 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18520 "TARGET_3DNOW
18521 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18522 "@
18523 pxor\t%0, %0
18524 movq\t{%1, %0|%0, %1}
18525 movq\t{%1, %0|%0, %1}"
18526 [(set_attr "type" "mmxcvt")
18527 (set_attr "mode" "DI")])
18528
18529 (define_expand "movti"
18530 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18531 (match_operand:TI 1 "nonimmediate_operand" ""))]
18532 "TARGET_SSE || TARGET_64BIT"
18533 {
18534 if (TARGET_64BIT)
18535 ix86_expand_move (TImode, operands);
18536 else
18537 ix86_expand_vector_move (TImode, operands);
18538 DONE;
18539 })
18540
18541 (define_expand "movtf"
18542 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18543 (match_operand:TF 1 "nonimmediate_operand" ""))]
18544 "TARGET_64BIT"
18545 {
18546 if (TARGET_64BIT)
18547 ix86_expand_move (TFmode, operands);
18548 else
18549 ix86_expand_vector_move (TFmode, operands);
18550 DONE;
18551 })
18552
18553 (define_insn "movv2df_internal"
18554 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18555 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18556 "TARGET_SSE2
18557 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18558 {
18559 switch (which_alternative)
18560 {
18561 case 0:
18562 if (get_attr_mode (insn) == MODE_V4SF)
18563 return "xorps\t%0, %0";
18564 else
18565 return "xorpd\t%0, %0";
18566 case 1:
18567 case 2:
18568 if (get_attr_mode (insn) == MODE_V4SF)
18569 return "movaps\t{%1, %0|%0, %1}";
18570 else
18571 return "movapd\t{%1, %0|%0, %1}";
18572 default:
18573 abort ();
18574 }
18575 }
18576 [(set_attr "type" "ssemov")
18577 (set (attr "mode")
18578 (cond [(eq_attr "alternative" "0,1")
18579 (if_then_else
18580 (ne (symbol_ref "optimize_size")
18581 (const_int 0))
18582 (const_string "V4SF")
18583 (const_string "V2DF"))
18584 (eq_attr "alternative" "2")
18585 (if_then_else
18586 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18587 (const_int 0))
18588 (ne (symbol_ref "optimize_size")
18589 (const_int 0)))
18590 (const_string "V4SF")
18591 (const_string "V2DF"))]
18592 (const_string "V2DF")))])
18593
18594 (define_insn "movv8hi_internal"
18595 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18596 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18597 "TARGET_SSE2
18598 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18599 {
18600 switch (which_alternative)
18601 {
18602 case 0:
18603 if (get_attr_mode (insn) == MODE_V4SF)
18604 return "xorps\t%0, %0";
18605 else
18606 return "pxor\t%0, %0";
18607 case 1:
18608 case 2:
18609 if (get_attr_mode (insn) == MODE_V4SF)
18610 return "movaps\t{%1, %0|%0, %1}";
18611 else
18612 return "movdqa\t{%1, %0|%0, %1}";
18613 default:
18614 abort ();
18615 }
18616 }
18617 [(set_attr "type" "ssemov")
18618 (set (attr "mode")
18619 (cond [(eq_attr "alternative" "0,1")
18620 (if_then_else
18621 (ne (symbol_ref "optimize_size")
18622 (const_int 0))
18623 (const_string "V4SF")
18624 (const_string "TI"))
18625 (eq_attr "alternative" "2")
18626 (if_then_else
18627 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18628 (const_int 0))
18629 (ne (symbol_ref "optimize_size")
18630 (const_int 0)))
18631 (const_string "V4SF")
18632 (const_string "TI"))]
18633 (const_string "TI")))])
18634
18635 (define_insn "movv16qi_internal"
18636 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18637 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18638 "TARGET_SSE2
18639 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18640 {
18641 switch (which_alternative)
18642 {
18643 case 0:
18644 if (get_attr_mode (insn) == MODE_V4SF)
18645 return "xorps\t%0, %0";
18646 else
18647 return "pxor\t%0, %0";
18648 case 1:
18649 case 2:
18650 if (get_attr_mode (insn) == MODE_V4SF)
18651 return "movaps\t{%1, %0|%0, %1}";
18652 else
18653 return "movdqa\t{%1, %0|%0, %1}";
18654 default:
18655 abort ();
18656 }
18657 }
18658 [(set_attr "type" "ssemov")
18659 (set (attr "mode")
18660 (cond [(eq_attr "alternative" "0,1")
18661 (if_then_else
18662 (ne (symbol_ref "optimize_size")
18663 (const_int 0))
18664 (const_string "V4SF")
18665 (const_string "TI"))
18666 (eq_attr "alternative" "2")
18667 (if_then_else
18668 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18669 (const_int 0))
18670 (ne (symbol_ref "optimize_size")
18671 (const_int 0)))
18672 (const_string "V4SF")
18673 (const_string "TI"))]
18674 (const_string "TI")))])
18675
18676 (define_expand "movv2df"
18677 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18678 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18679 "TARGET_SSE2"
18680 {
18681 ix86_expand_vector_move (V2DFmode, operands);
18682 DONE;
18683 })
18684
18685 (define_expand "movv8hi"
18686 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18687 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18688 "TARGET_SSE2"
18689 {
18690 ix86_expand_vector_move (V8HImode, operands);
18691 DONE;
18692 })
18693
18694 (define_expand "movv16qi"
18695 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18696 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18697 "TARGET_SSE2"
18698 {
18699 ix86_expand_vector_move (V16QImode, operands);
18700 DONE;
18701 })
18702
18703 (define_expand "movv4sf"
18704 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18705 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18706 "TARGET_SSE"
18707 {
18708 ix86_expand_vector_move (V4SFmode, operands);
18709 DONE;
18710 })
18711
18712 (define_expand "movv4si"
18713 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18714 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18715 "TARGET_SSE"
18716 {
18717 ix86_expand_vector_move (V4SImode, operands);
18718 DONE;
18719 })
18720
18721 (define_expand "movv2di"
18722 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18723 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18724 "TARGET_SSE"
18725 {
18726 ix86_expand_vector_move (V2DImode, operands);
18727 DONE;
18728 })
18729
18730 (define_expand "movv2si"
18731 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18732 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18733 "TARGET_MMX"
18734 {
18735 ix86_expand_vector_move (V2SImode, operands);
18736 DONE;
18737 })
18738
18739 (define_expand "movv4hi"
18740 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18741 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18742 "TARGET_MMX"
18743 {
18744 ix86_expand_vector_move (V4HImode, operands);
18745 DONE;
18746 })
18747
18748 (define_expand "movv8qi"
18749 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18750 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18751 "TARGET_MMX"
18752 {
18753 ix86_expand_vector_move (V8QImode, operands);
18754 DONE;
18755 })
18756
18757 (define_expand "movv2sf"
18758 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18759 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18760 "TARGET_3DNOW"
18761 {
18762 ix86_expand_vector_move (V2SFmode, operands);
18763 DONE;
18764 })
18765
18766 (define_insn "*pushti"
18767 [(set (match_operand:TI 0 "push_operand" "=<")
18768 (match_operand:TI 1 "register_operand" "x"))]
18769 "TARGET_SSE"
18770 "#")
18771
18772 (define_insn "*pushv2df"
18773 [(set (match_operand:V2DF 0 "push_operand" "=<")
18774 (match_operand:V2DF 1 "register_operand" "x"))]
18775 "TARGET_SSE"
18776 "#")
18777
18778 (define_insn "*pushv2di"
18779 [(set (match_operand:V2DI 0 "push_operand" "=<")
18780 (match_operand:V2DI 1 "register_operand" "x"))]
18781 "TARGET_SSE2"
18782 "#")
18783
18784 (define_insn "*pushv8hi"
18785 [(set (match_operand:V8HI 0 "push_operand" "=<")
18786 (match_operand:V8HI 1 "register_operand" "x"))]
18787 "TARGET_SSE2"
18788 "#")
18789
18790 (define_insn "*pushv16qi"
18791 [(set (match_operand:V16QI 0 "push_operand" "=<")
18792 (match_operand:V16QI 1 "register_operand" "x"))]
18793 "TARGET_SSE2"
18794 "#")
18795
18796 (define_insn "*pushv4sf"
18797 [(set (match_operand:V4SF 0 "push_operand" "=<")
18798 (match_operand:V4SF 1 "register_operand" "x"))]
18799 "TARGET_SSE"
18800 "#")
18801
18802 (define_insn "*pushv4si"
18803 [(set (match_operand:V4SI 0 "push_operand" "=<")
18804 (match_operand:V4SI 1 "register_operand" "x"))]
18805 "TARGET_SSE2"
18806 "#")
18807
18808 (define_insn "*pushv2si"
18809 [(set (match_operand:V2SI 0 "push_operand" "=<")
18810 (match_operand:V2SI 1 "register_operand" "y"))]
18811 "TARGET_MMX"
18812 "#")
18813
18814 (define_insn "*pushv4hi"
18815 [(set (match_operand:V4HI 0 "push_operand" "=<")
18816 (match_operand:V4HI 1 "register_operand" "y"))]
18817 "TARGET_MMX"
18818 "#")
18819
18820 (define_insn "*pushv8qi"
18821 [(set (match_operand:V8QI 0 "push_operand" "=<")
18822 (match_operand:V8QI 1 "register_operand" "y"))]
18823 "TARGET_MMX"
18824 "#")
18825
18826 (define_insn "*pushv2sf"
18827 [(set (match_operand:V2SF 0 "push_operand" "=<")
18828 (match_operand:V2SF 1 "register_operand" "y"))]
18829 "TARGET_3DNOW"
18830 "#")
18831
18832 (define_split
18833 [(set (match_operand 0 "push_operand" "")
18834 (match_operand 1 "register_operand" ""))]
18835 "!TARGET_64BIT && reload_completed
18836 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18837 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18838 (set (match_dup 2) (match_dup 1))]
18839 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18840 stack_pointer_rtx);
18841 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18842
18843 (define_split
18844 [(set (match_operand 0 "push_operand" "")
18845 (match_operand 1 "register_operand" ""))]
18846 "TARGET_64BIT && reload_completed
18847 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18848 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18849 (set (match_dup 2) (match_dup 1))]
18850 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18851 stack_pointer_rtx);
18852 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18853
18854
18855 (define_insn "movti_internal"
18856 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18857 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18858 "TARGET_SSE && !TARGET_64BIT
18859 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18860 {
18861 switch (which_alternative)
18862 {
18863 case 0:
18864 if (get_attr_mode (insn) == MODE_V4SF)
18865 return "xorps\t%0, %0";
18866 else
18867 return "pxor\t%0, %0";
18868 case 1:
18869 case 2:
18870 if (get_attr_mode (insn) == MODE_V4SF)
18871 return "movaps\t{%1, %0|%0, %1}";
18872 else
18873 return "movdqa\t{%1, %0|%0, %1}";
18874 default:
18875 abort ();
18876 }
18877 }
18878 [(set_attr "type" "ssemov,ssemov,ssemov")
18879 (set (attr "mode")
18880 (cond [(eq_attr "alternative" "0,1")
18881 (if_then_else
18882 (ne (symbol_ref "optimize_size")
18883 (const_int 0))
18884 (const_string "V4SF")
18885 (const_string "TI"))
18886 (eq_attr "alternative" "2")
18887 (if_then_else
18888 (ne (symbol_ref "optimize_size")
18889 (const_int 0))
18890 (const_string "V4SF")
18891 (const_string "TI"))]
18892 (const_string "TI")))])
18893
18894 (define_insn "*movti_rex64"
18895 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
18896 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
18897 "TARGET_64BIT
18898 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18899 {
18900 switch (which_alternative)
18901 {
18902 case 0:
18903 case 1:
18904 return "#";
18905 case 2:
18906 if (get_attr_mode (insn) == MODE_V4SF)
18907 return "xorps\t%0, %0";
18908 else
18909 return "pxor\t%0, %0";
18910 case 3:
18911 case 4:
18912 if (get_attr_mode (insn) == MODE_V4SF)
18913 return "movaps\t{%1, %0|%0, %1}";
18914 else
18915 return "movdqa\t{%1, %0|%0, %1}";
18916 default:
18917 abort ();
18918 }
18919 }
18920 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18921 (set (attr "mode")
18922 (cond [(eq_attr "alternative" "2,3")
18923 (if_then_else
18924 (ne (symbol_ref "optimize_size")
18925 (const_int 0))
18926 (const_string "V4SF")
18927 (const_string "TI"))
18928 (eq_attr "alternative" "4")
18929 (if_then_else
18930 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18931 (const_int 0))
18932 (ne (symbol_ref "optimize_size")
18933 (const_int 0)))
18934 (const_string "V4SF")
18935 (const_string "TI"))]
18936 (const_string "DI")))])
18937
18938 (define_insn "*movtf_rex64"
18939 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
18940 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
18941 "TARGET_64BIT
18942 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18943 {
18944 switch (which_alternative)
18945 {
18946 case 0:
18947 case 1:
18948 return "#";
18949 case 2:
18950 if (get_attr_mode (insn) == MODE_V4SF)
18951 return "xorps\t%0, %0";
18952 else
18953 return "pxor\t%0, %0";
18954 case 3:
18955 case 4:
18956 if (get_attr_mode (insn) == MODE_V4SF)
18957 return "movaps\t{%1, %0|%0, %1}";
18958 else
18959 return "movdqa\t{%1, %0|%0, %1}";
18960 default:
18961 abort ();
18962 }
18963 }
18964 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18965 (set (attr "mode")
18966 (cond [(eq_attr "alternative" "2,3")
18967 (if_then_else
18968 (ne (symbol_ref "optimize_size")
18969 (const_int 0))
18970 (const_string "V4SF")
18971 (const_string "TI"))
18972 (eq_attr "alternative" "4")
18973 (if_then_else
18974 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18975 (const_int 0))
18976 (ne (symbol_ref "optimize_size")
18977 (const_int 0)))
18978 (const_string "V4SF")
18979 (const_string "TI"))]
18980 (const_string "DI")))])
18981
18982 (define_split
18983 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18984 (match_operand:TI 1 "general_operand" ""))]
18985 "reload_completed && !SSE_REG_P (operands[0])
18986 && !SSE_REG_P (operands[1])"
18987 [(const_int 0)]
18988 "ix86_split_long_move (operands); DONE;")
18989
18990 (define_split
18991 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18992 (match_operand:TF 1 "general_operand" ""))]
18993 "reload_completed && !SSE_REG_P (operands[0])
18994 && !SSE_REG_P (operands[1])"
18995 [(const_int 0)]
18996 "ix86_split_long_move (operands); DONE;")
18997
18998 ;; These two patterns are useful for specifying exactly whether to use
18999 ;; movaps or movups
19000 (define_expand "sse_movaps"
19001 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19002 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19003 UNSPEC_MOVA))]
19004 "TARGET_SSE"
19005 {
19006 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19007 {
19008 rtx tmp = gen_reg_rtx (V4SFmode);
19009 emit_insn (gen_sse_movaps (tmp, operands[1]));
19010 emit_move_insn (operands[0], tmp);
19011 DONE;
19012 }
19013 })
19014
19015 (define_insn "*sse_movaps_1"
19016 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19017 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19018 UNSPEC_MOVA))]
19019 "TARGET_SSE
19020 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19021 "movaps\t{%1, %0|%0, %1}"
19022 [(set_attr "type" "ssemov,ssemov")
19023 (set_attr "mode" "V4SF")])
19024
19025 (define_expand "sse_movups"
19026 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19027 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19028 UNSPEC_MOVU))]
19029 "TARGET_SSE"
19030 {
19031 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19032 {
19033 rtx tmp = gen_reg_rtx (V4SFmode);
19034 emit_insn (gen_sse_movups (tmp, operands[1]));
19035 emit_move_insn (operands[0], tmp);
19036 DONE;
19037 }
19038 })
19039
19040 (define_insn "*sse_movups_1"
19041 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19042 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19043 UNSPEC_MOVU))]
19044 "TARGET_SSE
19045 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19046 "movups\t{%1, %0|%0, %1}"
19047 [(set_attr "type" "ssecvt,ssecvt")
19048 (set_attr "mode" "V4SF")])
19049
19050 ;; SSE Strange Moves.
19051
19052 (define_insn "sse_movmskps"
19053 [(set (match_operand:SI 0 "register_operand" "=r")
19054 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19055 UNSPEC_MOVMSK))]
19056 "TARGET_SSE"
19057 "movmskps\t{%1, %0|%0, %1}"
19058 [(set_attr "type" "ssecvt")
19059 (set_attr "mode" "V4SF")])
19060
19061 (define_insn "mmx_pmovmskb"
19062 [(set (match_operand:SI 0 "register_operand" "=r")
19063 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19064 UNSPEC_MOVMSK))]
19065 "TARGET_SSE || TARGET_3DNOW_A"
19066 "pmovmskb\t{%1, %0|%0, %1}"
19067 [(set_attr "type" "ssecvt")
19068 (set_attr "mode" "V4SF")])
19069
19070
19071 (define_insn "mmx_maskmovq"
19072 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19073 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19074 (match_operand:V8QI 2 "register_operand" "y")]
19075 UNSPEC_MASKMOV))]
19076 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19077 ;; @@@ check ordering of operands in intel/nonintel syntax
19078 "maskmovq\t{%2, %1|%1, %2}"
19079 [(set_attr "type" "mmxcvt")
19080 (set_attr "mode" "DI")])
19081
19082 (define_insn "mmx_maskmovq_rex"
19083 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19084 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19085 (match_operand:V8QI 2 "register_operand" "y")]
19086 UNSPEC_MASKMOV))]
19087 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19088 ;; @@@ check ordering of operands in intel/nonintel syntax
19089 "maskmovq\t{%2, %1|%1, %2}"
19090 [(set_attr "type" "mmxcvt")
19091 (set_attr "mode" "DI")])
19092
19093 (define_insn "sse_movntv4sf"
19094 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19095 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19096 UNSPEC_MOVNT))]
19097 "TARGET_SSE"
19098 "movntps\t{%1, %0|%0, %1}"
19099 [(set_attr "type" "ssemov")
19100 (set_attr "mode" "V4SF")])
19101
19102 (define_insn "sse_movntdi"
19103 [(set (match_operand:DI 0 "memory_operand" "=m")
19104 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19105 UNSPEC_MOVNT))]
19106 "TARGET_SSE || TARGET_3DNOW_A"
19107 "movntq\t{%1, %0|%0, %1}"
19108 [(set_attr "type" "mmxmov")
19109 (set_attr "mode" "DI")])
19110
19111 (define_insn "sse_movhlps"
19112 [(set (match_operand:V4SF 0 "register_operand" "=x")
19113 (vec_merge:V4SF
19114 (match_operand:V4SF 1 "register_operand" "0")
19115 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19116 (parallel [(const_int 2)
19117 (const_int 3)
19118 (const_int 0)
19119 (const_int 1)]))
19120 (const_int 3)))]
19121 "TARGET_SSE"
19122 "movhlps\t{%2, %0|%0, %2}"
19123 [(set_attr "type" "ssecvt")
19124 (set_attr "mode" "V4SF")])
19125
19126 (define_insn "sse_movlhps"
19127 [(set (match_operand:V4SF 0 "register_operand" "=x")
19128 (vec_merge:V4SF
19129 (match_operand:V4SF 1 "register_operand" "0")
19130 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19131 (parallel [(const_int 2)
19132 (const_int 3)
19133 (const_int 0)
19134 (const_int 1)]))
19135 (const_int 12)))]
19136 "TARGET_SSE"
19137 "movlhps\t{%2, %0|%0, %2}"
19138 [(set_attr "type" "ssecvt")
19139 (set_attr "mode" "V4SF")])
19140
19141 (define_insn "sse_movhps"
19142 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19143 (vec_merge:V4SF
19144 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19145 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19146 (const_int 12)))]
19147 "TARGET_SSE
19148 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19149 "movhps\t{%2, %0|%0, %2}"
19150 [(set_attr "type" "ssecvt")
19151 (set_attr "mode" "V4SF")])
19152
19153 (define_insn "sse_movlps"
19154 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19155 (vec_merge:V4SF
19156 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19157 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19158 (const_int 3)))]
19159 "TARGET_SSE
19160 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19161 "movlps\t{%2, %0|%0, %2}"
19162 [(set_attr "type" "ssecvt")
19163 (set_attr "mode" "V4SF")])
19164
19165 (define_expand "sse_loadss"
19166 [(match_operand:V4SF 0 "register_operand" "")
19167 (match_operand:SF 1 "memory_operand" "")]
19168 "TARGET_SSE"
19169 {
19170 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19171 CONST0_RTX (V4SFmode)));
19172 DONE;
19173 })
19174
19175 (define_insn "sse_loadss_1"
19176 [(set (match_operand:V4SF 0 "register_operand" "=x")
19177 (vec_merge:V4SF
19178 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19179 (match_operand:V4SF 2 "const0_operand" "X")
19180 (const_int 1)))]
19181 "TARGET_SSE"
19182 "movss\t{%1, %0|%0, %1}"
19183 [(set_attr "type" "ssemov")
19184 (set_attr "mode" "SF")])
19185
19186 (define_insn "sse_movss"
19187 [(set (match_operand:V4SF 0 "register_operand" "=x")
19188 (vec_merge:V4SF
19189 (match_operand:V4SF 1 "register_operand" "0")
19190 (match_operand:V4SF 2 "register_operand" "x")
19191 (const_int 1)))]
19192 "TARGET_SSE"
19193 "movss\t{%2, %0|%0, %2}"
19194 [(set_attr "type" "ssemov")
19195 (set_attr "mode" "SF")])
19196
19197 (define_insn "sse_storess"
19198 [(set (match_operand:SF 0 "memory_operand" "=m")
19199 (vec_select:SF
19200 (match_operand:V4SF 1 "register_operand" "x")
19201 (parallel [(const_int 0)])))]
19202 "TARGET_SSE"
19203 "movss\t{%1, %0|%0, %1}"
19204 [(set_attr "type" "ssemov")
19205 (set_attr "mode" "SF")])
19206
19207 (define_insn "sse_shufps"
19208 [(set (match_operand:V4SF 0 "register_operand" "=x")
19209 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19210 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19211 (match_operand:SI 3 "immediate_operand" "i")]
19212 UNSPEC_SHUFFLE))]
19213 "TARGET_SSE"
19214 ;; @@@ check operand order for intel/nonintel syntax
19215 "shufps\t{%3, %2, %0|%0, %2, %3}"
19216 [(set_attr "type" "ssecvt")
19217 (set_attr "mode" "V4SF")])
19218
19219
19220 ;; SSE arithmetic
19221
19222 (define_insn "addv4sf3"
19223 [(set (match_operand:V4SF 0 "register_operand" "=x")
19224 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19225 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19226 "TARGET_SSE"
19227 "addps\t{%2, %0|%0, %2}"
19228 [(set_attr "type" "sseadd")
19229 (set_attr "mode" "V4SF")])
19230
19231 (define_insn "vmaddv4sf3"
19232 [(set (match_operand:V4SF 0 "register_operand" "=x")
19233 (vec_merge:V4SF
19234 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19235 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19236 (match_dup 1)
19237 (const_int 1)))]
19238 "TARGET_SSE"
19239 "addss\t{%2, %0|%0, %2}"
19240 [(set_attr "type" "sseadd")
19241 (set_attr "mode" "SF")])
19242
19243 (define_insn "subv4sf3"
19244 [(set (match_operand:V4SF 0 "register_operand" "=x")
19245 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19246 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19247 "TARGET_SSE"
19248 "subps\t{%2, %0|%0, %2}"
19249 [(set_attr "type" "sseadd")
19250 (set_attr "mode" "V4SF")])
19251
19252 (define_insn "vmsubv4sf3"
19253 [(set (match_operand:V4SF 0 "register_operand" "=x")
19254 (vec_merge:V4SF
19255 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19256 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19257 (match_dup 1)
19258 (const_int 1)))]
19259 "TARGET_SSE"
19260 "subss\t{%2, %0|%0, %2}"
19261 [(set_attr "type" "sseadd")
19262 (set_attr "mode" "SF")])
19263
19264 (define_insn "mulv4sf3"
19265 [(set (match_operand:V4SF 0 "register_operand" "=x")
19266 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19267 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19268 "TARGET_SSE"
19269 "mulps\t{%2, %0|%0, %2}"
19270 [(set_attr "type" "ssemul")
19271 (set_attr "mode" "V4SF")])
19272
19273 (define_insn "vmmulv4sf3"
19274 [(set (match_operand:V4SF 0 "register_operand" "=x")
19275 (vec_merge:V4SF
19276 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19277 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19278 (match_dup 1)
19279 (const_int 1)))]
19280 "TARGET_SSE"
19281 "mulss\t{%2, %0|%0, %2}"
19282 [(set_attr "type" "ssemul")
19283 (set_attr "mode" "SF")])
19284
19285 (define_insn "divv4sf3"
19286 [(set (match_operand:V4SF 0 "register_operand" "=x")
19287 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19288 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19289 "TARGET_SSE"
19290 "divps\t{%2, %0|%0, %2}"
19291 [(set_attr "type" "ssediv")
19292 (set_attr "mode" "V4SF")])
19293
19294 (define_insn "vmdivv4sf3"
19295 [(set (match_operand:V4SF 0 "register_operand" "=x")
19296 (vec_merge:V4SF
19297 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19298 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19299 (match_dup 1)
19300 (const_int 1)))]
19301 "TARGET_SSE"
19302 "divss\t{%2, %0|%0, %2}"
19303 [(set_attr "type" "ssediv")
19304 (set_attr "mode" "SF")])
19305
19306
19307 ;; SSE square root/reciprocal
19308
19309 (define_insn "rcpv4sf2"
19310 [(set (match_operand:V4SF 0 "register_operand" "=x")
19311 (unspec:V4SF
19312 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19313 "TARGET_SSE"
19314 "rcpps\t{%1, %0|%0, %1}"
19315 [(set_attr "type" "sse")
19316 (set_attr "mode" "V4SF")])
19317
19318 (define_insn "vmrcpv4sf2"
19319 [(set (match_operand:V4SF 0 "register_operand" "=x")
19320 (vec_merge:V4SF
19321 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19322 UNSPEC_RCP)
19323 (match_operand:V4SF 2 "register_operand" "0")
19324 (const_int 1)))]
19325 "TARGET_SSE"
19326 "rcpss\t{%1, %0|%0, %1}"
19327 [(set_attr "type" "sse")
19328 (set_attr "mode" "SF")])
19329
19330 (define_insn "rsqrtv4sf2"
19331 [(set (match_operand:V4SF 0 "register_operand" "=x")
19332 (unspec:V4SF
19333 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19334 "TARGET_SSE"
19335 "rsqrtps\t{%1, %0|%0, %1}"
19336 [(set_attr "type" "sse")
19337 (set_attr "mode" "V4SF")])
19338
19339 (define_insn "vmrsqrtv4sf2"
19340 [(set (match_operand:V4SF 0 "register_operand" "=x")
19341 (vec_merge:V4SF
19342 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19343 UNSPEC_RSQRT)
19344 (match_operand:V4SF 2 "register_operand" "0")
19345 (const_int 1)))]
19346 "TARGET_SSE"
19347 "rsqrtss\t{%1, %0|%0, %1}"
19348 [(set_attr "type" "sse")
19349 (set_attr "mode" "SF")])
19350
19351 (define_insn "sqrtv4sf2"
19352 [(set (match_operand:V4SF 0 "register_operand" "=x")
19353 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19354 "TARGET_SSE"
19355 "sqrtps\t{%1, %0|%0, %1}"
19356 [(set_attr "type" "sse")
19357 (set_attr "mode" "V4SF")])
19358
19359 (define_insn "vmsqrtv4sf2"
19360 [(set (match_operand:V4SF 0 "register_operand" "=x")
19361 (vec_merge:V4SF
19362 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19363 (match_operand:V4SF 2 "register_operand" "0")
19364 (const_int 1)))]
19365 "TARGET_SSE"
19366 "sqrtss\t{%1, %0|%0, %1}"
19367 [(set_attr "type" "sse")
19368 (set_attr "mode" "SF")])
19369
19370 ;; SSE logical operations.
19371
19372 ;; SSE defines logical operations on floating point values. This brings
19373 ;; interesting challenge to RTL representation where logicals are only valid
19374 ;; on integral types. We deal with this by representing the floating point
19375 ;; logical as logical on arguments casted to TImode as this is what hardware
19376 ;; really does. Unfortunately hardware requires the type information to be
19377 ;; present and thus we must avoid subregs from being simplified and eliminated
19378 ;; in later compilation phases.
19379 ;;
19380 ;; We have following variants from each instruction:
19381 ;; sse_andsf3 - the operation taking V4SF vector operands
19382 ;; and doing TImode cast on them
19383 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19384 ;; TImode, since backend insist on eliminating casts
19385 ;; on memory operands
19386 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19387 ;; We can not accept memory operand here as instruction reads
19388 ;; whole scalar. This is generated only post reload by GCC
19389 ;; scalar float operations that expands to logicals (fabs)
19390 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19391 ;; memory operand. Eventually combine can be able
19392 ;; to synthesize these using splitter.
19393 ;; sse2_anddf3, *sse2_anddf3_memory
19394 ;;
19395 ;;
19396 ;; These are not called andti3 etc. because we really really don't want
19397 ;; the compiler to widen DImode ands to TImode ands and then try to move
19398 ;; into DImode subregs of SSE registers, and them together, and move out
19399 ;; of DImode subregs again!
19400 ;; SSE1 single precision floating point logical operation
19401 (define_expand "sse_andv4sf3"
19402 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19403 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19404 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19405 "TARGET_SSE"
19406 "")
19407
19408 (define_insn "*sse_andv4sf3"
19409 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19410 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19411 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19412 "TARGET_SSE
19413 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19414 "andps\t{%2, %0|%0, %2}"
19415 [(set_attr "type" "sselog")
19416 (set_attr "mode" "V4SF")])
19417
19418 (define_insn "*sse_andsf3"
19419 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19420 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19421 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19422 "TARGET_SSE
19423 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19424 "andps\t{%2, %0|%0, %2}"
19425 [(set_attr "type" "sselog")
19426 (set_attr "mode" "V4SF")])
19427
19428 (define_expand "sse_nandv4sf3"
19429 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19430 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19431 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19432 "TARGET_SSE"
19433 "")
19434
19435 (define_insn "*sse_nandv4sf3"
19436 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19437 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19438 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19439 "TARGET_SSE"
19440 "andnps\t{%2, %0|%0, %2}"
19441 [(set_attr "type" "sselog")
19442 (set_attr "mode" "V4SF")])
19443
19444 (define_insn "*sse_nandsf3"
19445 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19446 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19447 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19448 "TARGET_SSE"
19449 "andnps\t{%2, %0|%0, %2}"
19450 [(set_attr "type" "sselog")
19451 (set_attr "mode" "V4SF")])
19452
19453 (define_expand "sse_iorv4sf3"
19454 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19455 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19456 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19457 "TARGET_SSE"
19458 "")
19459
19460 (define_insn "*sse_iorv4sf3"
19461 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19462 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19463 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19464 "TARGET_SSE
19465 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19466 "orps\t{%2, %0|%0, %2}"
19467 [(set_attr "type" "sselog")
19468 (set_attr "mode" "V4SF")])
19469
19470 (define_insn "*sse_iorsf3"
19471 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19472 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19473 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19474 "TARGET_SSE
19475 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19476 "orps\t{%2, %0|%0, %2}"
19477 [(set_attr "type" "sselog")
19478 (set_attr "mode" "V4SF")])
19479
19480 (define_expand "sse_xorv4sf3"
19481 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19482 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19483 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19484 "TARGET_SSE
19485 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19486 "")
19487
19488 (define_insn "*sse_xorv4sf3"
19489 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19490 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19491 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19492 "TARGET_SSE
19493 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19494 "xorps\t{%2, %0|%0, %2}"
19495 [(set_attr "type" "sselog")
19496 (set_attr "mode" "V4SF")])
19497
19498 (define_insn "*sse_xorsf3"
19499 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19500 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19501 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19502 "TARGET_SSE
19503 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19504 "xorps\t{%2, %0|%0, %2}"
19505 [(set_attr "type" "sselog")
19506 (set_attr "mode" "V4SF")])
19507
19508 ;; SSE2 double precision floating point logical operation
19509
19510 (define_expand "sse2_andv2df3"
19511 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19512 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19513 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19514 "TARGET_SSE2"
19515 "")
19516
19517 (define_insn "*sse2_andv2df3"
19518 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19519 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19520 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19521 "TARGET_SSE2
19522 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19523 "andpd\t{%2, %0|%0, %2}"
19524 [(set_attr "type" "sselog")
19525 (set_attr "mode" "V2DF")])
19526
19527 (define_insn "*sse2_andv2df3"
19528 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19529 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19530 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19531 "TARGET_SSE2
19532 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19533 "andpd\t{%2, %0|%0, %2}"
19534 [(set_attr "type" "sselog")
19535 (set_attr "mode" "V2DF")])
19536
19537 (define_expand "sse2_nandv2df3"
19538 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19539 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19540 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19541 "TARGET_SSE2"
19542 "")
19543
19544 (define_insn "*sse2_nandv2df3"
19545 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19546 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19547 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19548 "TARGET_SSE2"
19549 "andnpd\t{%2, %0|%0, %2}"
19550 [(set_attr "type" "sselog")
19551 (set_attr "mode" "V2DF")])
19552
19553 (define_insn "*sse_nandti3_df"
19554 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19555 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19556 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19557 "TARGET_SSE2"
19558 "andnpd\t{%2, %0|%0, %2}"
19559 [(set_attr "type" "sselog")
19560 (set_attr "mode" "V2DF")])
19561
19562 (define_expand "sse2_iorv2df3"
19563 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19564 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19565 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19566 "TARGET_SSE2"
19567 "")
19568
19569 (define_insn "*sse2_iorv2df3"
19570 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19571 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19572 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19573 "TARGET_SSE2
19574 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19575 "orpd\t{%2, %0|%0, %2}"
19576 [(set_attr "type" "sselog")
19577 (set_attr "mode" "V2DF")])
19578
19579 (define_insn "*sse2_iordf3"
19580 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19581 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19582 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19583 "TARGET_SSE2
19584 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19585 "orpd\t{%2, %0|%0, %2}"
19586 [(set_attr "type" "sselog")
19587 (set_attr "mode" "V2DF")])
19588
19589 (define_expand "sse2_xorv2df3"
19590 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19591 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19592 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19593 "TARGET_SSE2"
19594 "")
19595
19596 (define_insn "*sse2_xorv2df3"
19597 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19598 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19599 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19600 "TARGET_SSE2
19601 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19602 "xorpd\t{%2, %0|%0, %2}"
19603 [(set_attr "type" "sselog")
19604 (set_attr "mode" "V2DF")])
19605
19606 (define_insn "*sse2_xordf3"
19607 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19608 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19609 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19610 "TARGET_SSE2
19611 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19612 "xorpd\t{%2, %0|%0, %2}"
19613 [(set_attr "type" "sselog")
19614 (set_attr "mode" "V2DF")])
19615
19616 ;; SSE2 integral logicals. These patterns must always come after floating
19617 ;; point ones since we don't want compiler to use integer opcodes on floating
19618 ;; point SSE values to avoid matching of subregs in the match_operand.
19619 (define_insn "*sse2_andti3"
19620 [(set (match_operand:TI 0 "register_operand" "=x")
19621 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19622 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19623 "TARGET_SSE2
19624 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19625 "pand\t{%2, %0|%0, %2}"
19626 [(set_attr "type" "sselog")
19627 (set_attr "mode" "TI")])
19628
19629 (define_insn "sse2_andv2di3"
19630 [(set (match_operand:V2DI 0 "register_operand" "=x")
19631 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19632 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19633 "TARGET_SSE2
19634 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19635 "pand\t{%2, %0|%0, %2}"
19636 [(set_attr "type" "sselog")
19637 (set_attr "mode" "TI")])
19638
19639 (define_insn "*sse2_nandti3"
19640 [(set (match_operand:TI 0 "register_operand" "=x")
19641 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19642 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19643 "TARGET_SSE2"
19644 "pandn\t{%2, %0|%0, %2}"
19645 [(set_attr "type" "sselog")
19646 (set_attr "mode" "TI")])
19647
19648 (define_insn "sse2_nandv2di3"
19649 [(set (match_operand:V2DI 0 "register_operand" "=x")
19650 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19651 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19652 "TARGET_SSE2
19653 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19654 "pandn\t{%2, %0|%0, %2}"
19655 [(set_attr "type" "sselog")
19656 (set_attr "mode" "TI")])
19657
19658 (define_insn "*sse2_iorti3"
19659 [(set (match_operand:TI 0 "register_operand" "=x")
19660 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19661 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19662 "TARGET_SSE2
19663 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19664 "por\t{%2, %0|%0, %2}"
19665 [(set_attr "type" "sselog")
19666 (set_attr "mode" "TI")])
19667
19668 (define_insn "sse2_iorv2di3"
19669 [(set (match_operand:V2DI 0 "register_operand" "=x")
19670 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19671 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19672 "TARGET_SSE2
19673 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19674 "por\t{%2, %0|%0, %2}"
19675 [(set_attr "type" "sselog")
19676 (set_attr "mode" "TI")])
19677
19678 (define_insn "*sse2_xorti3"
19679 [(set (match_operand:TI 0 "register_operand" "=x")
19680 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19681 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19682 "TARGET_SSE2
19683 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19684 "pxor\t{%2, %0|%0, %2}"
19685 [(set_attr "type" "sselog")
19686 (set_attr "mode" "TI")])
19687
19688 (define_insn "sse2_xorv2di3"
19689 [(set (match_operand:V2DI 0 "register_operand" "=x")
19690 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19691 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19692 "TARGET_SSE2
19693 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19694 "pxor\t{%2, %0|%0, %2}"
19695 [(set_attr "type" "sselog")
19696 (set_attr "mode" "TI")])
19697
19698 ;; Use xor, but don't show input operands so they aren't live before
19699 ;; this insn.
19700 (define_insn "sse_clrv4sf"
19701 [(set (match_operand:V4SF 0 "register_operand" "=x")
19702 (match_operand:V4SF 1 "const0_operand" "X"))]
19703 "TARGET_SSE"
19704 {
19705 if (get_attr_mode (insn) == MODE_TI)
19706 return "pxor\t{%0, %0|%0, %0}";
19707 else
19708 return "xorps\t{%0, %0|%0, %0}";
19709 }
19710 [(set_attr "type" "sselog")
19711 (set_attr "memory" "none")
19712 (set (attr "mode")
19713 (if_then_else
19714 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19715 (const_int 0))
19716 (ne (symbol_ref "TARGET_SSE2")
19717 (const_int 0)))
19718 (eq (symbol_ref "optimize_size")
19719 (const_int 0)))
19720 (const_string "TI")
19721 (const_string "V4SF")))])
19722
19723 ;; Use xor, but don't show input operands so they aren't live before
19724 ;; this insn.
19725 (define_insn "sse_clrv2df"
19726 [(set (match_operand:V2DF 0 "register_operand" "=x")
19727 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19728 "TARGET_SSE2"
19729 "xorpd\t{%0, %0|%0, %0}"
19730 [(set_attr "type" "sselog")
19731 (set_attr "memory" "none")
19732 (set_attr "mode" "V4SF")])
19733
19734 ;; SSE mask-generating compares
19735
19736 (define_insn "maskcmpv4sf3"
19737 [(set (match_operand:V4SI 0 "register_operand" "=x")
19738 (match_operator:V4SI 3 "sse_comparison_operator"
19739 [(match_operand:V4SF 1 "register_operand" "0")
19740 (match_operand:V4SF 2 "register_operand" "x")]))]
19741 "TARGET_SSE"
19742 "cmp%D3ps\t{%2, %0|%0, %2}"
19743 [(set_attr "type" "ssecmp")
19744 (set_attr "mode" "V4SF")])
19745
19746 (define_insn "maskncmpv4sf3"
19747 [(set (match_operand:V4SI 0 "register_operand" "=x")
19748 (not:V4SI
19749 (match_operator:V4SI 3 "sse_comparison_operator"
19750 [(match_operand:V4SF 1 "register_operand" "0")
19751 (match_operand:V4SF 2 "register_operand" "x")])))]
19752 "TARGET_SSE"
19753 {
19754 if (GET_CODE (operands[3]) == UNORDERED)
19755 return "cmpordps\t{%2, %0|%0, %2}";
19756 else
19757 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19758 }
19759 [(set_attr "type" "ssecmp")
19760 (set_attr "mode" "V4SF")])
19761
19762 (define_insn "vmmaskcmpv4sf3"
19763 [(set (match_operand:V4SI 0 "register_operand" "=x")
19764 (vec_merge:V4SI
19765 (match_operator:V4SI 3 "sse_comparison_operator"
19766 [(match_operand:V4SF 1 "register_operand" "0")
19767 (match_operand:V4SF 2 "register_operand" "x")])
19768 (subreg:V4SI (match_dup 1) 0)
19769 (const_int 1)))]
19770 "TARGET_SSE"
19771 "cmp%D3ss\t{%2, %0|%0, %2}"
19772 [(set_attr "type" "ssecmp")
19773 (set_attr "mode" "SF")])
19774
19775 (define_insn "vmmaskncmpv4sf3"
19776 [(set (match_operand:V4SI 0 "register_operand" "=x")
19777 (vec_merge:V4SI
19778 (not:V4SI
19779 (match_operator:V4SI 3 "sse_comparison_operator"
19780 [(match_operand:V4SF 1 "register_operand" "0")
19781 (match_operand:V4SF 2 "register_operand" "x")]))
19782 (subreg:V4SI (match_dup 1) 0)
19783 (const_int 1)))]
19784 "TARGET_SSE"
19785 {
19786 if (GET_CODE (operands[3]) == UNORDERED)
19787 return "cmpordss\t{%2, %0|%0, %2}";
19788 else
19789 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19790 }
19791 [(set_attr "type" "ssecmp")
19792 (set_attr "mode" "SF")])
19793
19794 (define_insn "sse_comi"
19795 [(set (reg:CCFP 17)
19796 (compare:CCFP (vec_select:SF
19797 (match_operand:V4SF 0 "register_operand" "x")
19798 (parallel [(const_int 0)]))
19799 (vec_select:SF
19800 (match_operand:V4SF 1 "register_operand" "x")
19801 (parallel [(const_int 0)]))))]
19802 "TARGET_SSE"
19803 "comiss\t{%1, %0|%0, %1}"
19804 [(set_attr "type" "ssecomi")
19805 (set_attr "mode" "SF")])
19806
19807 (define_insn "sse_ucomi"
19808 [(set (reg:CCFPU 17)
19809 (compare:CCFPU (vec_select:SF
19810 (match_operand:V4SF 0 "register_operand" "x")
19811 (parallel [(const_int 0)]))
19812 (vec_select:SF
19813 (match_operand:V4SF 1 "register_operand" "x")
19814 (parallel [(const_int 0)]))))]
19815 "TARGET_SSE"
19816 "ucomiss\t{%1, %0|%0, %1}"
19817 [(set_attr "type" "ssecomi")
19818 (set_attr "mode" "SF")])
19819
19820
19821 ;; SSE unpack
19822
19823 (define_insn "sse_unpckhps"
19824 [(set (match_operand:V4SF 0 "register_operand" "=x")
19825 (vec_merge:V4SF
19826 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19827 (parallel [(const_int 2)
19828 (const_int 0)
19829 (const_int 3)
19830 (const_int 1)]))
19831 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19832 (parallel [(const_int 0)
19833 (const_int 2)
19834 (const_int 1)
19835 (const_int 3)]))
19836 (const_int 5)))]
19837 "TARGET_SSE"
19838 "unpckhps\t{%2, %0|%0, %2}"
19839 [(set_attr "type" "ssecvt")
19840 (set_attr "mode" "V4SF")])
19841
19842 (define_insn "sse_unpcklps"
19843 [(set (match_operand:V4SF 0 "register_operand" "=x")
19844 (vec_merge:V4SF
19845 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19846 (parallel [(const_int 0)
19847 (const_int 2)
19848 (const_int 1)
19849 (const_int 3)]))
19850 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19851 (parallel [(const_int 2)
19852 (const_int 0)
19853 (const_int 3)
19854 (const_int 1)]))
19855 (const_int 5)))]
19856 "TARGET_SSE"
19857 "unpcklps\t{%2, %0|%0, %2}"
19858 [(set_attr "type" "ssecvt")
19859 (set_attr "mode" "V4SF")])
19860
19861
19862 ;; SSE min/max
19863
19864 (define_insn "smaxv4sf3"
19865 [(set (match_operand:V4SF 0 "register_operand" "=x")
19866 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19867 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19868 "TARGET_SSE"
19869 "maxps\t{%2, %0|%0, %2}"
19870 [(set_attr "type" "sse")
19871 (set_attr "mode" "V4SF")])
19872
19873 (define_insn "vmsmaxv4sf3"
19874 [(set (match_operand:V4SF 0 "register_operand" "=x")
19875 (vec_merge:V4SF
19876 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19877 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19878 (match_dup 1)
19879 (const_int 1)))]
19880 "TARGET_SSE"
19881 "maxss\t{%2, %0|%0, %2}"
19882 [(set_attr "type" "sse")
19883 (set_attr "mode" "SF")])
19884
19885 (define_insn "sminv4sf3"
19886 [(set (match_operand:V4SF 0 "register_operand" "=x")
19887 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19888 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19889 "TARGET_SSE"
19890 "minps\t{%2, %0|%0, %2}"
19891 [(set_attr "type" "sse")
19892 (set_attr "mode" "V4SF")])
19893
19894 (define_insn "vmsminv4sf3"
19895 [(set (match_operand:V4SF 0 "register_operand" "=x")
19896 (vec_merge:V4SF
19897 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19898 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19899 (match_dup 1)
19900 (const_int 1)))]
19901 "TARGET_SSE"
19902 "minss\t{%2, %0|%0, %2}"
19903 [(set_attr "type" "sse")
19904 (set_attr "mode" "SF")])
19905
19906 ;; SSE <-> integer/MMX conversions
19907
19908 (define_insn "cvtpi2ps"
19909 [(set (match_operand:V4SF 0 "register_operand" "=x")
19910 (vec_merge:V4SF
19911 (match_operand:V4SF 1 "register_operand" "0")
19912 (vec_duplicate:V4SF
19913 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
19914 (const_int 12)))]
19915 "TARGET_SSE"
19916 "cvtpi2ps\t{%2, %0|%0, %2}"
19917 [(set_attr "type" "ssecvt")
19918 (set_attr "mode" "V4SF")])
19919
19920 (define_insn "cvtps2pi"
19921 [(set (match_operand:V2SI 0 "register_operand" "=y")
19922 (vec_select:V2SI
19923 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19924 (parallel [(const_int 0) (const_int 1)])))]
19925 "TARGET_SSE"
19926 "cvtps2pi\t{%1, %0|%0, %1}"
19927 [(set_attr "type" "ssecvt")
19928 (set_attr "mode" "V4SF")])
19929
19930 (define_insn "cvttps2pi"
19931 [(set (match_operand:V2SI 0 "register_operand" "=y")
19932 (vec_select:V2SI
19933 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19934 UNSPEC_FIX)
19935 (parallel [(const_int 0) (const_int 1)])))]
19936 "TARGET_SSE"
19937 "cvttps2pi\t{%1, %0|%0, %1}"
19938 [(set_attr "type" "ssecvt")
19939 (set_attr "mode" "SF")])
19940
19941 (define_insn "cvtsi2ss"
19942 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
19943 (vec_merge:V4SF
19944 (match_operand:V4SF 1 "register_operand" "0,0")
19945 (vec_duplicate:V4SF
19946 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
19947 (const_int 14)))]
19948 "TARGET_SSE"
19949 "cvtsi2ss\t{%2, %0|%0, %2}"
19950 [(set_attr "type" "sseicvt")
19951 (set_attr "athlon_decode" "vector,double")
19952 (set_attr "mode" "SF")])
19953
19954 (define_insn "cvtsi2ssq"
19955 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
19956 (vec_merge:V4SF
19957 (match_operand:V4SF 1 "register_operand" "0,0")
19958 (vec_duplicate:V4SF
19959 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
19960 (const_int 14)))]
19961 "TARGET_SSE && TARGET_64BIT"
19962 "cvtsi2ssq\t{%2, %0|%0, %2}"
19963 [(set_attr "type" "sseicvt")
19964 (set_attr "athlon_decode" "vector,double")
19965 (set_attr "mode" "SF")])
19966
19967 (define_insn "cvtss2si"
19968 [(set (match_operand:SI 0 "register_operand" "=r,r")
19969 (vec_select:SI
19970 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
19971 (parallel [(const_int 0)])))]
19972 "TARGET_SSE"
19973 "cvtss2si\t{%1, %0|%0, %1}"
19974 [(set_attr "type" "sseicvt")
19975 (set_attr "athlon_decode" "double,vector")
19976 (set_attr "mode" "SI")])
19977
19978 (define_insn "cvtss2siq"
19979 [(set (match_operand:DI 0 "register_operand" "=r,r")
19980 (vec_select:DI
19981 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
19982 (parallel [(const_int 0)])))]
19983 "TARGET_SSE"
19984 "cvtss2siq\t{%1, %0|%0, %1}"
19985 [(set_attr "type" "sseicvt")
19986 (set_attr "athlon_decode" "double,vector")
19987 (set_attr "mode" "DI")])
19988
19989 (define_insn "cvttss2si"
19990 [(set (match_operand:SI 0 "register_operand" "=r,r")
19991 (vec_select:SI
19992 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
19993 UNSPEC_FIX)
19994 (parallel [(const_int 0)])))]
19995 "TARGET_SSE"
19996 "cvttss2si\t{%1, %0|%0, %1}"
19997 [(set_attr "type" "sseicvt")
19998 (set_attr "mode" "SF")
19999 (set_attr "athlon_decode" "double,vector")])
20000
20001 (define_insn "cvttss2siq"
20002 [(set (match_operand:DI 0 "register_operand" "=r,r")
20003 (vec_select:DI
20004 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20005 UNSPEC_FIX)
20006 (parallel [(const_int 0)])))]
20007 "TARGET_SSE && TARGET_64BIT"
20008 "cvttss2siq\t{%1, %0|%0, %1}"
20009 [(set_attr "type" "sseicvt")
20010 (set_attr "mode" "SF")
20011 (set_attr "athlon_decode" "double,vector")])
20012
20013
20014 ;; MMX insns
20015
20016 ;; MMX arithmetic
20017
20018 (define_insn "addv8qi3"
20019 [(set (match_operand:V8QI 0 "register_operand" "=y")
20020 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20021 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20022 "TARGET_MMX"
20023 "paddb\t{%2, %0|%0, %2}"
20024 [(set_attr "type" "mmxadd")
20025 (set_attr "mode" "DI")])
20026
20027 (define_insn "addv4hi3"
20028 [(set (match_operand:V4HI 0 "register_operand" "=y")
20029 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20030 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20031 "TARGET_MMX"
20032 "paddw\t{%2, %0|%0, %2}"
20033 [(set_attr "type" "mmxadd")
20034 (set_attr "mode" "DI")])
20035
20036 (define_insn "addv2si3"
20037 [(set (match_operand:V2SI 0 "register_operand" "=y")
20038 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20039 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20040 "TARGET_MMX"
20041 "paddd\t{%2, %0|%0, %2}"
20042 [(set_attr "type" "mmxadd")
20043 (set_attr "mode" "DI")])
20044
20045 (define_insn "mmx_adddi3"
20046 [(set (match_operand:DI 0 "register_operand" "=y")
20047 (unspec:DI
20048 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20049 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20050 UNSPEC_NOP))]
20051 "TARGET_MMX"
20052 "paddq\t{%2, %0|%0, %2}"
20053 [(set_attr "type" "mmxadd")
20054 (set_attr "mode" "DI")])
20055
20056 (define_insn "ssaddv8qi3"
20057 [(set (match_operand:V8QI 0 "register_operand" "=y")
20058 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20059 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20060 "TARGET_MMX"
20061 "paddsb\t{%2, %0|%0, %2}"
20062 [(set_attr "type" "mmxadd")
20063 (set_attr "mode" "DI")])
20064
20065 (define_insn "ssaddv4hi3"
20066 [(set (match_operand:V4HI 0 "register_operand" "=y")
20067 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20068 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20069 "TARGET_MMX"
20070 "paddsw\t{%2, %0|%0, %2}"
20071 [(set_attr "type" "mmxadd")
20072 (set_attr "mode" "DI")])
20073
20074 (define_insn "usaddv8qi3"
20075 [(set (match_operand:V8QI 0 "register_operand" "=y")
20076 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20077 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20078 "TARGET_MMX"
20079 "paddusb\t{%2, %0|%0, %2}"
20080 [(set_attr "type" "mmxadd")
20081 (set_attr "mode" "DI")])
20082
20083 (define_insn "usaddv4hi3"
20084 [(set (match_operand:V4HI 0 "register_operand" "=y")
20085 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20086 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20087 "TARGET_MMX"
20088 "paddusw\t{%2, %0|%0, %2}"
20089 [(set_attr "type" "mmxadd")
20090 (set_attr "mode" "DI")])
20091
20092 (define_insn "subv8qi3"
20093 [(set (match_operand:V8QI 0 "register_operand" "=y")
20094 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20095 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20096 "TARGET_MMX"
20097 "psubb\t{%2, %0|%0, %2}"
20098 [(set_attr "type" "mmxadd")
20099 (set_attr "mode" "DI")])
20100
20101 (define_insn "subv4hi3"
20102 [(set (match_operand:V4HI 0 "register_operand" "=y")
20103 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20104 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20105 "TARGET_MMX"
20106 "psubw\t{%2, %0|%0, %2}"
20107 [(set_attr "type" "mmxadd")
20108 (set_attr "mode" "DI")])
20109
20110 (define_insn "subv2si3"
20111 [(set (match_operand:V2SI 0 "register_operand" "=y")
20112 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20113 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20114 "TARGET_MMX"
20115 "psubd\t{%2, %0|%0, %2}"
20116 [(set_attr "type" "mmxadd")
20117 (set_attr "mode" "DI")])
20118
20119 (define_insn "mmx_subdi3"
20120 [(set (match_operand:DI 0 "register_operand" "=y")
20121 (unspec:DI
20122 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20123 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20124 UNSPEC_NOP))]
20125 "TARGET_MMX"
20126 "psubq\t{%2, %0|%0, %2}"
20127 [(set_attr "type" "mmxadd")
20128 (set_attr "mode" "DI")])
20129
20130 (define_insn "sssubv8qi3"
20131 [(set (match_operand:V8QI 0 "register_operand" "=y")
20132 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20133 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20134 "TARGET_MMX"
20135 "psubsb\t{%2, %0|%0, %2}"
20136 [(set_attr "type" "mmxadd")
20137 (set_attr "mode" "DI")])
20138
20139 (define_insn "sssubv4hi3"
20140 [(set (match_operand:V4HI 0 "register_operand" "=y")
20141 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20142 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20143 "TARGET_MMX"
20144 "psubsw\t{%2, %0|%0, %2}"
20145 [(set_attr "type" "mmxadd")
20146 (set_attr "mode" "DI")])
20147
20148 (define_insn "ussubv8qi3"
20149 [(set (match_operand:V8QI 0 "register_operand" "=y")
20150 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20151 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20152 "TARGET_MMX"
20153 "psubusb\t{%2, %0|%0, %2}"
20154 [(set_attr "type" "mmxadd")
20155 (set_attr "mode" "DI")])
20156
20157 (define_insn "ussubv4hi3"
20158 [(set (match_operand:V4HI 0 "register_operand" "=y")
20159 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20160 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20161 "TARGET_MMX"
20162 "psubusw\t{%2, %0|%0, %2}"
20163 [(set_attr "type" "mmxadd")
20164 (set_attr "mode" "DI")])
20165
20166 (define_insn "mulv4hi3"
20167 [(set (match_operand:V4HI 0 "register_operand" "=y")
20168 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20169 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20170 "TARGET_MMX"
20171 "pmullw\t{%2, %0|%0, %2}"
20172 [(set_attr "type" "mmxmul")
20173 (set_attr "mode" "DI")])
20174
20175 (define_insn "smulv4hi3_highpart"
20176 [(set (match_operand:V4HI 0 "register_operand" "=y")
20177 (truncate:V4HI
20178 (lshiftrt:V4SI
20179 (mult:V4SI (sign_extend:V4SI
20180 (match_operand:V4HI 1 "register_operand" "0"))
20181 (sign_extend:V4SI
20182 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20183 (const_int 16))))]
20184 "TARGET_MMX"
20185 "pmulhw\t{%2, %0|%0, %2}"
20186 [(set_attr "type" "mmxmul")
20187 (set_attr "mode" "DI")])
20188
20189 (define_insn "umulv4hi3_highpart"
20190 [(set (match_operand:V4HI 0 "register_operand" "=y")
20191 (truncate:V4HI
20192 (lshiftrt:V4SI
20193 (mult:V4SI (zero_extend:V4SI
20194 (match_operand:V4HI 1 "register_operand" "0"))
20195 (zero_extend:V4SI
20196 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20197 (const_int 16))))]
20198 "TARGET_SSE || TARGET_3DNOW_A"
20199 "pmulhuw\t{%2, %0|%0, %2}"
20200 [(set_attr "type" "mmxmul")
20201 (set_attr "mode" "DI")])
20202
20203 (define_insn "mmx_pmaddwd"
20204 [(set (match_operand:V2SI 0 "register_operand" "=y")
20205 (plus:V2SI
20206 (mult:V2SI
20207 (sign_extend:V2SI
20208 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20209 (parallel [(const_int 0) (const_int 2)])))
20210 (sign_extend:V2SI
20211 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20212 (parallel [(const_int 0) (const_int 2)]))))
20213 (mult:V2SI
20214 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20215 (parallel [(const_int 1)
20216 (const_int 3)])))
20217 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20218 (parallel [(const_int 1)
20219 (const_int 3)]))))))]
20220 "TARGET_MMX"
20221 "pmaddwd\t{%2, %0|%0, %2}"
20222 [(set_attr "type" "mmxmul")
20223 (set_attr "mode" "DI")])
20224
20225
20226 ;; MMX logical operations
20227 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20228 ;; normal code that also wants to use the FPU from getting broken.
20229 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20230 (define_insn "mmx_iordi3"
20231 [(set (match_operand:DI 0 "register_operand" "=y")
20232 (unspec:DI
20233 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20234 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20235 UNSPEC_NOP))]
20236 "TARGET_MMX"
20237 "por\t{%2, %0|%0, %2}"
20238 [(set_attr "type" "mmxadd")
20239 (set_attr "mode" "DI")])
20240
20241 (define_insn "mmx_xordi3"
20242 [(set (match_operand:DI 0 "register_operand" "=y")
20243 (unspec:DI
20244 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20245 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20246 UNSPEC_NOP))]
20247 "TARGET_MMX"
20248 "pxor\t{%2, %0|%0, %2}"
20249 [(set_attr "type" "mmxadd")
20250 (set_attr "mode" "DI")
20251 (set_attr "memory" "none")])
20252
20253 ;; Same as pxor, but don't show input operands so that we don't think
20254 ;; they are live.
20255 (define_insn "mmx_clrdi"
20256 [(set (match_operand:DI 0 "register_operand" "=y")
20257 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20258 "TARGET_MMX"
20259 "pxor\t{%0, %0|%0, %0}"
20260 [(set_attr "type" "mmxadd")
20261 (set_attr "mode" "DI")
20262 (set_attr "memory" "none")])
20263
20264 (define_insn "mmx_anddi3"
20265 [(set (match_operand:DI 0 "register_operand" "=y")
20266 (unspec:DI
20267 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20268 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20269 UNSPEC_NOP))]
20270 "TARGET_MMX"
20271 "pand\t{%2, %0|%0, %2}"
20272 [(set_attr "type" "mmxadd")
20273 (set_attr "mode" "DI")])
20274
20275 (define_insn "mmx_nanddi3"
20276 [(set (match_operand:DI 0 "register_operand" "=y")
20277 (unspec:DI
20278 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20279 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20280 UNSPEC_NOP))]
20281 "TARGET_MMX"
20282 "pandn\t{%2, %0|%0, %2}"
20283 [(set_attr "type" "mmxadd")
20284 (set_attr "mode" "DI")])
20285
20286
20287 ;; MMX unsigned averages/sum of absolute differences
20288
20289 (define_insn "mmx_uavgv8qi3"
20290 [(set (match_operand:V8QI 0 "register_operand" "=y")
20291 (ashiftrt:V8QI
20292 (plus:V8QI (plus:V8QI
20293 (match_operand:V8QI 1 "register_operand" "0")
20294 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20295 (const_vector:V8QI [(const_int 1)
20296 (const_int 1)
20297 (const_int 1)
20298 (const_int 1)
20299 (const_int 1)
20300 (const_int 1)
20301 (const_int 1)
20302 (const_int 1)]))
20303 (const_int 1)))]
20304 "TARGET_SSE || TARGET_3DNOW_A"
20305 "pavgb\t{%2, %0|%0, %2}"
20306 [(set_attr "type" "mmxshft")
20307 (set_attr "mode" "DI")])
20308
20309 (define_insn "mmx_uavgv4hi3"
20310 [(set (match_operand:V4HI 0 "register_operand" "=y")
20311 (ashiftrt:V4HI
20312 (plus:V4HI (plus:V4HI
20313 (match_operand:V4HI 1 "register_operand" "0")
20314 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20315 (const_vector:V4HI [(const_int 1)
20316 (const_int 1)
20317 (const_int 1)
20318 (const_int 1)]))
20319 (const_int 1)))]
20320 "TARGET_SSE || TARGET_3DNOW_A"
20321 "pavgw\t{%2, %0|%0, %2}"
20322 [(set_attr "type" "mmxshft")
20323 (set_attr "mode" "DI")])
20324
20325 (define_insn "mmx_psadbw"
20326 [(set (match_operand:DI 0 "register_operand" "=y")
20327 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20328 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20329 UNSPEC_PSADBW))]
20330 "TARGET_SSE || TARGET_3DNOW_A"
20331 "psadbw\t{%2, %0|%0, %2}"
20332 [(set_attr "type" "mmxshft")
20333 (set_attr "mode" "DI")])
20334
20335
20336 ;; MMX insert/extract/shuffle
20337
20338 (define_insn "mmx_pinsrw"
20339 [(set (match_operand:V4HI 0 "register_operand" "=y")
20340 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20341 (vec_duplicate:V4HI
20342 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20343 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20344 "TARGET_SSE || TARGET_3DNOW_A"
20345 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20346 [(set_attr "type" "mmxcvt")
20347 (set_attr "mode" "DI")])
20348
20349 (define_insn "mmx_pextrw"
20350 [(set (match_operand:SI 0 "register_operand" "=r")
20351 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20352 (parallel
20353 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20354 "TARGET_SSE || TARGET_3DNOW_A"
20355 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20356 [(set_attr "type" "mmxcvt")
20357 (set_attr "mode" "DI")])
20358
20359 (define_insn "mmx_pshufw"
20360 [(set (match_operand:V4HI 0 "register_operand" "=y")
20361 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20362 (match_operand:SI 2 "immediate_operand" "i")]
20363 UNSPEC_SHUFFLE))]
20364 "TARGET_SSE || TARGET_3DNOW_A"
20365 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20366 [(set_attr "type" "mmxcvt")
20367 (set_attr "mode" "DI")])
20368
20369
20370 ;; MMX mask-generating comparisons
20371
20372 (define_insn "eqv8qi3"
20373 [(set (match_operand:V8QI 0 "register_operand" "=y")
20374 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20375 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20376 "TARGET_MMX"
20377 "pcmpeqb\t{%2, %0|%0, %2}"
20378 [(set_attr "type" "mmxcmp")
20379 (set_attr "mode" "DI")])
20380
20381 (define_insn "eqv4hi3"
20382 [(set (match_operand:V4HI 0 "register_operand" "=y")
20383 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20384 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20385 "TARGET_MMX"
20386 "pcmpeqw\t{%2, %0|%0, %2}"
20387 [(set_attr "type" "mmxcmp")
20388 (set_attr "mode" "DI")])
20389
20390 (define_insn "eqv2si3"
20391 [(set (match_operand:V2SI 0 "register_operand" "=y")
20392 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20393 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20394 "TARGET_MMX"
20395 "pcmpeqd\t{%2, %0|%0, %2}"
20396 [(set_attr "type" "mmxcmp")
20397 (set_attr "mode" "DI")])
20398
20399 (define_insn "gtv8qi3"
20400 [(set (match_operand:V8QI 0 "register_operand" "=y")
20401 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20402 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20403 "TARGET_MMX"
20404 "pcmpgtb\t{%2, %0|%0, %2}"
20405 [(set_attr "type" "mmxcmp")
20406 (set_attr "mode" "DI")])
20407
20408 (define_insn "gtv4hi3"
20409 [(set (match_operand:V4HI 0 "register_operand" "=y")
20410 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20411 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20412 "TARGET_MMX"
20413 "pcmpgtw\t{%2, %0|%0, %2}"
20414 [(set_attr "type" "mmxcmp")
20415 (set_attr "mode" "DI")])
20416
20417 (define_insn "gtv2si3"
20418 [(set (match_operand:V2SI 0 "register_operand" "=y")
20419 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20420 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20421 "TARGET_MMX"
20422 "pcmpgtd\t{%2, %0|%0, %2}"
20423 [(set_attr "type" "mmxcmp")
20424 (set_attr "mode" "DI")])
20425
20426
20427 ;; MMX max/min insns
20428
20429 (define_insn "umaxv8qi3"
20430 [(set (match_operand:V8QI 0 "register_operand" "=y")
20431 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20432 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20433 "TARGET_SSE || TARGET_3DNOW_A"
20434 "pmaxub\t{%2, %0|%0, %2}"
20435 [(set_attr "type" "mmxadd")
20436 (set_attr "mode" "DI")])
20437
20438 (define_insn "smaxv4hi3"
20439 [(set (match_operand:V4HI 0 "register_operand" "=y")
20440 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20441 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20442 "TARGET_SSE || TARGET_3DNOW_A"
20443 "pmaxsw\t{%2, %0|%0, %2}"
20444 [(set_attr "type" "mmxadd")
20445 (set_attr "mode" "DI")])
20446
20447 (define_insn "uminv8qi3"
20448 [(set (match_operand:V8QI 0 "register_operand" "=y")
20449 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20450 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20451 "TARGET_SSE || TARGET_3DNOW_A"
20452 "pminub\t{%2, %0|%0, %2}"
20453 [(set_attr "type" "mmxadd")
20454 (set_attr "mode" "DI")])
20455
20456 (define_insn "sminv4hi3"
20457 [(set (match_operand:V4HI 0 "register_operand" "=y")
20458 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20459 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20460 "TARGET_SSE || TARGET_3DNOW_A"
20461 "pminsw\t{%2, %0|%0, %2}"
20462 [(set_attr "type" "mmxadd")
20463 (set_attr "mode" "DI")])
20464
20465
20466 ;; MMX shifts
20467
20468 (define_insn "ashrv4hi3"
20469 [(set (match_operand:V4HI 0 "register_operand" "=y")
20470 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20471 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20472 "TARGET_MMX"
20473 "psraw\t{%2, %0|%0, %2}"
20474 [(set_attr "type" "mmxshft")
20475 (set_attr "mode" "DI")])
20476
20477 (define_insn "ashrv2si3"
20478 [(set (match_operand:V2SI 0 "register_operand" "=y")
20479 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20480 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20481 "TARGET_MMX"
20482 "psrad\t{%2, %0|%0, %2}"
20483 [(set_attr "type" "mmxshft")
20484 (set_attr "mode" "DI")])
20485
20486 (define_insn "lshrv4hi3"
20487 [(set (match_operand:V4HI 0 "register_operand" "=y")
20488 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20489 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20490 "TARGET_MMX"
20491 "psrlw\t{%2, %0|%0, %2}"
20492 [(set_attr "type" "mmxshft")
20493 (set_attr "mode" "DI")])
20494
20495 (define_insn "lshrv2si3"
20496 [(set (match_operand:V2SI 0 "register_operand" "=y")
20497 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20498 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20499 "TARGET_MMX"
20500 "psrld\t{%2, %0|%0, %2}"
20501 [(set_attr "type" "mmxshft")
20502 (set_attr "mode" "DI")])
20503
20504 ;; See logical MMX insns.
20505 (define_insn "mmx_lshrdi3"
20506 [(set (match_operand:DI 0 "register_operand" "=y")
20507 (unspec:DI
20508 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20509 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20510 UNSPEC_NOP))]
20511 "TARGET_MMX"
20512 "psrlq\t{%2, %0|%0, %2}"
20513 [(set_attr "type" "mmxshft")
20514 (set_attr "mode" "DI")])
20515
20516 (define_insn "ashlv4hi3"
20517 [(set (match_operand:V4HI 0 "register_operand" "=y")
20518 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20519 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20520 "TARGET_MMX"
20521 "psllw\t{%2, %0|%0, %2}"
20522 [(set_attr "type" "mmxshft")
20523 (set_attr "mode" "DI")])
20524
20525 (define_insn "ashlv2si3"
20526 [(set (match_operand:V2SI 0 "register_operand" "=y")
20527 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20528 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20529 "TARGET_MMX"
20530 "pslld\t{%2, %0|%0, %2}"
20531 [(set_attr "type" "mmxshft")
20532 (set_attr "mode" "DI")])
20533
20534 ;; See logical MMX insns.
20535 (define_insn "mmx_ashldi3"
20536 [(set (match_operand:DI 0 "register_operand" "=y")
20537 (unspec:DI
20538 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20539 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20540 UNSPEC_NOP))]
20541 "TARGET_MMX"
20542 "psllq\t{%2, %0|%0, %2}"
20543 [(set_attr "type" "mmxshft")
20544 (set_attr "mode" "DI")])
20545
20546
20547 ;; MMX pack/unpack insns.
20548
20549 (define_insn "mmx_packsswb"
20550 [(set (match_operand:V8QI 0 "register_operand" "=y")
20551 (vec_concat:V8QI
20552 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20553 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20554 "TARGET_MMX"
20555 "packsswb\t{%2, %0|%0, %2}"
20556 [(set_attr "type" "mmxshft")
20557 (set_attr "mode" "DI")])
20558
20559 (define_insn "mmx_packssdw"
20560 [(set (match_operand:V4HI 0 "register_operand" "=y")
20561 (vec_concat:V4HI
20562 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20563 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20564 "TARGET_MMX"
20565 "packssdw\t{%2, %0|%0, %2}"
20566 [(set_attr "type" "mmxshft")
20567 (set_attr "mode" "DI")])
20568
20569 (define_insn "mmx_packuswb"
20570 [(set (match_operand:V8QI 0 "register_operand" "=y")
20571 (vec_concat:V8QI
20572 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20573 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20574 "TARGET_MMX"
20575 "packuswb\t{%2, %0|%0, %2}"
20576 [(set_attr "type" "mmxshft")
20577 (set_attr "mode" "DI")])
20578
20579 (define_insn "mmx_punpckhbw"
20580 [(set (match_operand:V8QI 0 "register_operand" "=y")
20581 (vec_merge:V8QI
20582 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20583 (parallel [(const_int 4)
20584 (const_int 0)
20585 (const_int 5)
20586 (const_int 1)
20587 (const_int 6)
20588 (const_int 2)
20589 (const_int 7)
20590 (const_int 3)]))
20591 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20592 (parallel [(const_int 0)
20593 (const_int 4)
20594 (const_int 1)
20595 (const_int 5)
20596 (const_int 2)
20597 (const_int 6)
20598 (const_int 3)
20599 (const_int 7)]))
20600 (const_int 85)))]
20601 "TARGET_MMX"
20602 "punpckhbw\t{%2, %0|%0, %2}"
20603 [(set_attr "type" "mmxcvt")
20604 (set_attr "mode" "DI")])
20605
20606 (define_insn "mmx_punpckhwd"
20607 [(set (match_operand:V4HI 0 "register_operand" "=y")
20608 (vec_merge:V4HI
20609 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20610 (parallel [(const_int 0)
20611 (const_int 2)
20612 (const_int 1)
20613 (const_int 3)]))
20614 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20615 (parallel [(const_int 2)
20616 (const_int 0)
20617 (const_int 3)
20618 (const_int 1)]))
20619 (const_int 5)))]
20620 "TARGET_MMX"
20621 "punpckhwd\t{%2, %0|%0, %2}"
20622 [(set_attr "type" "mmxcvt")
20623 (set_attr "mode" "DI")])
20624
20625 (define_insn "mmx_punpckhdq"
20626 [(set (match_operand:V2SI 0 "register_operand" "=y")
20627 (vec_merge:V2SI
20628 (match_operand:V2SI 1 "register_operand" "0")
20629 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20630 (parallel [(const_int 1)
20631 (const_int 0)]))
20632 (const_int 1)))]
20633 "TARGET_MMX"
20634 "punpckhdq\t{%2, %0|%0, %2}"
20635 [(set_attr "type" "mmxcvt")
20636 (set_attr "mode" "DI")])
20637
20638 (define_insn "mmx_punpcklbw"
20639 [(set (match_operand:V8QI 0 "register_operand" "=y")
20640 (vec_merge:V8QI
20641 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20642 (parallel [(const_int 0)
20643 (const_int 4)
20644 (const_int 1)
20645 (const_int 5)
20646 (const_int 2)
20647 (const_int 6)
20648 (const_int 3)
20649 (const_int 7)]))
20650 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20651 (parallel [(const_int 4)
20652 (const_int 0)
20653 (const_int 5)
20654 (const_int 1)
20655 (const_int 6)
20656 (const_int 2)
20657 (const_int 7)
20658 (const_int 3)]))
20659 (const_int 85)))]
20660 "TARGET_MMX"
20661 "punpcklbw\t{%2, %0|%0, %2}"
20662 [(set_attr "type" "mmxcvt")
20663 (set_attr "mode" "DI")])
20664
20665 (define_insn "mmx_punpcklwd"
20666 [(set (match_operand:V4HI 0 "register_operand" "=y")
20667 (vec_merge:V4HI
20668 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20669 (parallel [(const_int 2)
20670 (const_int 0)
20671 (const_int 3)
20672 (const_int 1)]))
20673 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20674 (parallel [(const_int 0)
20675 (const_int 2)
20676 (const_int 1)
20677 (const_int 3)]))
20678 (const_int 5)))]
20679 "TARGET_MMX"
20680 "punpcklwd\t{%2, %0|%0, %2}"
20681 [(set_attr "type" "mmxcvt")
20682 (set_attr "mode" "DI")])
20683
20684 (define_insn "mmx_punpckldq"
20685 [(set (match_operand:V2SI 0 "register_operand" "=y")
20686 (vec_merge:V2SI
20687 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20688 (parallel [(const_int 1)
20689 (const_int 0)]))
20690 (match_operand:V2SI 2 "register_operand" "y")
20691 (const_int 1)))]
20692 "TARGET_MMX"
20693 "punpckldq\t{%2, %0|%0, %2}"
20694 [(set_attr "type" "mmxcvt")
20695 (set_attr "mode" "DI")])
20696
20697
20698 ;; Miscellaneous stuff
20699
20700 (define_insn "emms"
20701 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20702 (clobber (reg:XF 8))
20703 (clobber (reg:XF 9))
20704 (clobber (reg:XF 10))
20705 (clobber (reg:XF 11))
20706 (clobber (reg:XF 12))
20707 (clobber (reg:XF 13))
20708 (clobber (reg:XF 14))
20709 (clobber (reg:XF 15))
20710 (clobber (reg:DI 29))
20711 (clobber (reg:DI 30))
20712 (clobber (reg:DI 31))
20713 (clobber (reg:DI 32))
20714 (clobber (reg:DI 33))
20715 (clobber (reg:DI 34))
20716 (clobber (reg:DI 35))
20717 (clobber (reg:DI 36))]
20718 "TARGET_MMX"
20719 "emms"
20720 [(set_attr "type" "mmx")
20721 (set_attr "memory" "unknown")])
20722
20723 (define_insn "ldmxcsr"
20724 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20725 UNSPECV_LDMXCSR)]
20726 "TARGET_SSE"
20727 "ldmxcsr\t%0"
20728 [(set_attr "type" "sse")
20729 (set_attr "memory" "load")])
20730
20731 (define_insn "stmxcsr"
20732 [(set (match_operand:SI 0 "memory_operand" "=m")
20733 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20734 "TARGET_SSE"
20735 "stmxcsr\t%0"
20736 [(set_attr "type" "sse")
20737 (set_attr "memory" "store")])
20738
20739 (define_expand "sfence"
20740 [(set (match_dup 0)
20741 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20742 "TARGET_SSE || TARGET_3DNOW_A"
20743 {
20744 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20745 MEM_VOLATILE_P (operands[0]) = 1;
20746 })
20747
20748 (define_insn "*sfence_insn"
20749 [(set (match_operand:BLK 0 "" "")
20750 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20751 "TARGET_SSE || TARGET_3DNOW_A"
20752 "sfence"
20753 [(set_attr "type" "sse")
20754 (set_attr "memory" "unknown")])
20755
20756 (define_expand "sse_prologue_save"
20757 [(parallel [(set (match_operand:BLK 0 "" "")
20758 (unspec:BLK [(reg:DI 21)
20759 (reg:DI 22)
20760 (reg:DI 23)
20761 (reg:DI 24)
20762 (reg:DI 25)
20763 (reg:DI 26)
20764 (reg:DI 27)
20765 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20766 (use (match_operand:DI 1 "register_operand" ""))
20767 (use (match_operand:DI 2 "immediate_operand" ""))
20768 (use (label_ref:DI (match_operand 3 "" "")))])]
20769 "TARGET_64BIT"
20770 "")
20771
20772 (define_insn "*sse_prologue_save_insn"
20773 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20774 (match_operand:DI 4 "const_int_operand" "n")))
20775 (unspec:BLK [(reg:DI 21)
20776 (reg:DI 22)
20777 (reg:DI 23)
20778 (reg:DI 24)
20779 (reg:DI 25)
20780 (reg:DI 26)
20781 (reg:DI 27)
20782 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20783 (use (match_operand:DI 1 "register_operand" "r"))
20784 (use (match_operand:DI 2 "const_int_operand" "i"))
20785 (use (label_ref:DI (match_operand 3 "" "X")))]
20786 "TARGET_64BIT
20787 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20788 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20789 "*
20790 {
20791 int i;
20792 operands[0] = gen_rtx_MEM (Pmode,
20793 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20794 output_asm_insn (\"jmp\\t%A1\", operands);
20795 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20796 {
20797 operands[4] = adjust_address (operands[0], DImode, i*16);
20798 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20799 PUT_MODE (operands[4], TImode);
20800 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20801 output_asm_insn (\"rex\", operands);
20802 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20803 }
20804 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20805 CODE_LABEL_NUMBER (operands[3]));
20806 RET;
20807 }
20808 "
20809 [(set_attr "type" "other")
20810 (set_attr "length_immediate" "0")
20811 (set_attr "length_address" "0")
20812 (set_attr "length" "135")
20813 (set_attr "memory" "store")
20814 (set_attr "modrm" "0")
20815 (set_attr "mode" "DI")])
20816
20817 ;; 3Dnow! instructions
20818
20819 (define_insn "addv2sf3"
20820 [(set (match_operand:V2SF 0 "register_operand" "=y")
20821 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20822 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20823 "TARGET_3DNOW"
20824 "pfadd\\t{%2, %0|%0, %2}"
20825 [(set_attr "type" "mmxadd")
20826 (set_attr "mode" "V2SF")])
20827
20828 (define_insn "subv2sf3"
20829 [(set (match_operand:V2SF 0 "register_operand" "=y")
20830 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20831 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20832 "TARGET_3DNOW"
20833 "pfsub\\t{%2, %0|%0, %2}"
20834 [(set_attr "type" "mmxadd")
20835 (set_attr "mode" "V2SF")])
20836
20837 (define_insn "subrv2sf3"
20838 [(set (match_operand:V2SF 0 "register_operand" "=y")
20839 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20840 (match_operand:V2SF 1 "register_operand" "0")))]
20841 "TARGET_3DNOW"
20842 "pfsubr\\t{%2, %0|%0, %2}"
20843 [(set_attr "type" "mmxadd")
20844 (set_attr "mode" "V2SF")])
20845
20846 (define_insn "gtv2sf3"
20847 [(set (match_operand:V2SI 0 "register_operand" "=y")
20848 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20849 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20850 "TARGET_3DNOW"
20851 "pfcmpgt\\t{%2, %0|%0, %2}"
20852 [(set_attr "type" "mmxcmp")
20853 (set_attr "mode" "V2SF")])
20854
20855 (define_insn "gev2sf3"
20856 [(set (match_operand:V2SI 0 "register_operand" "=y")
20857 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20858 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20859 "TARGET_3DNOW"
20860 "pfcmpge\\t{%2, %0|%0, %2}"
20861 [(set_attr "type" "mmxcmp")
20862 (set_attr "mode" "V2SF")])
20863
20864 (define_insn "eqv2sf3"
20865 [(set (match_operand:V2SI 0 "register_operand" "=y")
20866 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20867 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20868 "TARGET_3DNOW"
20869 "pfcmpeq\\t{%2, %0|%0, %2}"
20870 [(set_attr "type" "mmxcmp")
20871 (set_attr "mode" "V2SF")])
20872
20873 (define_insn "pfmaxv2sf3"
20874 [(set (match_operand:V2SF 0 "register_operand" "=y")
20875 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20876 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20877 "TARGET_3DNOW"
20878 "pfmax\\t{%2, %0|%0, %2}"
20879 [(set_attr "type" "mmxadd")
20880 (set_attr "mode" "V2SF")])
20881
20882 (define_insn "pfminv2sf3"
20883 [(set (match_operand:V2SF 0 "register_operand" "=y")
20884 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20885 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20886 "TARGET_3DNOW"
20887 "pfmin\\t{%2, %0|%0, %2}"
20888 [(set_attr "type" "mmxadd")
20889 (set_attr "mode" "V2SF")])
20890
20891 (define_insn "mulv2sf3"
20892 [(set (match_operand:V2SF 0 "register_operand" "=y")
20893 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20894 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20895 "TARGET_3DNOW"
20896 "pfmul\\t{%2, %0|%0, %2}"
20897 [(set_attr "type" "mmxmul")
20898 (set_attr "mode" "V2SF")])
20899
20900 (define_insn "femms"
20901 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20902 (clobber (reg:XF 8))
20903 (clobber (reg:XF 9))
20904 (clobber (reg:XF 10))
20905 (clobber (reg:XF 11))
20906 (clobber (reg:XF 12))
20907 (clobber (reg:XF 13))
20908 (clobber (reg:XF 14))
20909 (clobber (reg:XF 15))
20910 (clobber (reg:DI 29))
20911 (clobber (reg:DI 30))
20912 (clobber (reg:DI 31))
20913 (clobber (reg:DI 32))
20914 (clobber (reg:DI 33))
20915 (clobber (reg:DI 34))
20916 (clobber (reg:DI 35))
20917 (clobber (reg:DI 36))]
20918 "TARGET_3DNOW"
20919 "femms"
20920 [(set_attr "type" "mmx")
20921 (set_attr "memory" "none")])
20922
20923 (define_insn "pf2id"
20924 [(set (match_operand:V2SI 0 "register_operand" "=y")
20925 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20926 "TARGET_3DNOW"
20927 "pf2id\\t{%1, %0|%0, %1}"
20928 [(set_attr "type" "mmxcvt")
20929 (set_attr "mode" "V2SF")])
20930
20931 (define_insn "pf2iw"
20932 [(set (match_operand:V2SI 0 "register_operand" "=y")
20933 (sign_extend:V2SI
20934 (ss_truncate:V2HI
20935 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20936 "TARGET_3DNOW_A"
20937 "pf2iw\\t{%1, %0|%0, %1}"
20938 [(set_attr "type" "mmxcvt")
20939 (set_attr "mode" "V2SF")])
20940
20941 (define_insn "pfacc"
20942 [(set (match_operand:V2SF 0 "register_operand" "=y")
20943 (vec_concat:V2SF
20944 (plus:SF
20945 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20946 (parallel [(const_int 0)]))
20947 (vec_select:SF (match_dup 1)
20948 (parallel [(const_int 1)])))
20949 (plus:SF
20950 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20951 (parallel [(const_int 0)]))
20952 (vec_select:SF (match_dup 2)
20953 (parallel [(const_int 1)])))))]
20954 "TARGET_3DNOW"
20955 "pfacc\\t{%2, %0|%0, %2}"
20956 [(set_attr "type" "mmxadd")
20957 (set_attr "mode" "V2SF")])
20958
20959 (define_insn "pfnacc"
20960 [(set (match_operand:V2SF 0 "register_operand" "=y")
20961 (vec_concat:V2SF
20962 (minus:SF
20963 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20964 (parallel [(const_int 0)]))
20965 (vec_select:SF (match_dup 1)
20966 (parallel [(const_int 1)])))
20967 (minus:SF
20968 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20969 (parallel [(const_int 0)]))
20970 (vec_select:SF (match_dup 2)
20971 (parallel [(const_int 1)])))))]
20972 "TARGET_3DNOW_A"
20973 "pfnacc\\t{%2, %0|%0, %2}"
20974 [(set_attr "type" "mmxadd")
20975 (set_attr "mode" "V2SF")])
20976
20977 (define_insn "pfpnacc"
20978 [(set (match_operand:V2SF 0 "register_operand" "=y")
20979 (vec_concat:V2SF
20980 (minus:SF
20981 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
20982 (parallel [(const_int 0)]))
20983 (vec_select:SF (match_dup 1)
20984 (parallel [(const_int 1)])))
20985 (plus:SF
20986 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
20987 (parallel [(const_int 0)]))
20988 (vec_select:SF (match_dup 2)
20989 (parallel [(const_int 1)])))))]
20990 "TARGET_3DNOW_A"
20991 "pfpnacc\\t{%2, %0|%0, %2}"
20992 [(set_attr "type" "mmxadd")
20993 (set_attr "mode" "V2SF")])
20994
20995 (define_insn "pi2fw"
20996 [(set (match_operand:V2SF 0 "register_operand" "=y")
20997 (float:V2SF
20998 (vec_concat:V2SI
20999 (sign_extend:SI
21000 (truncate:HI
21001 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21002 (parallel [(const_int 0)]))))
21003 (sign_extend:SI
21004 (truncate:HI
21005 (vec_select:SI (match_dup 1)
21006 (parallel [(const_int 1)])))))))]
21007 "TARGET_3DNOW_A"
21008 "pi2fw\\t{%1, %0|%0, %1}"
21009 [(set_attr "type" "mmxcvt")
21010 (set_attr "mode" "V2SF")])
21011
21012 (define_insn "floatv2si2"
21013 [(set (match_operand:V2SF 0 "register_operand" "=y")
21014 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21015 "TARGET_3DNOW"
21016 "pi2fd\\t{%1, %0|%0, %1}"
21017 [(set_attr "type" "mmxcvt")
21018 (set_attr "mode" "V2SF")])
21019
21020 ;; This insn is identical to pavgb in operation, but the opcode is
21021 ;; different. To avoid accidentally matching pavgb, use an unspec.
21022
21023 (define_insn "pavgusb"
21024 [(set (match_operand:V8QI 0 "register_operand" "=y")
21025 (unspec:V8QI
21026 [(match_operand:V8QI 1 "register_operand" "0")
21027 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21028 UNSPEC_PAVGUSB))]
21029 "TARGET_3DNOW"
21030 "pavgusb\\t{%2, %0|%0, %2}"
21031 [(set_attr "type" "mmxshft")
21032 (set_attr "mode" "TI")])
21033
21034 ;; 3DNow reciprocal and sqrt
21035
21036 (define_insn "pfrcpv2sf2"
21037 [(set (match_operand:V2SF 0 "register_operand" "=y")
21038 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21039 UNSPEC_PFRCP))]
21040 "TARGET_3DNOW"
21041 "pfrcp\\t{%1, %0|%0, %1}"
21042 [(set_attr "type" "mmx")
21043 (set_attr "mode" "TI")])
21044
21045 (define_insn "pfrcpit1v2sf3"
21046 [(set (match_operand:V2SF 0 "register_operand" "=y")
21047 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21048 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21049 UNSPEC_PFRCPIT1))]
21050 "TARGET_3DNOW"
21051 "pfrcpit1\\t{%2, %0|%0, %2}"
21052 [(set_attr "type" "mmx")
21053 (set_attr "mode" "TI")])
21054
21055 (define_insn "pfrcpit2v2sf3"
21056 [(set (match_operand:V2SF 0 "register_operand" "=y")
21057 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21058 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21059 UNSPEC_PFRCPIT2))]
21060 "TARGET_3DNOW"
21061 "pfrcpit2\\t{%2, %0|%0, %2}"
21062 [(set_attr "type" "mmx")
21063 (set_attr "mode" "TI")])
21064
21065 (define_insn "pfrsqrtv2sf2"
21066 [(set (match_operand:V2SF 0 "register_operand" "=y")
21067 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21068 UNSPEC_PFRSQRT))]
21069 "TARGET_3DNOW"
21070 "pfrsqrt\\t{%1, %0|%0, %1}"
21071 [(set_attr "type" "mmx")
21072 (set_attr "mode" "TI")])
21073
21074 (define_insn "pfrsqit1v2sf3"
21075 [(set (match_operand:V2SF 0 "register_operand" "=y")
21076 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21077 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21078 UNSPEC_PFRSQIT1))]
21079 "TARGET_3DNOW"
21080 "pfrsqit1\\t{%2, %0|%0, %2}"
21081 [(set_attr "type" "mmx")
21082 (set_attr "mode" "TI")])
21083
21084 (define_insn "pmulhrwv4hi3"
21085 [(set (match_operand:V4HI 0 "register_operand" "=y")
21086 (truncate:V4HI
21087 (lshiftrt:V4SI
21088 (plus:V4SI
21089 (mult:V4SI
21090 (sign_extend:V4SI
21091 (match_operand:V4HI 1 "register_operand" "0"))
21092 (sign_extend:V4SI
21093 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21094 (const_vector:V4SI [(const_int 32768)
21095 (const_int 32768)
21096 (const_int 32768)
21097 (const_int 32768)]))
21098 (const_int 16))))]
21099 "TARGET_3DNOW"
21100 "pmulhrw\\t{%2, %0|%0, %2}"
21101 [(set_attr "type" "mmxmul")
21102 (set_attr "mode" "TI")])
21103
21104 (define_insn "pswapdv2si2"
21105 [(set (match_operand:V2SI 0 "register_operand" "=y")
21106 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21107 (parallel [(const_int 1) (const_int 0)])))]
21108 "TARGET_3DNOW_A"
21109 "pswapd\\t{%1, %0|%0, %1}"
21110 [(set_attr "type" "mmxcvt")
21111 (set_attr "mode" "TI")])
21112
21113 (define_insn "pswapdv2sf2"
21114 [(set (match_operand:V2SF 0 "register_operand" "=y")
21115 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21116 (parallel [(const_int 1) (const_int 0)])))]
21117 "TARGET_3DNOW_A"
21118 "pswapd\\t{%1, %0|%0, %1}"
21119 [(set_attr "type" "mmxcvt")
21120 (set_attr "mode" "TI")])
21121
21122 (define_expand "prefetch"
21123 [(prefetch (match_operand 0 "address_operand" "")
21124 (match_operand:SI 1 "const_int_operand" "")
21125 (match_operand:SI 2 "const_int_operand" ""))]
21126 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21127 {
21128 int rw = INTVAL (operands[1]);
21129 int locality = INTVAL (operands[2]);
21130
21131 if (rw != 0 && rw != 1)
21132 abort ();
21133 if (locality < 0 || locality > 3)
21134 abort ();
21135 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21136 abort ();
21137
21138 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21139 suported by SSE counterpart or the SSE prefetch is not available
21140 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21141 of locality. */
21142 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21143 operands[2] = GEN_INT (3);
21144 else
21145 operands[1] = const0_rtx;
21146 })
21147
21148 (define_insn "*prefetch_sse"
21149 [(prefetch (match_operand:SI 0 "address_operand" "p")
21150 (const_int 0)
21151 (match_operand:SI 1 "const_int_operand" ""))]
21152 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21153 {
21154 static const char * const patterns[4] = {
21155 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21156 };
21157
21158 int locality = INTVAL (operands[1]);
21159 if (locality < 0 || locality > 3)
21160 abort ();
21161
21162 return patterns[locality];
21163 }
21164 [(set_attr "type" "sse")
21165 (set_attr "memory" "none")])
21166
21167 (define_insn "*prefetch_sse_rex"
21168 [(prefetch (match_operand:DI 0 "address_operand" "p")
21169 (const_int 0)
21170 (match_operand:SI 1 "const_int_operand" ""))]
21171 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21172 {
21173 static const char * const patterns[4] = {
21174 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21175 };
21176
21177 int locality = INTVAL (operands[1]);
21178 if (locality < 0 || locality > 3)
21179 abort ();
21180
21181 return patterns[locality];
21182 }
21183 [(set_attr "type" "sse")
21184 (set_attr "memory" "none")])
21185
21186 (define_insn "*prefetch_3dnow"
21187 [(prefetch (match_operand:SI 0 "address_operand" "p")
21188 (match_operand:SI 1 "const_int_operand" "n")
21189 (const_int 3))]
21190 "TARGET_3DNOW && !TARGET_64BIT"
21191 {
21192 if (INTVAL (operands[1]) == 0)
21193 return "prefetch\t%a0";
21194 else
21195 return "prefetchw\t%a0";
21196 }
21197 [(set_attr "type" "mmx")
21198 (set_attr "memory" "none")])
21199
21200 (define_insn "*prefetch_3dnow_rex"
21201 [(prefetch (match_operand:DI 0 "address_operand" "p")
21202 (match_operand:SI 1 "const_int_operand" "n")
21203 (const_int 3))]
21204 "TARGET_3DNOW && TARGET_64BIT"
21205 {
21206 if (INTVAL (operands[1]) == 0)
21207 return "prefetch\t%a0";
21208 else
21209 return "prefetchw\t%a0";
21210 }
21211 [(set_attr "type" "mmx")
21212 (set_attr "memory" "none")])
21213
21214 ;; SSE2 support
21215
21216 (define_insn "addv2df3"
21217 [(set (match_operand:V2DF 0 "register_operand" "=x")
21218 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21219 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21220 "TARGET_SSE2"
21221 "addpd\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "sseadd")
21223 (set_attr "mode" "V2DF")])
21224
21225 (define_insn "vmaddv2df3"
21226 [(set (match_operand:V2DF 0 "register_operand" "=x")
21227 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21228 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21229 (match_dup 1)
21230 (const_int 1)))]
21231 "TARGET_SSE2"
21232 "addsd\t{%2, %0|%0, %2}"
21233 [(set_attr "type" "sseadd")
21234 (set_attr "mode" "DF")])
21235
21236 (define_insn "subv2df3"
21237 [(set (match_operand:V2DF 0 "register_operand" "=x")
21238 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21239 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21240 "TARGET_SSE2"
21241 "subpd\t{%2, %0|%0, %2}"
21242 [(set_attr "type" "sseadd")
21243 (set_attr "mode" "V2DF")])
21244
21245 (define_insn "vmsubv2df3"
21246 [(set (match_operand:V2DF 0 "register_operand" "=x")
21247 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21248 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21249 (match_dup 1)
21250 (const_int 1)))]
21251 "TARGET_SSE2"
21252 "subsd\t{%2, %0|%0, %2}"
21253 [(set_attr "type" "sseadd")
21254 (set_attr "mode" "DF")])
21255
21256 (define_insn "mulv2df3"
21257 [(set (match_operand:V2DF 0 "register_operand" "=x")
21258 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21259 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21260 "TARGET_SSE2"
21261 "mulpd\t{%2, %0|%0, %2}"
21262 [(set_attr "type" "ssemul")
21263 (set_attr "mode" "V2DF")])
21264
21265 (define_insn "vmmulv2df3"
21266 [(set (match_operand:V2DF 0 "register_operand" "=x")
21267 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21268 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21269 (match_dup 1)
21270 (const_int 1)))]
21271 "TARGET_SSE2"
21272 "mulsd\t{%2, %0|%0, %2}"
21273 [(set_attr "type" "ssemul")
21274 (set_attr "mode" "DF")])
21275
21276 (define_insn "divv2df3"
21277 [(set (match_operand:V2DF 0 "register_operand" "=x")
21278 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21279 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21280 "TARGET_SSE2"
21281 "divpd\t{%2, %0|%0, %2}"
21282 [(set_attr "type" "ssediv")
21283 (set_attr "mode" "V2DF")])
21284
21285 (define_insn "vmdivv2df3"
21286 [(set (match_operand:V2DF 0 "register_operand" "=x")
21287 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21288 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21289 (match_dup 1)
21290 (const_int 1)))]
21291 "TARGET_SSE2"
21292 "divsd\t{%2, %0|%0, %2}"
21293 [(set_attr "type" "ssediv")
21294 (set_attr "mode" "DF")])
21295
21296 ;; SSE min/max
21297
21298 (define_insn "smaxv2df3"
21299 [(set (match_operand:V2DF 0 "register_operand" "=x")
21300 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21301 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21302 "TARGET_SSE2"
21303 "maxpd\t{%2, %0|%0, %2}"
21304 [(set_attr "type" "sseadd")
21305 (set_attr "mode" "V2DF")])
21306
21307 (define_insn "vmsmaxv2df3"
21308 [(set (match_operand:V2DF 0 "register_operand" "=x")
21309 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21310 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21311 (match_dup 1)
21312 (const_int 1)))]
21313 "TARGET_SSE2"
21314 "maxsd\t{%2, %0|%0, %2}"
21315 [(set_attr "type" "sseadd")
21316 (set_attr "mode" "DF")])
21317
21318 (define_insn "sminv2df3"
21319 [(set (match_operand:V2DF 0 "register_operand" "=x")
21320 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21321 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21322 "TARGET_SSE2"
21323 "minpd\t{%2, %0|%0, %2}"
21324 [(set_attr "type" "sseadd")
21325 (set_attr "mode" "V2DF")])
21326
21327 (define_insn "vmsminv2df3"
21328 [(set (match_operand:V2DF 0 "register_operand" "=x")
21329 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21330 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21331 (match_dup 1)
21332 (const_int 1)))]
21333 "TARGET_SSE2"
21334 "minsd\t{%2, %0|%0, %2}"
21335 [(set_attr "type" "sseadd")
21336 (set_attr "mode" "DF")])
21337 ;; SSE2 square root. There doesn't appear to be an extension for the
21338 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21339
21340 (define_insn "sqrtv2df2"
21341 [(set (match_operand:V2DF 0 "register_operand" "=x")
21342 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21343 "TARGET_SSE2"
21344 "sqrtpd\t{%1, %0|%0, %1}"
21345 [(set_attr "type" "sse")
21346 (set_attr "mode" "V2DF")])
21347
21348 (define_insn "vmsqrtv2df2"
21349 [(set (match_operand:V2DF 0 "register_operand" "=x")
21350 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21351 (match_operand:V2DF 2 "register_operand" "0")
21352 (const_int 1)))]
21353 "TARGET_SSE2"
21354 "sqrtsd\t{%1, %0|%0, %1}"
21355 [(set_attr "type" "sse")
21356 (set_attr "mode" "SF")])
21357
21358 ;; SSE mask-generating compares
21359
21360 (define_insn "maskcmpv2df3"
21361 [(set (match_operand:V2DI 0 "register_operand" "=x")
21362 (match_operator:V2DI 3 "sse_comparison_operator"
21363 [(match_operand:V2DF 1 "register_operand" "0")
21364 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21365 "TARGET_SSE2"
21366 "cmp%D3pd\t{%2, %0|%0, %2}"
21367 [(set_attr "type" "ssecmp")
21368 (set_attr "mode" "V2DF")])
21369
21370 (define_insn "maskncmpv2df3"
21371 [(set (match_operand:V2DI 0 "register_operand" "=x")
21372 (not:V2DI
21373 (match_operator:V2DI 3 "sse_comparison_operator"
21374 [(match_operand:V2DF 1 "register_operand" "0")
21375 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21376 "TARGET_SSE2"
21377 {
21378 if (GET_CODE (operands[3]) == UNORDERED)
21379 return "cmpordps\t{%2, %0|%0, %2}";
21380 else
21381 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21382 }
21383 [(set_attr "type" "ssecmp")
21384 (set_attr "mode" "V2DF")])
21385
21386 (define_insn "vmmaskcmpv2df3"
21387 [(set (match_operand:V2DI 0 "register_operand" "=x")
21388 (vec_merge:V2DI
21389 (match_operator:V2DI 3 "sse_comparison_operator"
21390 [(match_operand:V2DF 1 "register_operand" "0")
21391 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21392 (subreg:V2DI (match_dup 1) 0)
21393 (const_int 1)))]
21394 "TARGET_SSE2"
21395 "cmp%D3sd\t{%2, %0|%0, %2}"
21396 [(set_attr "type" "ssecmp")
21397 (set_attr "mode" "DF")])
21398
21399 (define_insn "vmmaskncmpv2df3"
21400 [(set (match_operand:V2DI 0 "register_operand" "=x")
21401 (vec_merge:V2DI
21402 (not:V2DI
21403 (match_operator:V2DI 3 "sse_comparison_operator"
21404 [(match_operand:V2DF 1 "register_operand" "0")
21405 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21406 (subreg:V2DI (match_dup 1) 0)
21407 (const_int 1)))]
21408 "TARGET_SSE2"
21409 {
21410 if (GET_CODE (operands[3]) == UNORDERED)
21411 return "cmpordsd\t{%2, %0|%0, %2}";
21412 else
21413 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21414 }
21415 [(set_attr "type" "ssecmp")
21416 (set_attr "mode" "DF")])
21417
21418 (define_insn "sse2_comi"
21419 [(set (reg:CCFP 17)
21420 (compare:CCFP (vec_select:DF
21421 (match_operand:V2DF 0 "register_operand" "x")
21422 (parallel [(const_int 0)]))
21423 (vec_select:DF
21424 (match_operand:V2DF 1 "register_operand" "x")
21425 (parallel [(const_int 0)]))))]
21426 "TARGET_SSE2"
21427 "comisd\t{%1, %0|%0, %1}"
21428 [(set_attr "type" "ssecomi")
21429 (set_attr "mode" "DF")])
21430
21431 (define_insn "sse2_ucomi"
21432 [(set (reg:CCFPU 17)
21433 (compare:CCFPU (vec_select:DF
21434 (match_operand:V2DF 0 "register_operand" "x")
21435 (parallel [(const_int 0)]))
21436 (vec_select:DF
21437 (match_operand:V2DF 1 "register_operand" "x")
21438 (parallel [(const_int 0)]))))]
21439 "TARGET_SSE2"
21440 "ucomisd\t{%1, %0|%0, %1}"
21441 [(set_attr "type" "ssecomi")
21442 (set_attr "mode" "DF")])
21443
21444 ;; SSE Strange Moves.
21445
21446 (define_insn "sse2_movmskpd"
21447 [(set (match_operand:SI 0 "register_operand" "=r")
21448 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21449 UNSPEC_MOVMSK))]
21450 "TARGET_SSE2"
21451 "movmskpd\t{%1, %0|%0, %1}"
21452 [(set_attr "type" "ssecvt")
21453 (set_attr "mode" "V2DF")])
21454
21455 (define_insn "sse2_pmovmskb"
21456 [(set (match_operand:SI 0 "register_operand" "=r")
21457 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21458 UNSPEC_MOVMSK))]
21459 "TARGET_SSE2"
21460 "pmovmskb\t{%1, %0|%0, %1}"
21461 [(set_attr "type" "ssecvt")
21462 (set_attr "mode" "V2DF")])
21463
21464 (define_insn "sse2_maskmovdqu"
21465 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21466 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21467 (match_operand:V16QI 2 "register_operand" "x")]
21468 UNSPEC_MASKMOV))]
21469 "TARGET_SSE2"
21470 ;; @@@ check ordering of operands in intel/nonintel syntax
21471 "maskmovdqu\t{%2, %1|%1, %2}"
21472 [(set_attr "type" "ssecvt")
21473 (set_attr "mode" "TI")])
21474
21475 (define_insn "sse2_maskmovdqu_rex64"
21476 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21477 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21478 (match_operand:V16QI 2 "register_operand" "x")]
21479 UNSPEC_MASKMOV))]
21480 "TARGET_SSE2"
21481 ;; @@@ check ordering of operands in intel/nonintel syntax
21482 "maskmovdqu\t{%2, %1|%1, %2}"
21483 [(set_attr "type" "ssecvt")
21484 (set_attr "mode" "TI")])
21485
21486 (define_insn "sse2_movntv2df"
21487 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21488 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21489 UNSPEC_MOVNT))]
21490 "TARGET_SSE2"
21491 "movntpd\t{%1, %0|%0, %1}"
21492 [(set_attr "type" "ssecvt")
21493 (set_attr "mode" "V2DF")])
21494
21495 (define_insn "sse2_movntv2di"
21496 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21497 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21498 UNSPEC_MOVNT))]
21499 "TARGET_SSE2"
21500 "movntdq\t{%1, %0|%0, %1}"
21501 [(set_attr "type" "ssecvt")
21502 (set_attr "mode" "TI")])
21503
21504 (define_insn "sse2_movntsi"
21505 [(set (match_operand:SI 0 "memory_operand" "=m")
21506 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21507 UNSPEC_MOVNT))]
21508 "TARGET_SSE2"
21509 "movnti\t{%1, %0|%0, %1}"
21510 [(set_attr "type" "ssecvt")
21511 (set_attr "mode" "V2DF")])
21512
21513 ;; SSE <-> integer/MMX conversions
21514
21515 ;; Conversions between SI and SF
21516
21517 (define_insn "cvtdq2ps"
21518 [(set (match_operand:V4SF 0 "register_operand" "=x")
21519 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21520 "TARGET_SSE2"
21521 "cvtdq2ps\t{%1, %0|%0, %1}"
21522 [(set_attr "type" "ssecvt")
21523 (set_attr "mode" "V2DF")])
21524
21525 (define_insn "cvtps2dq"
21526 [(set (match_operand:V4SI 0 "register_operand" "=x")
21527 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21528 "TARGET_SSE2"
21529 "cvtps2dq\t{%1, %0|%0, %1}"
21530 [(set_attr "type" "ssecvt")
21531 (set_attr "mode" "TI")])
21532
21533 (define_insn "cvttps2dq"
21534 [(set (match_operand:V4SI 0 "register_operand" "=x")
21535 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21536 UNSPEC_FIX))]
21537 "TARGET_SSE2"
21538 "cvttps2dq\t{%1, %0|%0, %1}"
21539 [(set_attr "type" "ssecvt")
21540 (set_attr "mode" "TI")])
21541
21542 ;; Conversions between SI and DF
21543
21544 (define_insn "cvtdq2pd"
21545 [(set (match_operand:V2DF 0 "register_operand" "=x")
21546 (float:V2DF (vec_select:V2SI
21547 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21548 (parallel
21549 [(const_int 0)
21550 (const_int 1)]))))]
21551 "TARGET_SSE2"
21552 "cvtdq2pd\t{%1, %0|%0, %1}"
21553 [(set_attr "type" "ssecvt")
21554 (set_attr "mode" "V2DF")])
21555
21556 (define_insn "cvtpd2dq"
21557 [(set (match_operand:V4SI 0 "register_operand" "=x")
21558 (vec_concat:V4SI
21559 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21560 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21561 "TARGET_SSE2"
21562 "cvtpd2dq\t{%1, %0|%0, %1}"
21563 [(set_attr "type" "ssecvt")
21564 (set_attr "mode" "TI")])
21565
21566 (define_insn "cvttpd2dq"
21567 [(set (match_operand:V4SI 0 "register_operand" "=x")
21568 (vec_concat:V4SI
21569 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21570 UNSPEC_FIX)
21571 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21572 "TARGET_SSE2"
21573 "cvttpd2dq\t{%1, %0|%0, %1}"
21574 [(set_attr "type" "ssecvt")
21575 (set_attr "mode" "TI")])
21576
21577 (define_insn "cvtpd2pi"
21578 [(set (match_operand:V2SI 0 "register_operand" "=y")
21579 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21580 "TARGET_SSE2"
21581 "cvtpd2pi\t{%1, %0|%0, %1}"
21582 [(set_attr "type" "ssecvt")
21583 (set_attr "mode" "TI")])
21584
21585 (define_insn "cvttpd2pi"
21586 [(set (match_operand:V2SI 0 "register_operand" "=y")
21587 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21588 UNSPEC_FIX))]
21589 "TARGET_SSE2"
21590 "cvttpd2pi\t{%1, %0|%0, %1}"
21591 [(set_attr "type" "ssecvt")
21592 (set_attr "mode" "TI")])
21593
21594 (define_insn "cvtpi2pd"
21595 [(set (match_operand:V2DF 0 "register_operand" "=x")
21596 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21597 "TARGET_SSE2"
21598 "cvtpi2pd\t{%1, %0|%0, %1}"
21599 [(set_attr "type" "ssecvt")
21600 (set_attr "mode" "TI")])
21601
21602 ;; Conversions between SI and DF
21603
21604 (define_insn "cvtsd2si"
21605 [(set (match_operand:SI 0 "register_operand" "=r,r")
21606 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21607 (parallel [(const_int 0)]))))]
21608 "TARGET_SSE2"
21609 "cvtsd2si\t{%1, %0|%0, %1}"
21610 [(set_attr "type" "sseicvt")
21611 (set_attr "athlon_decode" "double,vector")
21612 (set_attr "mode" "SI")])
21613
21614 (define_insn "cvtsd2siq"
21615 [(set (match_operand:DI 0 "register_operand" "=r,r")
21616 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21617 (parallel [(const_int 0)]))))]
21618 "TARGET_SSE2 && TARGET_64BIT"
21619 "cvtsd2siq\t{%1, %0|%0, %1}"
21620 [(set_attr "type" "sseicvt")
21621 (set_attr "athlon_decode" "double,vector")
21622 (set_attr "mode" "DI")])
21623
21624 (define_insn "cvttsd2si"
21625 [(set (match_operand:SI 0 "register_operand" "=r,r")
21626 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21627 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21628 "TARGET_SSE2"
21629 "cvttsd2si\t{%1, %0|%0, %1}"
21630 [(set_attr "type" "sseicvt")
21631 (set_attr "mode" "SI")
21632 (set_attr "athlon_decode" "double,vector")])
21633
21634 (define_insn "cvttsd2siq"
21635 [(set (match_operand:DI 0 "register_operand" "=r,r")
21636 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21637 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21638 "TARGET_SSE2 && TARGET_64BIT"
21639 "cvttsd2siq\t{%1, %0|%0, %1}"
21640 [(set_attr "type" "sseicvt")
21641 (set_attr "mode" "DI")
21642 (set_attr "athlon_decode" "double,vector")])
21643
21644 (define_insn "cvtsi2sd"
21645 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21646 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21647 (vec_duplicate:V2DF
21648 (float:DF
21649 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21650 (const_int 2)))]
21651 "TARGET_SSE2"
21652 "cvtsi2sd\t{%2, %0|%0, %2}"
21653 [(set_attr "type" "sseicvt")
21654 (set_attr "mode" "DF")
21655 (set_attr "athlon_decode" "double,direct")])
21656
21657 (define_insn "cvtsi2sdq"
21658 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21659 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21660 (vec_duplicate:V2DF
21661 (float:DF
21662 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21663 (const_int 2)))]
21664 "TARGET_SSE2 && TARGET_64BIT"
21665 "cvtsi2sdq\t{%2, %0|%0, %2}"
21666 [(set_attr "type" "sseicvt")
21667 (set_attr "mode" "DF")
21668 (set_attr "athlon_decode" "double,direct")])
21669
21670 ;; Conversions between SF and DF
21671
21672 (define_insn "cvtsd2ss"
21673 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21674 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21675 (vec_duplicate:V4SF
21676 (float_truncate:V2SF
21677 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21678 (const_int 14)))]
21679 "TARGET_SSE2"
21680 "cvtsd2ss\t{%2, %0|%0, %2}"
21681 [(set_attr "type" "ssecvt")
21682 (set_attr "athlon_decode" "vector,double")
21683 (set_attr "mode" "SF")])
21684
21685 (define_insn "cvtss2sd"
21686 [(set (match_operand:V2DF 0 "register_operand" "=x")
21687 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21688 (float_extend:V2DF
21689 (vec_select:V2SF
21690 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21691 (parallel [(const_int 0)
21692 (const_int 1)])))
21693 (const_int 2)))]
21694 "TARGET_SSE2"
21695 "cvtss2sd\t{%2, %0|%0, %2}"
21696 [(set_attr "type" "ssecvt")
21697 (set_attr "mode" "DF")])
21698
21699 (define_insn "cvtpd2ps"
21700 [(set (match_operand:V4SF 0 "register_operand" "=x")
21701 (subreg:V4SF
21702 (vec_concat:V4SI
21703 (subreg:V2SI (float_truncate:V2SF
21704 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21705 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21706 "TARGET_SSE2"
21707 "cvtpd2ps\t{%1, %0|%0, %1}"
21708 [(set_attr "type" "ssecvt")
21709 (set_attr "mode" "V4SF")])
21710
21711 (define_insn "cvtps2pd"
21712 [(set (match_operand:V2DF 0 "register_operand" "=x")
21713 (float_extend:V2DF
21714 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21715 (parallel [(const_int 0)
21716 (const_int 1)]))))]
21717 "TARGET_SSE2"
21718 "cvtps2pd\t{%1, %0|%0, %1}"
21719 [(set_attr "type" "ssecvt")
21720 (set_attr "mode" "V2DF")])
21721
21722 ;; SSE2 variants of MMX insns
21723
21724 ;; MMX arithmetic
21725
21726 (define_insn "addv16qi3"
21727 [(set (match_operand:V16QI 0 "register_operand" "=x")
21728 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21729 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21730 "TARGET_SSE2"
21731 "paddb\t{%2, %0|%0, %2}"
21732 [(set_attr "type" "sseiadd")
21733 (set_attr "mode" "TI")])
21734
21735 (define_insn "addv8hi3"
21736 [(set (match_operand:V8HI 0 "register_operand" "=x")
21737 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21738 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21739 "TARGET_SSE2"
21740 "paddw\t{%2, %0|%0, %2}"
21741 [(set_attr "type" "sseiadd")
21742 (set_attr "mode" "TI")])
21743
21744 (define_insn "addv4si3"
21745 [(set (match_operand:V4SI 0 "register_operand" "=x")
21746 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21747 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21748 "TARGET_SSE2"
21749 "paddd\t{%2, %0|%0, %2}"
21750 [(set_attr "type" "sseiadd")
21751 (set_attr "mode" "TI")])
21752
21753 (define_insn "addv2di3"
21754 [(set (match_operand:V2DI 0 "register_operand" "=x")
21755 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21756 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21757 "TARGET_SSE2"
21758 "paddq\t{%2, %0|%0, %2}"
21759 [(set_attr "type" "sseiadd")
21760 (set_attr "mode" "TI")])
21761
21762 (define_insn "ssaddv16qi3"
21763 [(set (match_operand:V16QI 0 "register_operand" "=x")
21764 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21765 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21766 "TARGET_SSE2"
21767 "paddsb\t{%2, %0|%0, %2}"
21768 [(set_attr "type" "sseiadd")
21769 (set_attr "mode" "TI")])
21770
21771 (define_insn "ssaddv8hi3"
21772 [(set (match_operand:V8HI 0 "register_operand" "=x")
21773 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21774 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21775 "TARGET_SSE2"
21776 "paddsw\t{%2, %0|%0, %2}"
21777 [(set_attr "type" "sseiadd")
21778 (set_attr "mode" "TI")])
21779
21780 (define_insn "usaddv16qi3"
21781 [(set (match_operand:V16QI 0 "register_operand" "=x")
21782 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21783 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21784 "TARGET_SSE2"
21785 "paddusb\t{%2, %0|%0, %2}"
21786 [(set_attr "type" "sseiadd")
21787 (set_attr "mode" "TI")])
21788
21789 (define_insn "usaddv8hi3"
21790 [(set (match_operand:V8HI 0 "register_operand" "=x")
21791 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21792 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21793 "TARGET_SSE2"
21794 "paddusw\t{%2, %0|%0, %2}"
21795 [(set_attr "type" "sseiadd")
21796 (set_attr "mode" "TI")])
21797
21798 (define_insn "subv16qi3"
21799 [(set (match_operand:V16QI 0 "register_operand" "=x")
21800 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21801 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21802 "TARGET_SSE2"
21803 "psubb\t{%2, %0|%0, %2}"
21804 [(set_attr "type" "sseiadd")
21805 (set_attr "mode" "TI")])
21806
21807 (define_insn "subv8hi3"
21808 [(set (match_operand:V8HI 0 "register_operand" "=x")
21809 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21810 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21811 "TARGET_SSE2"
21812 "psubw\t{%2, %0|%0, %2}"
21813 [(set_attr "type" "sseiadd")
21814 (set_attr "mode" "TI")])
21815
21816 (define_insn "subv4si3"
21817 [(set (match_operand:V4SI 0 "register_operand" "=x")
21818 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21819 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21820 "TARGET_SSE2"
21821 "psubd\t{%2, %0|%0, %2}"
21822 [(set_attr "type" "sseiadd")
21823 (set_attr "mode" "TI")])
21824
21825 (define_insn "subv2di3"
21826 [(set (match_operand:V2DI 0 "register_operand" "=x")
21827 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21828 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21829 "TARGET_SSE2"
21830 "psubq\t{%2, %0|%0, %2}"
21831 [(set_attr "type" "sseiadd")
21832 (set_attr "mode" "TI")])
21833
21834 (define_insn "sssubv16qi3"
21835 [(set (match_operand:V16QI 0 "register_operand" "=x")
21836 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21837 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21838 "TARGET_SSE2"
21839 "psubsb\t{%2, %0|%0, %2}"
21840 [(set_attr "type" "sseiadd")
21841 (set_attr "mode" "TI")])
21842
21843 (define_insn "sssubv8hi3"
21844 [(set (match_operand:V8HI 0 "register_operand" "=x")
21845 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21846 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21847 "TARGET_SSE2"
21848 "psubsw\t{%2, %0|%0, %2}"
21849 [(set_attr "type" "sseiadd")
21850 (set_attr "mode" "TI")])
21851
21852 (define_insn "ussubv16qi3"
21853 [(set (match_operand:V16QI 0 "register_operand" "=x")
21854 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21855 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21856 "TARGET_SSE2"
21857 "psubusb\t{%2, %0|%0, %2}"
21858 [(set_attr "type" "sseiadd")
21859 (set_attr "mode" "TI")])
21860
21861 (define_insn "ussubv8hi3"
21862 [(set (match_operand:V8HI 0 "register_operand" "=x")
21863 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21864 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21865 "TARGET_SSE2"
21866 "psubusw\t{%2, %0|%0, %2}"
21867 [(set_attr "type" "sseiadd")
21868 (set_attr "mode" "TI")])
21869
21870 (define_insn "mulv8hi3"
21871 [(set (match_operand:V8HI 0 "register_operand" "=x")
21872 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21873 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21874 "TARGET_SSE2"
21875 "pmullw\t{%2, %0|%0, %2}"
21876 [(set_attr "type" "sseimul")
21877 (set_attr "mode" "TI")])
21878
21879 (define_insn "smulv8hi3_highpart"
21880 [(set (match_operand:V8HI 0 "register_operand" "=x")
21881 (truncate:V8HI
21882 (lshiftrt:V8SI
21883 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21884 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21885 (const_int 16))))]
21886 "TARGET_SSE2"
21887 "pmulhw\t{%2, %0|%0, %2}"
21888 [(set_attr "type" "sseimul")
21889 (set_attr "mode" "TI")])
21890
21891 (define_insn "umulv8hi3_highpart"
21892 [(set (match_operand:V8HI 0 "register_operand" "=x")
21893 (truncate:V8HI
21894 (lshiftrt:V8SI
21895 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21896 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21897 (const_int 16))))]
21898 "TARGET_SSE2"
21899 "pmulhuw\t{%2, %0|%0, %2}"
21900 [(set_attr "type" "sseimul")
21901 (set_attr "mode" "TI")])
21902
21903 (define_insn "sse2_umulsidi3"
21904 [(set (match_operand:DI 0 "register_operand" "=y")
21905 (mult:DI (zero_extend:DI (vec_select:SI
21906 (match_operand:V2SI 1 "register_operand" "0")
21907 (parallel [(const_int 0)])))
21908 (zero_extend:DI (vec_select:SI
21909 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21910 (parallel [(const_int 0)])))))]
21911 "TARGET_SSE2"
21912 "pmuludq\t{%2, %0|%0, %2}"
21913 [(set_attr "type" "sseimul")
21914 (set_attr "mode" "TI")])
21915
21916 (define_insn "sse2_umulv2siv2di3"
21917 [(set (match_operand:V2DI 0 "register_operand" "=x")
21918 (mult:V2DI (zero_extend:V2DI
21919 (vec_select:V2SI
21920 (match_operand:V4SI 1 "register_operand" "0")
21921 (parallel [(const_int 0) (const_int 2)])))
21922 (zero_extend:V2DI
21923 (vec_select:V2SI
21924 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21925 (parallel [(const_int 0) (const_int 2)])))))]
21926 "TARGET_SSE2"
21927 "pmuludq\t{%2, %0|%0, %2}"
21928 [(set_attr "type" "sseimul")
21929 (set_attr "mode" "TI")])
21930
21931 (define_insn "sse2_pmaddwd"
21932 [(set (match_operand:V4SI 0 "register_operand" "=x")
21933 (plus:V4SI
21934 (mult:V4SI
21935 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21936 (parallel [(const_int 0)
21937 (const_int 2)
21938 (const_int 4)
21939 (const_int 6)])))
21940 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
21941 (parallel [(const_int 0)
21942 (const_int 2)
21943 (const_int 4)
21944 (const_int 6)]))))
21945 (mult:V4SI
21946 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
21947 (parallel [(const_int 1)
21948 (const_int 3)
21949 (const_int 5)
21950 (const_int 7)])))
21951 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
21952 (parallel [(const_int 1)
21953 (const_int 3)
21954 (const_int 5)
21955 (const_int 7)]))))))]
21956 "TARGET_SSE2"
21957 "pmaddwd\t{%2, %0|%0, %2}"
21958 [(set_attr "type" "sseiadd")
21959 (set_attr "mode" "TI")])
21960
21961 ;; Same as pxor, but don't show input operands so that we don't think
21962 ;; they are live.
21963 (define_insn "sse2_clrti"
21964 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
21965 "TARGET_SSE2"
21966 {
21967 if (get_attr_mode (insn) == MODE_TI)
21968 return "pxor\t%0, %0";
21969 else
21970 return "xorps\t%0, %0";
21971 }
21972 [(set_attr "type" "ssemov")
21973 (set_attr "memory" "none")
21974 (set (attr "mode")
21975 (if_then_else
21976 (ne (symbol_ref "optimize_size")
21977 (const_int 0))
21978 (const_string "V4SF")
21979 (const_string "TI")))])
21980
21981 ;; MMX unsigned averages/sum of absolute differences
21982
21983 (define_insn "sse2_uavgv16qi3"
21984 [(set (match_operand:V16QI 0 "register_operand" "=x")
21985 (ashiftrt:V16QI
21986 (plus:V16QI (plus:V16QI
21987 (match_operand:V16QI 1 "register_operand" "0")
21988 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
21989 (const_vector:V16QI [(const_int 1) (const_int 1)
21990 (const_int 1) (const_int 1)
21991 (const_int 1) (const_int 1)
21992 (const_int 1) (const_int 1)
21993 (const_int 1) (const_int 1)
21994 (const_int 1) (const_int 1)
21995 (const_int 1) (const_int 1)
21996 (const_int 1) (const_int 1)]))
21997 (const_int 1)))]
21998 "TARGET_SSE2"
21999 "pavgb\t{%2, %0|%0, %2}"
22000 [(set_attr "type" "sseiadd")
22001 (set_attr "mode" "TI")])
22002
22003 (define_insn "sse2_uavgv8hi3"
22004 [(set (match_operand:V8HI 0 "register_operand" "=x")
22005 (ashiftrt:V8HI
22006 (plus:V8HI (plus:V8HI
22007 (match_operand:V8HI 1 "register_operand" "0")
22008 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22009 (const_vector:V8HI [(const_int 1) (const_int 1)
22010 (const_int 1) (const_int 1)
22011 (const_int 1) (const_int 1)
22012 (const_int 1) (const_int 1)]))
22013 (const_int 1)))]
22014 "TARGET_SSE2"
22015 "pavgw\t{%2, %0|%0, %2}"
22016 [(set_attr "type" "sseiadd")
22017 (set_attr "mode" "TI")])
22018
22019 ;; @@@ this isn't the right representation.
22020 (define_insn "sse2_psadbw"
22021 [(set (match_operand:V2DI 0 "register_operand" "=x")
22022 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22023 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22024 UNSPEC_PSADBW))]
22025 "TARGET_SSE2"
22026 "psadbw\t{%2, %0|%0, %2}"
22027 [(set_attr "type" "sseiadd")
22028 (set_attr "mode" "TI")])
22029
22030
22031 ;; MMX insert/extract/shuffle
22032
22033 (define_insn "sse2_pinsrw"
22034 [(set (match_operand:V8HI 0 "register_operand" "=x")
22035 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22036 (vec_duplicate:V8HI
22037 (truncate:HI
22038 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22039 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22040 "TARGET_SSE2"
22041 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22042 [(set_attr "type" "ssecvt")
22043 (set_attr "mode" "TI")])
22044
22045 (define_insn "sse2_pextrw"
22046 [(set (match_operand:SI 0 "register_operand" "=r")
22047 (zero_extend:SI
22048 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22049 (parallel
22050 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22051 "TARGET_SSE2"
22052 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22053 [(set_attr "type" "ssecvt")
22054 (set_attr "mode" "TI")])
22055
22056 (define_insn "sse2_pshufd"
22057 [(set (match_operand:V4SI 0 "register_operand" "=x")
22058 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22059 (match_operand:SI 2 "immediate_operand" "i")]
22060 UNSPEC_SHUFFLE))]
22061 "TARGET_SSE2"
22062 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22063 [(set_attr "type" "ssecvt")
22064 (set_attr "mode" "TI")])
22065
22066 (define_insn "sse2_pshuflw"
22067 [(set (match_operand:V8HI 0 "register_operand" "=x")
22068 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22069 (match_operand:SI 2 "immediate_operand" "i")]
22070 UNSPEC_PSHUFLW))]
22071 "TARGET_SSE2"
22072 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22073 [(set_attr "type" "ssecvt")
22074 (set_attr "mode" "TI")])
22075
22076 (define_insn "sse2_pshufhw"
22077 [(set (match_operand:V8HI 0 "register_operand" "=x")
22078 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22079 (match_operand:SI 2 "immediate_operand" "i")]
22080 UNSPEC_PSHUFHW))]
22081 "TARGET_SSE2"
22082 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22083 [(set_attr "type" "ssecvt")
22084 (set_attr "mode" "TI")])
22085
22086 ;; MMX mask-generating comparisons
22087
22088 (define_insn "eqv16qi3"
22089 [(set (match_operand:V16QI 0 "register_operand" "=x")
22090 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22091 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22092 "TARGET_SSE2"
22093 "pcmpeqb\t{%2, %0|%0, %2}"
22094 [(set_attr "type" "ssecmp")
22095 (set_attr "mode" "TI")])
22096
22097 (define_insn "eqv8hi3"
22098 [(set (match_operand:V8HI 0 "register_operand" "=x")
22099 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22100 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22101 "TARGET_SSE2"
22102 "pcmpeqw\t{%2, %0|%0, %2}"
22103 [(set_attr "type" "ssecmp")
22104 (set_attr "mode" "TI")])
22105
22106 (define_insn "eqv4si3"
22107 [(set (match_operand:V4SI 0 "register_operand" "=x")
22108 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22109 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22110 "TARGET_SSE2"
22111 "pcmpeqd\t{%2, %0|%0, %2}"
22112 [(set_attr "type" "ssecmp")
22113 (set_attr "mode" "TI")])
22114
22115 (define_insn "gtv16qi3"
22116 [(set (match_operand:V16QI 0 "register_operand" "=x")
22117 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22118 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22119 "TARGET_SSE2"
22120 "pcmpgtb\t{%2, %0|%0, %2}"
22121 [(set_attr "type" "ssecmp")
22122 (set_attr "mode" "TI")])
22123
22124 (define_insn "gtv8hi3"
22125 [(set (match_operand:V8HI 0 "register_operand" "=x")
22126 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22127 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22128 "TARGET_SSE2"
22129 "pcmpgtw\t{%2, %0|%0, %2}"
22130 [(set_attr "type" "ssecmp")
22131 (set_attr "mode" "TI")])
22132
22133 (define_insn "gtv4si3"
22134 [(set (match_operand:V4SI 0 "register_operand" "=x")
22135 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22136 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22137 "TARGET_SSE2"
22138 "pcmpgtd\t{%2, %0|%0, %2}"
22139 [(set_attr "type" "ssecmp")
22140 (set_attr "mode" "TI")])
22141
22142
22143 ;; MMX max/min insns
22144
22145 (define_insn "umaxv16qi3"
22146 [(set (match_operand:V16QI 0 "register_operand" "=x")
22147 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22148 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22149 "TARGET_SSE2"
22150 "pmaxub\t{%2, %0|%0, %2}"
22151 [(set_attr "type" "sseiadd")
22152 (set_attr "mode" "TI")])
22153
22154 (define_insn "smaxv8hi3"
22155 [(set (match_operand:V8HI 0 "register_operand" "=x")
22156 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22157 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22158 "TARGET_SSE2"
22159 "pmaxsw\t{%2, %0|%0, %2}"
22160 [(set_attr "type" "sseiadd")
22161 (set_attr "mode" "TI")])
22162
22163 (define_insn "uminv16qi3"
22164 [(set (match_operand:V16QI 0 "register_operand" "=x")
22165 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22166 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22167 "TARGET_SSE2"
22168 "pminub\t{%2, %0|%0, %2}"
22169 [(set_attr "type" "sseiadd")
22170 (set_attr "mode" "TI")])
22171
22172 (define_insn "sminv8hi3"
22173 [(set (match_operand:V8HI 0 "register_operand" "=x")
22174 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22175 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22176 "TARGET_SSE2"
22177 "pminsw\t{%2, %0|%0, %2}"
22178 [(set_attr "type" "sseiadd")
22179 (set_attr "mode" "TI")])
22180
22181
22182 ;; MMX shifts
22183
22184 (define_insn "ashrv8hi3"
22185 [(set (match_operand:V8HI 0 "register_operand" "=x")
22186 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22187 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22188 "TARGET_SSE2"
22189 "psraw\t{%2, %0|%0, %2}"
22190 [(set_attr "type" "sseishft")
22191 (set_attr "mode" "TI")])
22192
22193 (define_insn "ashrv4si3"
22194 [(set (match_operand:V4SI 0 "register_operand" "=x")
22195 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22196 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22197 "TARGET_SSE2"
22198 "psrad\t{%2, %0|%0, %2}"
22199 [(set_attr "type" "sseishft")
22200 (set_attr "mode" "TI")])
22201
22202 (define_insn "lshrv8hi3"
22203 [(set (match_operand:V8HI 0 "register_operand" "=x")
22204 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22205 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22206 "TARGET_SSE2"
22207 "psrlw\t{%2, %0|%0, %2}"
22208 [(set_attr "type" "sseishft")
22209 (set_attr "mode" "TI")])
22210
22211 (define_insn "lshrv4si3"
22212 [(set (match_operand:V4SI 0 "register_operand" "=x")
22213 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22214 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22215 "TARGET_SSE2"
22216 "psrld\t{%2, %0|%0, %2}"
22217 [(set_attr "type" "sseishft")
22218 (set_attr "mode" "TI")])
22219
22220 (define_insn "lshrv2di3"
22221 [(set (match_operand:V2DI 0 "register_operand" "=x")
22222 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22223 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22224 "TARGET_SSE2"
22225 "psrlq\t{%2, %0|%0, %2}"
22226 [(set_attr "type" "sseishft")
22227 (set_attr "mode" "TI")])
22228
22229 (define_insn "ashlv8hi3"
22230 [(set (match_operand:V8HI 0 "register_operand" "=x")
22231 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22232 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22233 "TARGET_SSE2"
22234 "psllw\t{%2, %0|%0, %2}"
22235 [(set_attr "type" "sseishft")
22236 (set_attr "mode" "TI")])
22237
22238 (define_insn "ashlv4si3"
22239 [(set (match_operand:V4SI 0 "register_operand" "=x")
22240 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22241 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22242 "TARGET_SSE2"
22243 "pslld\t{%2, %0|%0, %2}"
22244 [(set_attr "type" "sseishft")
22245 (set_attr "mode" "TI")])
22246
22247 (define_insn "ashlv2di3"
22248 [(set (match_operand:V2DI 0 "register_operand" "=x")
22249 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22250 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22251 "TARGET_SSE2"
22252 "psllq\t{%2, %0|%0, %2}"
22253 [(set_attr "type" "sseishft")
22254 (set_attr "mode" "TI")])
22255
22256 (define_insn "ashrv8hi3_ti"
22257 [(set (match_operand:V8HI 0 "register_operand" "=x")
22258 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22259 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22260 "TARGET_SSE2"
22261 "psraw\t{%2, %0|%0, %2}"
22262 [(set_attr "type" "sseishft")
22263 (set_attr "mode" "TI")])
22264
22265 (define_insn "ashrv4si3_ti"
22266 [(set (match_operand:V4SI 0 "register_operand" "=x")
22267 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22268 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22269 "TARGET_SSE2"
22270 "psrad\t{%2, %0|%0, %2}"
22271 [(set_attr "type" "sseishft")
22272 (set_attr "mode" "TI")])
22273
22274 (define_insn "lshrv8hi3_ti"
22275 [(set (match_operand:V8HI 0 "register_operand" "=x")
22276 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22277 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22278 "TARGET_SSE2"
22279 "psrlw\t{%2, %0|%0, %2}"
22280 [(set_attr "type" "sseishft")
22281 (set_attr "mode" "TI")])
22282
22283 (define_insn "lshrv4si3_ti"
22284 [(set (match_operand:V4SI 0 "register_operand" "=x")
22285 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22286 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22287 "TARGET_SSE2"
22288 "psrld\t{%2, %0|%0, %2}"
22289 [(set_attr "type" "sseishft")
22290 (set_attr "mode" "TI")])
22291
22292 (define_insn "lshrv2di3_ti"
22293 [(set (match_operand:V2DI 0 "register_operand" "=x")
22294 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22295 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22296 "TARGET_SSE2"
22297 "psrlq\t{%2, %0|%0, %2}"
22298 [(set_attr "type" "sseishft")
22299 (set_attr "mode" "TI")])
22300
22301 (define_insn "ashlv8hi3_ti"
22302 [(set (match_operand:V8HI 0 "register_operand" "=x")
22303 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22304 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22305 "TARGET_SSE2"
22306 "psllw\t{%2, %0|%0, %2}"
22307 [(set_attr "type" "sseishft")
22308 (set_attr "mode" "TI")])
22309
22310 (define_insn "ashlv4si3_ti"
22311 [(set (match_operand:V4SI 0 "register_operand" "=x")
22312 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22313 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22314 "TARGET_SSE2"
22315 "pslld\t{%2, %0|%0, %2}"
22316 [(set_attr "type" "sseishft")
22317 (set_attr "mode" "TI")])
22318
22319 (define_insn "ashlv2di3_ti"
22320 [(set (match_operand:V2DI 0 "register_operand" "=x")
22321 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22322 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22323 "TARGET_SSE2"
22324 "psllq\t{%2, %0|%0, %2}"
22325 [(set_attr "type" "sseishft")
22326 (set_attr "mode" "TI")])
22327
22328 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22329 ;; we wouldn't need here it since we never generate TImode arithmetic.
22330
22331 ;; There has to be some kind of prize for the weirdest new instruction...
22332 (define_insn "sse2_ashlti3"
22333 [(set (match_operand:TI 0 "register_operand" "=x")
22334 (unspec:TI
22335 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22336 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22337 (const_int 8)))] UNSPEC_NOP))]
22338 "TARGET_SSE2"
22339 "pslldq\t{%2, %0|%0, %2}"
22340 [(set_attr "type" "sseishft")
22341 (set_attr "mode" "TI")])
22342
22343 (define_insn "sse2_lshrti3"
22344 [(set (match_operand:TI 0 "register_operand" "=x")
22345 (unspec:TI
22346 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22347 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22348 (const_int 8)))] UNSPEC_NOP))]
22349 "TARGET_SSE2"
22350 "psrldq\t{%2, %0|%0, %2}"
22351 [(set_attr "type" "sseishft")
22352 (set_attr "mode" "TI")])
22353
22354 ;; SSE unpack
22355
22356 (define_insn "sse2_unpckhpd"
22357 [(set (match_operand:V2DF 0 "register_operand" "=x")
22358 (vec_concat:V2DF
22359 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22360 (parallel [(const_int 1)]))
22361 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22362 (parallel [(const_int 0)]))))]
22363 "TARGET_SSE2"
22364 "unpckhpd\t{%2, %0|%0, %2}"
22365 [(set_attr "type" "ssecvt")
22366 (set_attr "mode" "TI")])
22367
22368 (define_insn "sse2_unpcklpd"
22369 [(set (match_operand:V2DF 0 "register_operand" "=x")
22370 (vec_concat:V2DF
22371 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22372 (parallel [(const_int 0)]))
22373 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22374 (parallel [(const_int 1)]))))]
22375 "TARGET_SSE2"
22376 "unpcklpd\t{%2, %0|%0, %2}"
22377 [(set_attr "type" "ssecvt")
22378 (set_attr "mode" "TI")])
22379
22380 ;; MMX pack/unpack insns.
22381
22382 (define_insn "sse2_packsswb"
22383 [(set (match_operand:V16QI 0 "register_operand" "=x")
22384 (vec_concat:V16QI
22385 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22386 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22387 "TARGET_SSE2"
22388 "packsswb\t{%2, %0|%0, %2}"
22389 [(set_attr "type" "ssecvt")
22390 (set_attr "mode" "TI")])
22391
22392 (define_insn "sse2_packssdw"
22393 [(set (match_operand:V8HI 0 "register_operand" "=x")
22394 (vec_concat:V8HI
22395 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22396 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22397 "TARGET_SSE2"
22398 "packssdw\t{%2, %0|%0, %2}"
22399 [(set_attr "type" "ssecvt")
22400 (set_attr "mode" "TI")])
22401
22402 (define_insn "sse2_packuswb"
22403 [(set (match_operand:V16QI 0 "register_operand" "=x")
22404 (vec_concat:V16QI
22405 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22406 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22407 "TARGET_SSE2"
22408 "packuswb\t{%2, %0|%0, %2}"
22409 [(set_attr "type" "ssecvt")
22410 (set_attr "mode" "TI")])
22411
22412 (define_insn "sse2_punpckhbw"
22413 [(set (match_operand:V16QI 0 "register_operand" "=x")
22414 (vec_merge:V16QI
22415 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22416 (parallel [(const_int 8) (const_int 0)
22417 (const_int 9) (const_int 1)
22418 (const_int 10) (const_int 2)
22419 (const_int 11) (const_int 3)
22420 (const_int 12) (const_int 4)
22421 (const_int 13) (const_int 5)
22422 (const_int 14) (const_int 6)
22423 (const_int 15) (const_int 7)]))
22424 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22425 (parallel [(const_int 0) (const_int 8)
22426 (const_int 1) (const_int 9)
22427 (const_int 2) (const_int 10)
22428 (const_int 3) (const_int 11)
22429 (const_int 4) (const_int 12)
22430 (const_int 5) (const_int 13)
22431 (const_int 6) (const_int 14)
22432 (const_int 7) (const_int 15)]))
22433 (const_int 21845)))]
22434 "TARGET_SSE2"
22435 "punpckhbw\t{%2, %0|%0, %2}"
22436 [(set_attr "type" "ssecvt")
22437 (set_attr "mode" "TI")])
22438
22439 (define_insn "sse2_punpckhwd"
22440 [(set (match_operand:V8HI 0 "register_operand" "=x")
22441 (vec_merge:V8HI
22442 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22443 (parallel [(const_int 4) (const_int 0)
22444 (const_int 5) (const_int 1)
22445 (const_int 6) (const_int 2)
22446 (const_int 7) (const_int 3)]))
22447 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22448 (parallel [(const_int 0) (const_int 4)
22449 (const_int 1) (const_int 5)
22450 (const_int 2) (const_int 6)
22451 (const_int 3) (const_int 7)]))
22452 (const_int 85)))]
22453 "TARGET_SSE2"
22454 "punpckhwd\t{%2, %0|%0, %2}"
22455 [(set_attr "type" "ssecvt")
22456 (set_attr "mode" "TI")])
22457
22458 (define_insn "sse2_punpckhdq"
22459 [(set (match_operand:V4SI 0 "register_operand" "=x")
22460 (vec_merge:V4SI
22461 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22462 (parallel [(const_int 2) (const_int 0)
22463 (const_int 3) (const_int 1)]))
22464 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22465 (parallel [(const_int 0) (const_int 2)
22466 (const_int 1) (const_int 3)]))
22467 (const_int 5)))]
22468 "TARGET_SSE2"
22469 "punpckhdq\t{%2, %0|%0, %2}"
22470 [(set_attr "type" "ssecvt")
22471 (set_attr "mode" "TI")])
22472
22473 (define_insn "sse2_punpcklbw"
22474 [(set (match_operand:V16QI 0 "register_operand" "=x")
22475 (vec_merge:V16QI
22476 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22477 (parallel [(const_int 0) (const_int 8)
22478 (const_int 1) (const_int 9)
22479 (const_int 2) (const_int 10)
22480 (const_int 3) (const_int 11)
22481 (const_int 4) (const_int 12)
22482 (const_int 5) (const_int 13)
22483 (const_int 6) (const_int 14)
22484 (const_int 7) (const_int 15)]))
22485 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22486 (parallel [(const_int 8) (const_int 0)
22487 (const_int 9) (const_int 1)
22488 (const_int 10) (const_int 2)
22489 (const_int 11) (const_int 3)
22490 (const_int 12) (const_int 4)
22491 (const_int 13) (const_int 5)
22492 (const_int 14) (const_int 6)
22493 (const_int 15) (const_int 7)]))
22494 (const_int 21845)))]
22495 "TARGET_SSE2"
22496 "punpcklbw\t{%2, %0|%0, %2}"
22497 [(set_attr "type" "ssecvt")
22498 (set_attr "mode" "TI")])
22499
22500 (define_insn "sse2_punpcklwd"
22501 [(set (match_operand:V8HI 0 "register_operand" "=x")
22502 (vec_merge:V8HI
22503 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22504 (parallel [(const_int 0) (const_int 4)
22505 (const_int 1) (const_int 5)
22506 (const_int 2) (const_int 6)
22507 (const_int 3) (const_int 7)]))
22508 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22509 (parallel [(const_int 4) (const_int 0)
22510 (const_int 5) (const_int 1)
22511 (const_int 6) (const_int 2)
22512 (const_int 7) (const_int 3)]))
22513 (const_int 85)))]
22514 "TARGET_SSE2"
22515 "punpcklwd\t{%2, %0|%0, %2}"
22516 [(set_attr "type" "ssecvt")
22517 (set_attr "mode" "TI")])
22518
22519 (define_insn "sse2_punpckldq"
22520 [(set (match_operand:V4SI 0 "register_operand" "=x")
22521 (vec_merge:V4SI
22522 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22523 (parallel [(const_int 0) (const_int 2)
22524 (const_int 1) (const_int 3)]))
22525 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22526 (parallel [(const_int 2) (const_int 0)
22527 (const_int 3) (const_int 1)]))
22528 (const_int 5)))]
22529 "TARGET_SSE2"
22530 "punpckldq\t{%2, %0|%0, %2}"
22531 [(set_attr "type" "ssecvt")
22532 (set_attr "mode" "TI")])
22533
22534 (define_insn "sse2_punpcklqdq"
22535 [(set (match_operand:V2DI 0 "register_operand" "=x")
22536 (vec_merge:V2DI
22537 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22538 (parallel [(const_int 1)
22539 (const_int 0)]))
22540 (match_operand:V2DI 1 "register_operand" "0")
22541 (const_int 1)))]
22542 "TARGET_SSE2"
22543 "punpcklqdq\t{%2, %0|%0, %2}"
22544 [(set_attr "type" "ssecvt")
22545 (set_attr "mode" "TI")])
22546
22547 (define_insn "sse2_punpckhqdq"
22548 [(set (match_operand:V2DI 0 "register_operand" "=x")
22549 (vec_merge:V2DI
22550 (match_operand:V2DI 1 "register_operand" "0")
22551 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22552 (parallel [(const_int 1)
22553 (const_int 0)]))
22554 (const_int 1)))]
22555 "TARGET_SSE2"
22556 "punpckhqdq\t{%2, %0|%0, %2}"
22557 [(set_attr "type" "ssecvt")
22558 (set_attr "mode" "TI")])
22559
22560 ;; SSE2 moves
22561
22562 (define_insn "sse2_movapd"
22563 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22564 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22565 UNSPEC_MOVA))]
22566 "TARGET_SSE2
22567 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22568 "movapd\t{%1, %0|%0, %1}"
22569 [(set_attr "type" "ssemov")
22570 (set_attr "mode" "V2DF")])
22571
22572 (define_insn "sse2_movupd"
22573 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22574 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22575 UNSPEC_MOVU))]
22576 "TARGET_SSE2
22577 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22578 "movupd\t{%1, %0|%0, %1}"
22579 [(set_attr "type" "ssecvt")
22580 (set_attr "mode" "V2DF")])
22581
22582 (define_insn "sse2_movdqa"
22583 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22584 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22585 UNSPEC_MOVA))]
22586 "TARGET_SSE2
22587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22588 "movdqa\t{%1, %0|%0, %1}"
22589 [(set_attr "type" "ssemov")
22590 (set_attr "mode" "TI")])
22591
22592 (define_insn "sse2_movdqu"
22593 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22594 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22595 UNSPEC_MOVU))]
22596 "TARGET_SSE2
22597 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22598 "movdqu\t{%1, %0|%0, %1}"
22599 [(set_attr "type" "ssecvt")
22600 (set_attr "mode" "TI")])
22601
22602 (define_insn "sse2_movdq2q"
22603 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22604 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22605 (parallel [(const_int 0)])))]
22606 "TARGET_SSE2 && !TARGET_64BIT"
22607 "@
22608 movq\t{%1, %0|%0, %1}
22609 movdq2q\t{%1, %0|%0, %1}"
22610 [(set_attr "type" "ssecvt")
22611 (set_attr "mode" "TI")])
22612
22613 (define_insn "sse2_movdq2q_rex64"
22614 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22615 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22616 (parallel [(const_int 0)])))]
22617 "TARGET_SSE2 && TARGET_64BIT"
22618 "@
22619 movq\t{%1, %0|%0, %1}
22620 movdq2q\t{%1, %0|%0, %1}
22621 movd\t{%1, %0|%0, %1}"
22622 [(set_attr "type" "ssecvt")
22623 (set_attr "mode" "TI")])
22624
22625 (define_insn "sse2_movq2dq"
22626 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22627 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22628 (const_int 0)))]
22629 "TARGET_SSE2 && !TARGET_64BIT"
22630 "@
22631 movq\t{%1, %0|%0, %1}
22632 movq2dq\t{%1, %0|%0, %1}"
22633 [(set_attr "type" "ssecvt,ssemov")
22634 (set_attr "mode" "TI")])
22635
22636 (define_insn "sse2_movq2dq_rex64"
22637 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22638 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22639 (const_int 0)))]
22640 "TARGET_SSE2 && TARGET_64BIT"
22641 "@
22642 movq\t{%1, %0|%0, %1}
22643 movq2dq\t{%1, %0|%0, %1}
22644 movd\t{%1, %0|%0, %1}"
22645 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22646 (set_attr "mode" "TI")])
22647
22648 (define_insn "sse2_movq"
22649 [(set (match_operand:V2DI 0 "register_operand" "=x")
22650 (vec_concat:V2DI (vec_select:DI
22651 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22652 (parallel [(const_int 0)]))
22653 (const_int 0)))]
22654 "TARGET_SSE2"
22655 "movq\t{%1, %0|%0, %1}"
22656 [(set_attr "type" "ssemov")
22657 (set_attr "mode" "TI")])
22658
22659 (define_insn "sse2_loadd"
22660 [(set (match_operand:V4SI 0 "register_operand" "=x")
22661 (vec_merge:V4SI
22662 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22663 (const_vector:V4SI [(const_int 0)
22664 (const_int 0)
22665 (const_int 0)
22666 (const_int 0)])
22667 (const_int 1)))]
22668 "TARGET_SSE2"
22669 "movd\t{%1, %0|%0, %1}"
22670 [(set_attr "type" "ssemov")
22671 (set_attr "mode" "TI")])
22672
22673 (define_insn "sse2_stored"
22674 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22675 (vec_select:SI
22676 (match_operand:V4SI 1 "register_operand" "x")
22677 (parallel [(const_int 0)])))]
22678 "TARGET_SSE2"
22679 "movd\t{%1, %0|%0, %1}"
22680 [(set_attr "type" "ssemov")
22681 (set_attr "mode" "TI")])
22682
22683 (define_insn "sse2_movhpd"
22684 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22685 (vec_merge:V2DF
22686 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22687 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22688 (const_int 2)))]
22689 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22690 "movhpd\t{%2, %0|%0, %2}"
22691 [(set_attr "type" "ssecvt")
22692 (set_attr "mode" "V2DF")])
22693
22694 (define_insn "sse2_movlpd"
22695 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22696 (vec_merge:V2DF
22697 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22698 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22699 (const_int 1)))]
22700 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22701 "movlpd\t{%2, %0|%0, %2}"
22702 [(set_attr "type" "ssecvt")
22703 (set_attr "mode" "V2DF")])
22704
22705 (define_expand "sse2_loadsd"
22706 [(match_operand:V2DF 0 "register_operand" "")
22707 (match_operand:DF 1 "memory_operand" "")]
22708 "TARGET_SSE2"
22709 {
22710 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22711 CONST0_RTX (V2DFmode)));
22712 DONE;
22713 })
22714
22715 (define_insn "sse2_loadsd_1"
22716 [(set (match_operand:V2DF 0 "register_operand" "=x")
22717 (vec_merge:V2DF
22718 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22719 (match_operand:V2DF 2 "const0_operand" "X")
22720 (const_int 1)))]
22721 "TARGET_SSE2"
22722 "movsd\t{%1, %0|%0, %1}"
22723 [(set_attr "type" "ssecvt")
22724 (set_attr "mode" "DF")])
22725
22726 (define_insn "sse2_movsd"
22727 [(set (match_operand:V2DF 0 "register_operand" "=x")
22728 (vec_merge:V2DF
22729 (match_operand:V2DF 1 "register_operand" "0")
22730 (match_operand:V2DF 2 "register_operand" "x")
22731 (const_int 1)))]
22732 "TARGET_SSE2"
22733 "movsd\t{%2, %0|%0, %2}"
22734 [(set_attr "type" "ssecvt")
22735 (set_attr "mode" "DF")])
22736
22737 (define_insn "sse2_storesd"
22738 [(set (match_operand:DF 0 "memory_operand" "=m")
22739 (vec_select:DF
22740 (match_operand:V2DF 1 "register_operand" "x")
22741 (parallel [(const_int 0)])))]
22742 "TARGET_SSE2"
22743 "movsd\t{%1, %0|%0, %1}"
22744 [(set_attr "type" "ssecvt")
22745 (set_attr "mode" "DF")])
22746
22747 (define_insn "sse2_shufpd"
22748 [(set (match_operand:V2DF 0 "register_operand" "=x")
22749 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22750 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22751 (match_operand:SI 3 "immediate_operand" "i")]
22752 UNSPEC_SHUFFLE))]
22753 "TARGET_SSE2"
22754 ;; @@@ check operand order for intel/nonintel syntax
22755 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22756 [(set_attr "type" "ssecvt")
22757 (set_attr "mode" "V2DF")])
22758
22759 (define_insn "sse2_clflush"
22760 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22761 UNSPECV_CLFLUSH)]
22762 "TARGET_SSE2"
22763 "clflush %0"
22764 [(set_attr "type" "sse")
22765 (set_attr "memory" "unknown")])
22766
22767 (define_expand "sse2_mfence"
22768 [(set (match_dup 0)
22769 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22770 "TARGET_SSE2"
22771 {
22772 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22773 MEM_VOLATILE_P (operands[0]) = 1;
22774 })
22775
22776 (define_insn "*mfence_insn"
22777 [(set (match_operand:BLK 0 "" "")
22778 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22779 "TARGET_SSE2"
22780 "mfence"
22781 [(set_attr "type" "sse")
22782 (set_attr "memory" "unknown")])
22783
22784 (define_expand "sse2_lfence"
22785 [(set (match_dup 0)
22786 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22787 "TARGET_SSE2"
22788 {
22789 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22790 MEM_VOLATILE_P (operands[0]) = 1;
22791 })
22792
22793 (define_insn "*lfence_insn"
22794 [(set (match_operand:BLK 0 "" "")
22795 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22796 "TARGET_SSE2"
22797 "lfence"
22798 [(set_attr "type" "sse")
22799 (set_attr "memory" "unknown")])
22800
22801 ;; PNI
22802
22803 (define_insn "mwait"
22804 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22805 (match_operand:SI 1 "register_operand" "c")]
22806 UNSPECV_MWAIT)]
22807 "TARGET_PNI"
22808 "mwait\t%0, %1"
22809 [(set_attr "length" "3")])
22810
22811 (define_insn "monitor"
22812 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22813 (match_operand:SI 1 "register_operand" "c")
22814 (match_operand:SI 2 "register_operand" "d")]
22815 UNSPECV_MONITOR)]
22816 "TARGET_PNI"
22817 "monitor\t%0, %1, %2"
22818 [(set_attr "length" "3")])
22819
22820 ;; PNI arithmetic
22821
22822 (define_insn "addsubv4sf3"
22823 [(set (match_operand:V4SF 0 "register_operand" "=x")
22824 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22825 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22826 UNSPEC_ADDSUB))]
22827 "TARGET_PNI"
22828 "addsubps\t{%2, %0|%0, %2}"
22829 [(set_attr "type" "sseadd")
22830 (set_attr "mode" "V4SF")])
22831
22832 (define_insn "addsubv2df3"
22833 [(set (match_operand:V2DF 0 "register_operand" "=x")
22834 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22835 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22836 UNSPEC_ADDSUB))]
22837 "TARGET_PNI"
22838 "addsubpd\t{%2, %0|%0, %2}"
22839 [(set_attr "type" "sseadd")
22840 (set_attr "mode" "V2DF")])
22841
22842 (define_insn "haddv4sf3"
22843 [(set (match_operand:V4SF 0 "register_operand" "=x")
22844 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22845 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22846 UNSPEC_HADD))]
22847 "TARGET_PNI"
22848 "haddps\t{%2, %0|%0, %2}"
22849 [(set_attr "type" "sseadd")
22850 (set_attr "mode" "V4SF")])
22851
22852 (define_insn "haddv2df3"
22853 [(set (match_operand:V2DF 0 "register_operand" "=x")
22854 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22855 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22856 UNSPEC_HADD))]
22857 "TARGET_PNI"
22858 "haddpd\t{%2, %0|%0, %2}"
22859 [(set_attr "type" "sseadd")
22860 (set_attr "mode" "V2DF")])
22861
22862 (define_insn "hsubv4sf3"
22863 [(set (match_operand:V4SF 0 "register_operand" "=x")
22864 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22865 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22866 UNSPEC_HSUB))]
22867 "TARGET_PNI"
22868 "hsubps\t{%2, %0|%0, %2}"
22869 [(set_attr "type" "sseadd")
22870 (set_attr "mode" "V4SF")])
22871
22872 (define_insn "hsubv2df3"
22873 [(set (match_operand:V2DF 0 "register_operand" "=x")
22874 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22875 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22876 UNSPEC_HSUB))]
22877 "TARGET_PNI"
22878 "hsubpd\t{%2, %0|%0, %2}"
22879 [(set_attr "type" "sseadd")
22880 (set_attr "mode" "V2DF")])
22881
22882 (define_insn "movshdup"
22883 [(set (match_operand:V4SF 0 "register_operand" "=x")
22884 (unspec:V4SF
22885 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22886 "TARGET_PNI"
22887 "movshdup\t{%1, %0|%0, %1}"
22888 [(set_attr "type" "sse")
22889 (set_attr "mode" "V4SF")])
22890
22891 (define_insn "movsldup"
22892 [(set (match_operand:V4SF 0 "register_operand" "=x")
22893 (unspec:V4SF
22894 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22895 "TARGET_PNI"
22896 "movsldup\t{%1, %0|%0, %1}"
22897 [(set_attr "type" "sse")
22898 (set_attr "mode" "V4SF")])
22899
22900 (define_insn "lddqu"
22901 [(set (match_operand:V16QI 0 "register_operand" "=x")
22902 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22903 UNSPEC_LDQQU))]
22904 "TARGET_PNI"
22905 "lddqu\t{%1, %0|%0, %1}"
22906 [(set_attr "type" "ssecvt")
22907 (set_attr "mode" "TI")])
22908
22909 (define_insn "loadddup"
22910 [(set (match_operand:V2DF 0 "register_operand" "=x")
22911 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
22912 "TARGET_PNI"
22913 "movddup\t{%1, %0|%0, %1}"
22914 [(set_attr "type" "ssecvt")
22915 (set_attr "mode" "DF")])
22916
22917 (define_insn "movddup"
22918 [(set (match_operand:V2DF 0 "register_operand" "=x")
22919 (vec_duplicate:V2DF
22920 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
22921 (parallel [(const_int 0)]))))]
22922 "TARGET_PNI"
22923 "movddup\t{%1, %0|%0, %1}"
22924 [(set_attr "type" "ssecvt")
22925 (set_attr "mode" "DF")])