alias.c (rtx_equal_for_memref_p): Use predicates to test rtx classes and new rtx...
[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, 2004
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 [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1318 (const_int 0))
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1320 (const_int 0))))
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1326 (const_int 0))
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1329 ]
1330 (const_string "imov")))
1331 (set (attr "mode")
1332 (cond [(eq_attr "type" "imovx")
1333 (const_string "SI")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1336 (const_string "SI")
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1339 (const_int 0))
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1341 (const_int 0))))
1342 (const_string "SI")
1343 ]
1344 (const_string "HI")))])
1345
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1353 "@
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1362
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1367 "@
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1376
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1380 (set (match_dup 1)
1381 (match_dup 0))]
1382 "TARGET_PARTIAL_REG_STALL"
1383 "xchg{w}\t%1, %0"
1384 [(set_attr "type" "imov")
1385 (set_attr "pent_pair" "np")
1386 (set_attr "mode" "HI")
1387 (set_attr "modrm" "0")
1388 (set_attr "ppro_uops" "few")])
1389
1390 (define_insn "*swaphi_2"
1391 [(set (match_operand:HI 0 "register_operand" "+r")
1392 (match_operand:HI 1 "register_operand" "+r"))
1393 (set (match_dup 1)
1394 (match_dup 0))]
1395 "! TARGET_PARTIAL_REG_STALL"
1396 "xchg{l}\t%k1, %k0"
1397 [(set_attr "type" "imov")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "mode" "SI")
1400 (set_attr "modrm" "0")
1401 (set_attr "ppro_uops" "few")])
1402
1403 (define_expand "movstricthi"
1404 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1405 (match_operand:HI 1 "general_operand" ""))]
1406 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407 {
1408 /* Don't generate memory->memory moves, go through a register */
1409 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1410 operands[1] = force_reg (HImode, operands[1]);
1411 })
1412
1413 (define_insn "*movstricthi_1"
1414 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1415 (match_operand:HI 1 "general_operand" "rn,m"))]
1416 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1417 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1418 "mov{w}\t{%1, %0|%0, %1}"
1419 [(set_attr "type" "imov")
1420 (set_attr "mode" "HI")])
1421
1422 (define_insn "*movstricthi_xor"
1423 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1424 (match_operand:HI 1 "const0_operand" "i"))
1425 (clobber (reg:CC 17))]
1426 "reload_completed
1427 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1428 "xor{w}\t{%0, %0|%0, %0}"
1429 [(set_attr "type" "alu1")
1430 (set_attr "mode" "HI")
1431 (set_attr "length_immediate" "0")])
1432
1433 (define_expand "movqi"
1434 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1435 (match_operand:QI 1 "general_operand" ""))]
1436 ""
1437 "ix86_expand_move (QImode, operands); DONE;")
1438
1439 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1440 ;; "push a byte". But actually we use pushw, which has the effect
1441 ;; of rounding the amount pushed up to a halfword.
1442
1443 (define_insn "*pushqi2"
1444 [(set (match_operand:QI 0 "push_operand" "=X,X")
1445 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1446 "!TARGET_64BIT"
1447 "@
1448 push{w}\t{|word ptr }%1
1449 push{w}\t%w1"
1450 [(set_attr "type" "push")
1451 (set_attr "mode" "HI")])
1452
1453 ;; For 64BIT abi we always round up to 8 bytes.
1454 (define_insn "*pushqi2_rex64"
1455 [(set (match_operand:QI 0 "push_operand" "=X")
1456 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1457 "TARGET_64BIT"
1458 "push{q}\t%q1"
1459 [(set_attr "type" "push")
1460 (set_attr "mode" "QI")])
1461
1462 ;; Situation is quite tricky about when to choose full sized (SImode) move
1463 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1464 ;; partial register dependency machines (such as AMD Athlon), where QImode
1465 ;; moves issue extra dependency and for partial register stalls machines
1466 ;; that don't use QImode patterns (and QImode move cause stall on the next
1467 ;; instruction).
1468 ;;
1469 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1470 ;; register stall machines with, where we use QImode instructions, since
1471 ;; partial register stall can be caused there. Then we use movzx.
1472 (define_insn "*movqi_1"
1473 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1474 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1475 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1476 {
1477 switch (get_attr_type (insn))
1478 {
1479 case TYPE_IMOVX:
1480 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1481 abort ();
1482 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1483 default:
1484 if (get_attr_mode (insn) == MODE_SI)
1485 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1486 else
1487 return "mov{b}\t{%1, %0|%0, %1}";
1488 }
1489 }
1490 [(set (attr "type")
1491 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1492 (const_string "imov")
1493 (and (eq_attr "alternative" "3")
1494 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495 (const_int 0))
1496 (eq (symbol_ref "TARGET_QIMODE_MATH")
1497 (const_int 0))))
1498 (const_string "imov")
1499 (eq_attr "alternative" "3,5")
1500 (const_string "imovx")
1501 (and (ne (symbol_ref "TARGET_MOVX")
1502 (const_int 0))
1503 (eq_attr "alternative" "2"))
1504 (const_string "imovx")
1505 ]
1506 (const_string "imov")))
1507 (set (attr "mode")
1508 (cond [(eq_attr "alternative" "3,4,5")
1509 (const_string "SI")
1510 (eq_attr "alternative" "6")
1511 (const_string "QI")
1512 (eq_attr "type" "imovx")
1513 (const_string "SI")
1514 (and (eq_attr "type" "imov")
1515 (and (eq_attr "alternative" "0,1,2")
1516 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517 (const_int 0))))
1518 (const_string "SI")
1519 ;; Avoid partial register stalls when not using QImode arithmetic
1520 (and (eq_attr "type" "imov")
1521 (and (eq_attr "alternative" "0,1,2")
1522 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1523 (const_int 0))
1524 (eq (symbol_ref "TARGET_QIMODE_MATH")
1525 (const_int 0)))))
1526 (const_string "SI")
1527 ]
1528 (const_string "QI")))])
1529
1530 (define_expand "reload_outqi"
1531 [(parallel [(match_operand:QI 0 "" "=m")
1532 (match_operand:QI 1 "register_operand" "r")
1533 (match_operand:QI 2 "register_operand" "=&q")])]
1534 ""
1535 {
1536 rtx op0, op1, op2;
1537 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1538
1539 if (reg_overlap_mentioned_p (op2, op0))
1540 abort ();
1541 if (! q_regs_operand (op1, QImode))
1542 {
1543 emit_insn (gen_movqi (op2, op1));
1544 op1 = op2;
1545 }
1546 emit_insn (gen_movqi (op0, op1));
1547 DONE;
1548 })
1549
1550 (define_insn "*swapqi"
1551 [(set (match_operand:QI 0 "register_operand" "+r")
1552 (match_operand:QI 1 "register_operand" "+r"))
1553 (set (match_dup 1)
1554 (match_dup 0))]
1555 ""
1556 "xchg{b}\t%1, %0"
1557 [(set_attr "type" "imov")
1558 (set_attr "pent_pair" "np")
1559 (set_attr "mode" "QI")
1560 (set_attr "modrm" "0")
1561 (set_attr "ppro_uops" "few")])
1562
1563 (define_expand "movstrictqi"
1564 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1565 (match_operand:QI 1 "general_operand" ""))]
1566 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1567 {
1568 /* Don't generate memory->memory moves, go through a register. */
1569 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1570 operands[1] = force_reg (QImode, operands[1]);
1571 })
1572
1573 (define_insn "*movstrictqi_1"
1574 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1575 (match_operand:QI 1 "general_operand" "*qn,m"))]
1576 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1577 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1578 "mov{b}\t{%1, %0|%0, %1}"
1579 [(set_attr "type" "imov")
1580 (set_attr "mode" "QI")])
1581
1582 (define_insn "*movstrictqi_xor"
1583 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1584 (match_operand:QI 1 "const0_operand" "i"))
1585 (clobber (reg:CC 17))]
1586 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1587 "xor{b}\t{%0, %0|%0, %0}"
1588 [(set_attr "type" "alu1")
1589 (set_attr "mode" "QI")
1590 (set_attr "length_immediate" "0")])
1591
1592 (define_insn "*movsi_extv_1"
1593 [(set (match_operand:SI 0 "register_operand" "=R")
1594 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1595 (const_int 8)
1596 (const_int 8)))]
1597 ""
1598 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1599 [(set_attr "type" "imovx")
1600 (set_attr "mode" "SI")])
1601
1602 (define_insn "*movhi_extv_1"
1603 [(set (match_operand:HI 0 "register_operand" "=R")
1604 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1605 (const_int 8)
1606 (const_int 8)))]
1607 ""
1608 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1609 [(set_attr "type" "imovx")
1610 (set_attr "mode" "SI")])
1611
1612 (define_insn "*movqi_extv_1"
1613 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1614 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1615 (const_int 8)
1616 (const_int 8)))]
1617 "!TARGET_64BIT"
1618 {
1619 switch (get_attr_type (insn))
1620 {
1621 case TYPE_IMOVX:
1622 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1623 default:
1624 return "mov{b}\t{%h1, %0|%0, %h1}";
1625 }
1626 }
1627 [(set (attr "type")
1628 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1629 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1630 (ne (symbol_ref "TARGET_MOVX")
1631 (const_int 0))))
1632 (const_string "imovx")
1633 (const_string "imov")))
1634 (set (attr "mode")
1635 (if_then_else (eq_attr "type" "imovx")
1636 (const_string "SI")
1637 (const_string "QI")))])
1638
1639 (define_insn "*movqi_extv_1_rex64"
1640 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1641 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1642 (const_int 8)
1643 (const_int 8)))]
1644 "TARGET_64BIT"
1645 {
1646 switch (get_attr_type (insn))
1647 {
1648 case TYPE_IMOVX:
1649 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1650 default:
1651 return "mov{b}\t{%h1, %0|%0, %h1}";
1652 }
1653 }
1654 [(set (attr "type")
1655 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1656 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1657 (ne (symbol_ref "TARGET_MOVX")
1658 (const_int 0))))
1659 (const_string "imovx")
1660 (const_string "imov")))
1661 (set (attr "mode")
1662 (if_then_else (eq_attr "type" "imovx")
1663 (const_string "SI")
1664 (const_string "QI")))])
1665
1666 ;; Stores and loads of ax to arbitrary constant address.
1667 ;; We fake an second form of instruction to force reload to load address
1668 ;; into register when rax is not available
1669 (define_insn "*movabsqi_1_rex64"
1670 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1671 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1672 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1673 "@
1674 movabs{b}\t{%1, %P0|%P0, %1}
1675 mov{b}\t{%1, %a0|%a0, %1}"
1676 [(set_attr "type" "imov")
1677 (set_attr "modrm" "0,*")
1678 (set_attr "length_address" "8,0")
1679 (set_attr "length_immediate" "0,*")
1680 (set_attr "memory" "store")
1681 (set_attr "mode" "QI")])
1682
1683 (define_insn "*movabsqi_2_rex64"
1684 [(set (match_operand:QI 0 "register_operand" "=a,r")
1685 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1686 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1687 "@
1688 movabs{b}\t{%P1, %0|%0, %P1}
1689 mov{b}\t{%a1, %0|%0, %a1}"
1690 [(set_attr "type" "imov")
1691 (set_attr "modrm" "0,*")
1692 (set_attr "length_address" "8,0")
1693 (set_attr "length_immediate" "0")
1694 (set_attr "memory" "load")
1695 (set_attr "mode" "QI")])
1696
1697 (define_insn "*movsi_extzv_1"
1698 [(set (match_operand:SI 0 "register_operand" "=R")
1699 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1700 (const_int 8)
1701 (const_int 8)))]
1702 ""
1703 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1704 [(set_attr "type" "imovx")
1705 (set_attr "mode" "SI")])
1706
1707 (define_insn "*movqi_extzv_2"
1708 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1709 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1710 (const_int 8)
1711 (const_int 8)) 0))]
1712 "!TARGET_64BIT"
1713 {
1714 switch (get_attr_type (insn))
1715 {
1716 case TYPE_IMOVX:
1717 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1718 default:
1719 return "mov{b}\t{%h1, %0|%0, %h1}";
1720 }
1721 }
1722 [(set (attr "type")
1723 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1724 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1725 (ne (symbol_ref "TARGET_MOVX")
1726 (const_int 0))))
1727 (const_string "imovx")
1728 (const_string "imov")))
1729 (set (attr "mode")
1730 (if_then_else (eq_attr "type" "imovx")
1731 (const_string "SI")
1732 (const_string "QI")))])
1733
1734 (define_insn "*movqi_extzv_2_rex64"
1735 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1736 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1737 (const_int 8)
1738 (const_int 8)) 0))]
1739 "TARGET_64BIT"
1740 {
1741 switch (get_attr_type (insn))
1742 {
1743 case TYPE_IMOVX:
1744 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1745 default:
1746 return "mov{b}\t{%h1, %0|%0, %h1}";
1747 }
1748 }
1749 [(set (attr "type")
1750 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1751 (ne (symbol_ref "TARGET_MOVX")
1752 (const_int 0)))
1753 (const_string "imovx")
1754 (const_string "imov")))
1755 (set (attr "mode")
1756 (if_then_else (eq_attr "type" "imovx")
1757 (const_string "SI")
1758 (const_string "QI")))])
1759
1760 (define_insn "movsi_insv_1"
1761 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1762 (const_int 8)
1763 (const_int 8))
1764 (match_operand:SI 1 "general_operand" "Qmn"))]
1765 "!TARGET_64BIT"
1766 "mov{b}\t{%b1, %h0|%h0, %b1}"
1767 [(set_attr "type" "imov")
1768 (set_attr "mode" "QI")])
1769
1770 (define_insn "*movsi_insv_1_rex64"
1771 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1772 (const_int 8)
1773 (const_int 8))
1774 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1775 "TARGET_64BIT"
1776 "mov{b}\t{%b1, %h0|%h0, %b1}"
1777 [(set_attr "type" "imov")
1778 (set_attr "mode" "QI")])
1779
1780 (define_insn "*movqi_insv_2"
1781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1782 (const_int 8)
1783 (const_int 8))
1784 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1785 (const_int 8)))]
1786 ""
1787 "mov{b}\t{%h1, %h0|%h0, %h1}"
1788 [(set_attr "type" "imov")
1789 (set_attr "mode" "QI")])
1790
1791 (define_expand "movdi"
1792 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1793 (match_operand:DI 1 "general_operand" ""))]
1794 ""
1795 "ix86_expand_move (DImode, operands); DONE;")
1796
1797 (define_insn "*pushdi"
1798 [(set (match_operand:DI 0 "push_operand" "=<")
1799 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1800 "!TARGET_64BIT"
1801 "#")
1802
1803 (define_insn "pushdi2_rex64"
1804 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1805 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1806 "TARGET_64BIT"
1807 "@
1808 push{q}\t%1
1809 #"
1810 [(set_attr "type" "push,multi")
1811 (set_attr "mode" "DI")])
1812
1813 ;; Convert impossible pushes of immediate to existing instructions.
1814 ;; First try to get scratch register and go through it. In case this
1815 ;; fails, push sign extended lower part first and then overwrite
1816 ;; upper part by 32bit move.
1817 (define_peephole2
1818 [(match_scratch:DI 2 "r")
1819 (set (match_operand:DI 0 "push_operand" "")
1820 (match_operand:DI 1 "immediate_operand" ""))]
1821 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1822 && !x86_64_immediate_operand (operands[1], DImode)"
1823 [(set (match_dup 2) (match_dup 1))
1824 (set (match_dup 0) (match_dup 2))]
1825 "")
1826
1827 ;; We need to define this as both peepholer and splitter for case
1828 ;; peephole2 pass is not run.
1829 (define_peephole2
1830 [(set (match_operand:DI 0 "push_operand" "")
1831 (match_operand:DI 1 "immediate_operand" ""))]
1832 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1833 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1834 [(set (match_dup 0) (match_dup 1))
1835 (set (match_dup 2) (match_dup 3))]
1836 "split_di (operands + 1, 1, operands + 2, operands + 3);
1837 operands[1] = gen_lowpart (DImode, operands[2]);
1838 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1839 GEN_INT (4)));
1840 ")
1841
1842 (define_split
1843 [(set (match_operand:DI 0 "push_operand" "")
1844 (match_operand:DI 1 "immediate_operand" ""))]
1845 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1846 && !symbolic_operand (operands[1], DImode)
1847 && !x86_64_immediate_operand (operands[1], DImode)"
1848 [(set (match_dup 0) (match_dup 1))
1849 (set (match_dup 2) (match_dup 3))]
1850 "split_di (operands + 1, 1, operands + 2, operands + 3);
1851 operands[1] = gen_lowpart (DImode, operands[2]);
1852 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1853 GEN_INT (4)));
1854 ")
1855
1856 (define_insn "*pushdi2_prologue_rex64"
1857 [(set (match_operand:DI 0 "push_operand" "=<")
1858 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1859 (clobber (mem:BLK (scratch)))]
1860 "TARGET_64BIT"
1861 "push{q}\t%1"
1862 [(set_attr "type" "push")
1863 (set_attr "mode" "DI")])
1864
1865 (define_insn "*popdi1_epilogue_rex64"
1866 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1867 (mem:DI (reg:DI 7)))
1868 (set (reg:DI 7)
1869 (plus:DI (reg:DI 7) (const_int 8)))
1870 (clobber (mem:BLK (scratch)))]
1871 "TARGET_64BIT"
1872 "pop{q}\t%0"
1873 [(set_attr "type" "pop")
1874 (set_attr "mode" "DI")])
1875
1876 (define_insn "popdi1"
1877 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1878 (mem:DI (reg:DI 7)))
1879 (set (reg:DI 7)
1880 (plus:DI (reg:DI 7) (const_int 8)))]
1881 "TARGET_64BIT"
1882 "pop{q}\t%0"
1883 [(set_attr "type" "pop")
1884 (set_attr "mode" "DI")])
1885
1886 (define_insn "*movdi_xor_rex64"
1887 [(set (match_operand:DI 0 "register_operand" "=r")
1888 (match_operand:DI 1 "const0_operand" "i"))
1889 (clobber (reg:CC 17))]
1890 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1891 && reload_completed"
1892 "xor{l}\t{%k0, %k0|%k0, %k0}"
1893 [(set_attr "type" "alu1")
1894 (set_attr "mode" "SI")
1895 (set_attr "length_immediate" "0")])
1896
1897 (define_insn "*movdi_or_rex64"
1898 [(set (match_operand:DI 0 "register_operand" "=r")
1899 (match_operand:DI 1 "const_int_operand" "i"))
1900 (clobber (reg:CC 17))]
1901 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1902 && reload_completed
1903 && operands[1] == constm1_rtx"
1904 {
1905 operands[1] = constm1_rtx;
1906 return "or{q}\t{%1, %0|%0, %1}";
1907 }
1908 [(set_attr "type" "alu1")
1909 (set_attr "mode" "DI")
1910 (set_attr "length_immediate" "1")])
1911
1912 (define_insn "*movdi_2"
1913 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1914 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1915 "!TARGET_64BIT
1916 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1917 "@
1918 #
1919 #
1920 movq\t{%1, %0|%0, %1}
1921 movq\t{%1, %0|%0, %1}
1922 movq\t{%1, %0|%0, %1}
1923 movdqa\t{%1, %0|%0, %1}
1924 movq\t{%1, %0|%0, %1}"
1925 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1926 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1927
1928 (define_split
1929 [(set (match_operand:DI 0 "push_operand" "")
1930 (match_operand:DI 1 "general_operand" ""))]
1931 "!TARGET_64BIT && reload_completed
1932 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1933 [(const_int 0)]
1934 "ix86_split_long_move (operands); DONE;")
1935
1936 ;; %%% This multiword shite has got to go.
1937 (define_split
1938 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1939 (match_operand:DI 1 "general_operand" ""))]
1940 "!TARGET_64BIT && reload_completed
1941 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1942 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1943 [(const_int 0)]
1944 "ix86_split_long_move (operands); DONE;")
1945
1946 (define_insn "*movdi_1_rex64"
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1948 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1949 "TARGET_64BIT
1950 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1951 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1952 {
1953 switch (get_attr_type (insn))
1954 {
1955 case TYPE_SSEMOV:
1956 if (get_attr_mode (insn) == MODE_TI)
1957 return "movdqa\t{%1, %0|%0, %1}";
1958 /* FALLTHRU */
1959 case TYPE_MMXMOV:
1960 /* Moves from and into integer register is done using movd opcode with
1961 REX prefix. */
1962 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1963 return "movd\t{%1, %0|%0, %1}";
1964 return "movq\t{%1, %0|%0, %1}";
1965 case TYPE_MULTI:
1966 return "#";
1967 case TYPE_LEA:
1968 return "lea{q}\t{%a1, %0|%0, %a1}";
1969 default:
1970 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1971 abort ();
1972 if (get_attr_mode (insn) == MODE_SI)
1973 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1974 else if (which_alternative == 2)
1975 return "movabs{q}\t{%1, %0|%0, %1}";
1976 else
1977 return "mov{q}\t{%1, %0|%0, %1}";
1978 }
1979 }
1980 [(set (attr "type")
1981 (cond [(eq_attr "alternative" "5,6,7")
1982 (const_string "mmxmov")
1983 (eq_attr "alternative" "8,9,10")
1984 (const_string "ssemov")
1985 (eq_attr "alternative" "4")
1986 (const_string "multi")
1987 (and (ne (symbol_ref "flag_pic") (const_int 0))
1988 (match_operand:DI 1 "symbolic_operand" ""))
1989 (const_string "lea")
1990 ]
1991 (const_string "imov")))
1992 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
1993 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
1994 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
1995
1996 (define_insn "*movdi_1_rex64_nointerunit"
1997 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
1998 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
1999 "TARGET_64BIT
2000 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2001 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2002 {
2003 switch (get_attr_type (insn))
2004 {
2005 case TYPE_SSEMOV:
2006 if (get_attr_mode (insn) == MODE_TI)
2007 return "movdqa\t{%1, %0|%0, %1}";
2008 /* FALLTHRU */
2009 case TYPE_MMXMOV:
2010 return "movq\t{%1, %0|%0, %1}";
2011 case TYPE_MULTI:
2012 return "#";
2013 case TYPE_LEA:
2014 return "lea{q}\t{%a1, %0|%0, %a1}";
2015 default:
2016 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2017 abort ();
2018 if (get_attr_mode (insn) == MODE_SI)
2019 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2020 else if (which_alternative == 2)
2021 return "movabs{q}\t{%1, %0|%0, %1}";
2022 else
2023 return "mov{q}\t{%1, %0|%0, %1}";
2024 }
2025 }
2026 [(set (attr "type")
2027 (cond [(eq_attr "alternative" "5,6,7")
2028 (const_string "mmxmov")
2029 (eq_attr "alternative" "8,9,10")
2030 (const_string "ssemov")
2031 (eq_attr "alternative" "4")
2032 (const_string "multi")
2033 (and (ne (symbol_ref "flag_pic") (const_int 0))
2034 (match_operand:DI 1 "symbolic_operand" ""))
2035 (const_string "lea")
2036 ]
2037 (const_string "imov")))
2038 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2039 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2040 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2041
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsdi_1_rex64"
2046 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2048 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049 "@
2050 movabs{q}\t{%1, %P0|%P0, %1}
2051 mov{q}\t{%1, %a0|%a0, %1}"
2052 [(set_attr "type" "imov")
2053 (set_attr "modrm" "0,*")
2054 (set_attr "length_address" "8,0")
2055 (set_attr "length_immediate" "0,*")
2056 (set_attr "memory" "store")
2057 (set_attr "mode" "DI")])
2058
2059 (define_insn "*movabsdi_2_rex64"
2060 [(set (match_operand:DI 0 "register_operand" "=a,r")
2061 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063 "@
2064 movabs{q}\t{%P1, %0|%0, %P1}
2065 mov{q}\t{%a1, %0|%0, %a1}"
2066 [(set_attr "type" "imov")
2067 (set_attr "modrm" "0,*")
2068 (set_attr "length_address" "8,0")
2069 (set_attr "length_immediate" "0")
2070 (set_attr "memory" "load")
2071 (set_attr "mode" "DI")])
2072
2073 ;; Convert impossible stores of immediate to existing instructions.
2074 ;; First try to get scratch register and go through it. In case this
2075 ;; fails, move by 32bit parts.
2076 (define_peephole2
2077 [(match_scratch:DI 2 "r")
2078 (set (match_operand:DI 0 "memory_operand" "")
2079 (match_operand:DI 1 "immediate_operand" ""))]
2080 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2081 && !x86_64_immediate_operand (operands[1], DImode)"
2082 [(set (match_dup 2) (match_dup 1))
2083 (set (match_dup 0) (match_dup 2))]
2084 "")
2085
2086 ;; We need to define this as both peepholer and splitter for case
2087 ;; peephole2 pass is not run.
2088 (define_peephole2
2089 [(set (match_operand:DI 0 "memory_operand" "")
2090 (match_operand:DI 1 "immediate_operand" ""))]
2091 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2092 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2093 [(set (match_dup 2) (match_dup 3))
2094 (set (match_dup 4) (match_dup 5))]
2095 "split_di (operands, 2, operands + 2, operands + 4);")
2096
2097 (define_split
2098 [(set (match_operand:DI 0 "memory_operand" "")
2099 (match_operand:DI 1 "immediate_operand" ""))]
2100 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_di (operands, 2, operands + 2, operands + 4);")
2106
2107 (define_insn "*swapdi_rex64"
2108 [(set (match_operand:DI 0 "register_operand" "+r")
2109 (match_operand:DI 1 "register_operand" "+r"))
2110 (set (match_dup 1)
2111 (match_dup 0))]
2112 "TARGET_64BIT"
2113 "xchg{q}\t%1, %0"
2114 [(set_attr "type" "imov")
2115 (set_attr "pent_pair" "np")
2116 (set_attr "athlon_decode" "vector")
2117 (set_attr "mode" "DI")
2118 (set_attr "modrm" "0")
2119 (set_attr "ppro_uops" "few")])
2120
2121
2122 (define_expand "movsf"
2123 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2124 (match_operand:SF 1 "general_operand" ""))]
2125 ""
2126 "ix86_expand_move (SFmode, operands); DONE;")
2127
2128 (define_insn "*pushsf"
2129 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2130 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2131 "!TARGET_64BIT"
2132 {
2133 switch (which_alternative)
2134 {
2135 case 1:
2136 return "push{l}\t%1";
2137
2138 default:
2139 /* This insn should be already split before reg-stack. */
2140 abort ();
2141 }
2142 }
2143 [(set_attr "type" "multi,push,multi")
2144 (set_attr "mode" "SF,SI,SF")])
2145
2146 (define_insn "*pushsf_rex64"
2147 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2148 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2149 "TARGET_64BIT"
2150 {
2151 switch (which_alternative)
2152 {
2153 case 1:
2154 return "push{q}\t%q1";
2155
2156 default:
2157 /* This insn should be already split before reg-stack. */
2158 abort ();
2159 }
2160 }
2161 [(set_attr "type" "multi,push,multi")
2162 (set_attr "mode" "SF,DI,SF")])
2163
2164 (define_split
2165 [(set (match_operand:SF 0 "push_operand" "")
2166 (match_operand:SF 1 "memory_operand" ""))]
2167 "reload_completed
2168 && GET_CODE (operands[1]) == MEM
2169 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2170 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2171 [(set (match_dup 0)
2172 (match_dup 1))]
2173 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2174
2175
2176 ;; %%% Kill this when call knows how to work this out.
2177 (define_split
2178 [(set (match_operand:SF 0 "push_operand" "")
2179 (match_operand:SF 1 "any_fp_register_operand" ""))]
2180 "!TARGET_64BIT"
2181 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2182 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2183
2184 (define_split
2185 [(set (match_operand:SF 0 "push_operand" "")
2186 (match_operand:SF 1 "any_fp_register_operand" ""))]
2187 "TARGET_64BIT"
2188 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2189 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2190
2191 (define_insn "*movsf_1"
2192 [(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")
2193 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2194 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2195 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2196 && (reload_in_progress || reload_completed
2197 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2198 || GET_CODE (operands[1]) != CONST_DOUBLE
2199 || memory_operand (operands[0], SFmode))"
2200 {
2201 switch (which_alternative)
2202 {
2203 case 0:
2204 if (REG_P (operands[1])
2205 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2206 return "fstp\t%y0";
2207 else if (STACK_TOP_P (operands[0]))
2208 return "fld%z1\t%y1";
2209 else
2210 return "fst\t%y0";
2211
2212 case 1:
2213 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2214 return "fstp%z0\t%y0";
2215 else
2216 return "fst%z0\t%y0";
2217
2218 case 2:
2219 return standard_80387_constant_opcode (operands[1]);
2220
2221 case 3:
2222 case 4:
2223 return "mov{l}\t{%1, %0|%0, %1}";
2224 case 5:
2225 if (get_attr_mode (insn) == MODE_TI)
2226 return "pxor\t%0, %0";
2227 else
2228 return "xorps\t%0, %0";
2229 case 6:
2230 if (get_attr_mode (insn) == MODE_V4SF)
2231 return "movaps\t{%1, %0|%0, %1}";
2232 else
2233 return "movss\t{%1, %0|%0, %1}";
2234 case 7:
2235 case 8:
2236 return "movss\t{%1, %0|%0, %1}";
2237
2238 case 9:
2239 case 10:
2240 return "movd\t{%1, %0|%0, %1}";
2241
2242 case 11:
2243 return "movq\t{%1, %0|%0, %1}";
2244
2245 default:
2246 abort();
2247 }
2248 }
2249 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2250 (set (attr "mode")
2251 (cond [(eq_attr "alternative" "3,4,9,10")
2252 (const_string "SI")
2253 (eq_attr "alternative" "5")
2254 (if_then_else
2255 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2256 (const_int 0))
2257 (ne (symbol_ref "TARGET_SSE2")
2258 (const_int 0)))
2259 (eq (symbol_ref "optimize_size")
2260 (const_int 0)))
2261 (const_string "TI")
2262 (const_string "V4SF"))
2263 /* For architectures resolving dependencies on
2264 whole SSE registers use APS move to break dependency
2265 chains, otherwise use short move to avoid extra work.
2266
2267 Do the same for architectures resolving dependencies on
2268 the parts. While in DF mode it is better to always handle
2269 just register parts, the SF mode is different due to lack
2270 of instructions to load just part of the register. It is
2271 better to maintain the whole registers in single format
2272 to avoid problems on using packed logical operations. */
2273 (eq_attr "alternative" "6")
2274 (if_then_else
2275 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2276 (const_int 0))
2277 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2278 (const_int 0)))
2279 (const_string "V4SF")
2280 (const_string "SF"))
2281 (eq_attr "alternative" "11")
2282 (const_string "DI")]
2283 (const_string "SF")))])
2284
2285 (define_insn "*movsf_1_nointerunit"
2286 [(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")
2287 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2288 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2289 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2290 && (reload_in_progress || reload_completed
2291 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2292 || GET_CODE (operands[1]) != CONST_DOUBLE
2293 || memory_operand (operands[0], SFmode))"
2294 {
2295 switch (which_alternative)
2296 {
2297 case 0:
2298 if (REG_P (operands[1])
2299 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2300 {
2301 if (REGNO (operands[0]) == FIRST_STACK_REG
2302 && TARGET_USE_FFREEP)
2303 return "ffreep\t%y0";
2304 return "fstp\t%y0";
2305 }
2306 else if (STACK_TOP_P (operands[0]))
2307 return "fld%z1\t%y1";
2308 else
2309 return "fst\t%y0";
2310
2311 case 1:
2312 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2313 return "fstp%z0\t%y0";
2314 else
2315 return "fst%z0\t%y0";
2316
2317 case 2:
2318 return standard_80387_constant_opcode (operands[1]);
2319
2320 case 3:
2321 case 4:
2322 return "mov{l}\t{%1, %0|%0, %1}";
2323 case 5:
2324 if (get_attr_mode (insn) == MODE_TI)
2325 return "pxor\t%0, %0";
2326 else
2327 return "xorps\t%0, %0";
2328 case 6:
2329 if (get_attr_mode (insn) == MODE_V4SF)
2330 return "movaps\t{%1, %0|%0, %1}";
2331 else
2332 return "movss\t{%1, %0|%0, %1}";
2333 case 7:
2334 case 8:
2335 return "movss\t{%1, %0|%0, %1}";
2336
2337 case 9:
2338 case 10:
2339 return "movd\t{%1, %0|%0, %1}";
2340
2341 case 11:
2342 return "movq\t{%1, %0|%0, %1}";
2343
2344 default:
2345 abort();
2346 }
2347 }
2348 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2349 (set (attr "mode")
2350 (cond [(eq_attr "alternative" "3,4,9,10")
2351 (const_string "SI")
2352 (eq_attr "alternative" "5")
2353 (if_then_else
2354 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2355 (const_int 0))
2356 (ne (symbol_ref "TARGET_SSE2")
2357 (const_int 0)))
2358 (eq (symbol_ref "optimize_size")
2359 (const_int 0)))
2360 (const_string "TI")
2361 (const_string "V4SF"))
2362 /* For architectures resolving dependencies on
2363 whole SSE registers use APS move to break dependency
2364 chains, otherwise use short move to avoid extra work.
2365
2366 Do the same for architectures resolving dependencies on
2367 the parts. While in DF mode it is better to always handle
2368 just register parts, the SF mode is different due to lack
2369 of instructions to load just part of the register. It is
2370 better to maintain the whole registers in single format
2371 to avoid problems on using packed logical operations. */
2372 (eq_attr "alternative" "6")
2373 (if_then_else
2374 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2375 (const_int 0))
2376 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2377 (const_int 0)))
2378 (const_string "V4SF")
2379 (const_string "SF"))
2380 (eq_attr "alternative" "11")
2381 (const_string "DI")]
2382 (const_string "SF")))])
2383
2384 (define_insn "*swapsf"
2385 [(set (match_operand:SF 0 "register_operand" "+f")
2386 (match_operand:SF 1 "register_operand" "+f"))
2387 (set (match_dup 1)
2388 (match_dup 0))]
2389 "reload_completed || !TARGET_SSE"
2390 {
2391 if (STACK_TOP_P (operands[0]))
2392 return "fxch\t%1";
2393 else
2394 return "fxch\t%0";
2395 }
2396 [(set_attr "type" "fxch")
2397 (set_attr "mode" "SF")])
2398
2399 (define_expand "movdf"
2400 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2401 (match_operand:DF 1 "general_operand" ""))]
2402 ""
2403 "ix86_expand_move (DFmode, operands); DONE;")
2404
2405 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2406 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2407 ;; On the average, pushdf using integers can be still shorter. Allow this
2408 ;; pattern for optimize_size too.
2409
2410 (define_insn "*pushdf_nointeger"
2411 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2412 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2413 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2414 {
2415 /* This insn should be already split before reg-stack. */
2416 abort ();
2417 }
2418 [(set_attr "type" "multi")
2419 (set_attr "mode" "DF,SI,SI,DF")])
2420
2421 (define_insn "*pushdf_integer"
2422 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2423 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2424 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2425 {
2426 /* This insn should be already split before reg-stack. */
2427 abort ();
2428 }
2429 [(set_attr "type" "multi")
2430 (set_attr "mode" "DF,SI,DF")])
2431
2432 ;; %%% Kill this when call knows how to work this out.
2433 (define_split
2434 [(set (match_operand:DF 0 "push_operand" "")
2435 (match_operand:DF 1 "any_fp_register_operand" ""))]
2436 "!TARGET_64BIT && reload_completed"
2437 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2438 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2439 "")
2440
2441 (define_split
2442 [(set (match_operand:DF 0 "push_operand" "")
2443 (match_operand:DF 1 "any_fp_register_operand" ""))]
2444 "TARGET_64BIT && reload_completed"
2445 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2446 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2447 "")
2448
2449 (define_split
2450 [(set (match_operand:DF 0 "push_operand" "")
2451 (match_operand:DF 1 "general_operand" ""))]
2452 "reload_completed"
2453 [(const_int 0)]
2454 "ix86_split_long_move (operands); DONE;")
2455
2456 ;; Moving is usually shorter when only FP registers are used. This separate
2457 ;; movdf pattern avoids the use of integer registers for FP operations
2458 ;; when optimizing for size.
2459
2460 (define_insn "*movdf_nointeger"
2461 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2462 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2463 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2464 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2465 && (reload_in_progress || reload_completed
2466 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2467 || GET_CODE (operands[1]) != CONST_DOUBLE
2468 || memory_operand (operands[0], DFmode))"
2469 {
2470 switch (which_alternative)
2471 {
2472 case 0:
2473 if (REG_P (operands[1])
2474 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2475 {
2476 if (REGNO (operands[0]) == FIRST_STACK_REG
2477 && TARGET_USE_FFREEP)
2478 return "ffreep\t%y0";
2479 return "fstp\t%y0";
2480 }
2481 else if (STACK_TOP_P (operands[0]))
2482 return "fld%z1\t%y1";
2483 else
2484 return "fst\t%y0";
2485
2486 case 1:
2487 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488 return "fstp%z0\t%y0";
2489 else
2490 return "fst%z0\t%y0";
2491
2492 case 2:
2493 return standard_80387_constant_opcode (operands[1]);
2494
2495 case 3:
2496 case 4:
2497 return "#";
2498 case 5:
2499 switch (get_attr_mode (insn))
2500 {
2501 case MODE_V4SF:
2502 return "xorps\t%0, %0";
2503 case MODE_V2DF:
2504 return "xorpd\t%0, %0";
2505 case MODE_TI:
2506 return "pxor\t%0, %0";
2507 default:
2508 abort ();
2509 }
2510 case 6:
2511 switch (get_attr_mode (insn))
2512 {
2513 case MODE_V4SF:
2514 return "movaps\t{%1, %0|%0, %1}";
2515 case MODE_V2DF:
2516 return "movapd\t{%1, %0|%0, %1}";
2517 case MODE_DF:
2518 return "movsd\t{%1, %0|%0, %1}";
2519 default:
2520 abort ();
2521 }
2522 case 7:
2523 if (get_attr_mode (insn) == MODE_V2DF)
2524 return "movlpd\t{%1, %0|%0, %1}";
2525 else
2526 return "movsd\t{%1, %0|%0, %1}";
2527 case 8:
2528 return "movsd\t{%1, %0|%0, %1}";
2529
2530 default:
2531 abort();
2532 }
2533 }
2534 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2535 (set (attr "mode")
2536 (cond [(eq_attr "alternative" "3,4")
2537 (const_string "SI")
2538 /* xorps is one byte shorter. */
2539 (eq_attr "alternative" "5")
2540 (cond [(ne (symbol_ref "optimize_size")
2541 (const_int 0))
2542 (const_string "V4SF")
2543 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2544 (const_int 0))
2545 (const_string "TI")]
2546 (const_string "V2DF"))
2547 /* For architectures resolving dependencies on
2548 whole SSE registers use APD move to break dependency
2549 chains, otherwise use short move to avoid extra work.
2550
2551 movaps encodes one byte shorter. */
2552 (eq_attr "alternative" "6")
2553 (cond
2554 [(ne (symbol_ref "optimize_size")
2555 (const_int 0))
2556 (const_string "V4SF")
2557 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2558 (const_int 0))
2559 (const_string "V2DF")]
2560 (const_string "DF"))
2561 /* For architectures resolving dependencies on register
2562 parts we may avoid extra work to zero out upper part
2563 of register. */
2564 (eq_attr "alternative" "7")
2565 (if_then_else
2566 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2567 (const_int 0))
2568 (const_string "V2DF")
2569 (const_string "DF"))]
2570 (const_string "DF")))])
2571
2572 (define_insn "*movdf_integer"
2573 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2574 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2575 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577 && (reload_in_progress || reload_completed
2578 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579 || GET_CODE (operands[1]) != CONST_DOUBLE
2580 || memory_operand (operands[0], DFmode))"
2581 {
2582 switch (which_alternative)
2583 {
2584 case 0:
2585 if (REG_P (operands[1])
2586 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2587 {
2588 if (REGNO (operands[0]) == FIRST_STACK_REG
2589 && TARGET_USE_FFREEP)
2590 return "ffreep\t%y0";
2591 return "fstp\t%y0";
2592 }
2593 else if (STACK_TOP_P (operands[0]))
2594 return "fld%z1\t%y1";
2595 else
2596 return "fst\t%y0";
2597
2598 case 1:
2599 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2600 return "fstp%z0\t%y0";
2601 else
2602 return "fst%z0\t%y0";
2603
2604 case 2:
2605 return standard_80387_constant_opcode (operands[1]);
2606
2607 case 3:
2608 case 4:
2609 return "#";
2610
2611 case 5:
2612 switch (get_attr_mode (insn))
2613 {
2614 case MODE_V4SF:
2615 return "xorps\t%0, %0";
2616 case MODE_V2DF:
2617 return "xorpd\t%0, %0";
2618 case MODE_TI:
2619 return "pxor\t%0, %0";
2620 default:
2621 abort ();
2622 }
2623 case 6:
2624 switch (get_attr_mode (insn))
2625 {
2626 case MODE_V4SF:
2627 return "movaps\t{%1, %0|%0, %1}";
2628 case MODE_V2DF:
2629 return "movapd\t{%1, %0|%0, %1}";
2630 case MODE_DF:
2631 return "movsd\t{%1, %0|%0, %1}";
2632 default:
2633 abort ();
2634 }
2635 case 7:
2636 if (get_attr_mode (insn) == MODE_V2DF)
2637 return "movlpd\t{%1, %0|%0, %1}";
2638 else
2639 return "movsd\t{%1, %0|%0, %1}";
2640 case 8:
2641 return "movsd\t{%1, %0|%0, %1}";
2642
2643 default:
2644 abort();
2645 }
2646 }
2647 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2648 (set (attr "mode")
2649 (cond [(eq_attr "alternative" "3,4")
2650 (const_string "SI")
2651 /* xorps is one byte shorter. */
2652 (eq_attr "alternative" "5")
2653 (cond [(ne (symbol_ref "optimize_size")
2654 (const_int 0))
2655 (const_string "V4SF")
2656 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2657 (const_int 0))
2658 (const_string "TI")]
2659 (const_string "V2DF"))
2660 /* For architectures resolving dependencies on
2661 whole SSE registers use APD move to break dependency
2662 chains, otherwise use short move to avoid extra work.
2663
2664 movaps encodes one byte shorter. */
2665 (eq_attr "alternative" "6")
2666 (cond
2667 [(ne (symbol_ref "optimize_size")
2668 (const_int 0))
2669 (const_string "V4SF")
2670 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2671 (const_int 0))
2672 (const_string "V2DF")]
2673 (const_string "DF"))
2674 /* For architectures resolving dependencies on register
2675 parts we may avoid extra work to zero out upper part
2676 of register. */
2677 (eq_attr "alternative" "7")
2678 (if_then_else
2679 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2680 (const_int 0))
2681 (const_string "V2DF")
2682 (const_string "DF"))]
2683 (const_string "DF")))])
2684
2685 (define_split
2686 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2687 (match_operand:DF 1 "general_operand" ""))]
2688 "reload_completed
2689 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2690 && ! (ANY_FP_REG_P (operands[0]) ||
2691 (GET_CODE (operands[0]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2693 && ! (ANY_FP_REG_P (operands[1]) ||
2694 (GET_CODE (operands[1]) == SUBREG
2695 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2696 [(const_int 0)]
2697 "ix86_split_long_move (operands); DONE;")
2698
2699 (define_insn "*swapdf"
2700 [(set (match_operand:DF 0 "register_operand" "+f")
2701 (match_operand:DF 1 "register_operand" "+f"))
2702 (set (match_dup 1)
2703 (match_dup 0))]
2704 "reload_completed || !TARGET_SSE2"
2705 {
2706 if (STACK_TOP_P (operands[0]))
2707 return "fxch\t%1";
2708 else
2709 return "fxch\t%0";
2710 }
2711 [(set_attr "type" "fxch")
2712 (set_attr "mode" "DF")])
2713
2714 (define_expand "movxf"
2715 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2716 (match_operand:XF 1 "general_operand" ""))]
2717 ""
2718 "ix86_expand_move (XFmode, operands); DONE;")
2719
2720 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2721 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2722 ;; Pushing using integer instructions is longer except for constants
2723 ;; and direct memory references.
2724 ;; (assuming that any given constant is pushed only once, but this ought to be
2725 ;; handled elsewhere).
2726
2727 (define_insn "*pushxf_nointeger"
2728 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2729 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2730 "optimize_size"
2731 {
2732 /* This insn should be already split before reg-stack. */
2733 abort ();
2734 }
2735 [(set_attr "type" "multi")
2736 (set_attr "mode" "XF,SI,SI")])
2737
2738 (define_insn "*pushxf_integer"
2739 [(set (match_operand:XF 0 "push_operand" "=<,<")
2740 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2741 "!optimize_size"
2742 {
2743 /* This insn should be already split before reg-stack. */
2744 abort ();
2745 }
2746 [(set_attr "type" "multi")
2747 (set_attr "mode" "XF,SI")])
2748
2749 (define_split
2750 [(set (match_operand 0 "push_operand" "")
2751 (match_operand 1 "general_operand" ""))]
2752 "reload_completed
2753 && (GET_MODE (operands[0]) == XFmode
2754 || GET_MODE (operands[0]) == DFmode)
2755 && !ANY_FP_REG_P (operands[1])"
2756 [(const_int 0)]
2757 "ix86_split_long_move (operands); DONE;")
2758
2759 (define_split
2760 [(set (match_operand:XF 0 "push_operand" "")
2761 (match_operand:XF 1 "any_fp_register_operand" ""))]
2762 "!TARGET_64BIT"
2763 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
2764 (set (mem:XF (reg:SI 7)) (match_dup 1))]
2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2766
2767 (define_split
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2770 "TARGET_64BIT"
2771 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
2772 (set (mem:XF (reg:DI 7)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779 "optimize_size
2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781 && (reload_in_progress || reload_completed
2782 || GET_CODE (operands[1]) != CONST_DOUBLE
2783 || memory_operand (operands[0], XFmode))"
2784 {
2785 switch (which_alternative)
2786 {
2787 case 0:
2788 if (REG_P (operands[1])
2789 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2790 {
2791 if (REGNO (operands[0]) == FIRST_STACK_REG
2792 && TARGET_USE_FFREEP)
2793 return "ffreep\t%y0";
2794 return "fstp\t%y0";
2795 }
2796 else if (STACK_TOP_P (operands[0]))
2797 return "fld%z1\t%y1";
2798 else
2799 return "fst\t%y0";
2800
2801 case 1:
2802 /* There is no non-popping store to memory for XFmode. So if
2803 we need one, follow the store with a load. */
2804 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2805 return "fstp%z0\t%y0\;fld%z0\t%y0";
2806 else
2807 return "fstp%z0\t%y0";
2808
2809 case 2:
2810 return standard_80387_constant_opcode (operands[1]);
2811
2812 case 3: case 4:
2813 return "#";
2814 }
2815 abort();
2816 }
2817 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2818 (set_attr "mode" "XF,XF,XF,SI,SI")])
2819
2820 (define_insn "*movxf_integer"
2821 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2822 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2823 "!optimize_size
2824 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2825 && (reload_in_progress || reload_completed
2826 || GET_CODE (operands[1]) != CONST_DOUBLE
2827 || memory_operand (operands[0], XFmode))"
2828 {
2829 switch (which_alternative)
2830 {
2831 case 0:
2832 if (REG_P (operands[1])
2833 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834 {
2835 if (REGNO (operands[0]) == FIRST_STACK_REG
2836 && TARGET_USE_FFREEP)
2837 return "ffreep\t%y0";
2838 return "fstp\t%y0";
2839 }
2840 else if (STACK_TOP_P (operands[0]))
2841 return "fld%z1\t%y1";
2842 else
2843 return "fst\t%y0";
2844
2845 case 1:
2846 /* There is no non-popping store to memory for XFmode. So if
2847 we need one, follow the store with a load. */
2848 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2849 return "fstp%z0\t%y0\;fld%z0\t%y0";
2850 else
2851 return "fstp%z0\t%y0";
2852
2853 case 2:
2854 return standard_80387_constant_opcode (operands[1]);
2855
2856 case 3: case 4:
2857 return "#";
2858 }
2859 abort();
2860 }
2861 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2862 (set_attr "mode" "XF,XF,XF,SI,SI")])
2863
2864 (define_split
2865 [(set (match_operand 0 "nonimmediate_operand" "")
2866 (match_operand 1 "general_operand" ""))]
2867 "reload_completed
2868 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2869 && GET_MODE (operands[0]) == XFmode
2870 && ! (ANY_FP_REG_P (operands[0]) ||
2871 (GET_CODE (operands[0]) == SUBREG
2872 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2873 && ! (ANY_FP_REG_P (operands[1]) ||
2874 (GET_CODE (operands[1]) == SUBREG
2875 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2876 [(const_int 0)]
2877 "ix86_split_long_move (operands); DONE;")
2878
2879 (define_split
2880 [(set (match_operand 0 "register_operand" "")
2881 (match_operand 1 "memory_operand" ""))]
2882 "reload_completed
2883 && GET_CODE (operands[1]) == MEM
2884 && (GET_MODE (operands[0]) == XFmode
2885 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2886 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2887 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2888 [(set (match_dup 0) (match_dup 1))]
2889 {
2890 rtx c = get_pool_constant (XEXP (operands[1], 0));
2891 rtx r = operands[0];
2892
2893 if (GET_CODE (r) == SUBREG)
2894 r = SUBREG_REG (r);
2895
2896 if (SSE_REG_P (r))
2897 {
2898 if (!standard_sse_constant_p (c))
2899 FAIL;
2900 }
2901 else if (FP_REG_P (r))
2902 {
2903 if (!standard_80387_constant_p (c))
2904 FAIL;
2905 }
2906 else if (MMX_REG_P (r))
2907 FAIL;
2908
2909 operands[1] = c;
2910 })
2911
2912 (define_insn "swapxf"
2913 [(set (match_operand:XF 0 "register_operand" "+f")
2914 (match_operand:XF 1 "register_operand" "+f"))
2915 (set (match_dup 1)
2916 (match_dup 0))]
2917 ""
2918 {
2919 if (STACK_TOP_P (operands[0]))
2920 return "fxch\t%1";
2921 else
2922 return "fxch\t%0";
2923 }
2924 [(set_attr "type" "fxch")
2925 (set_attr "mode" "XF")])
2926 \f
2927 ;; Zero extension instructions
2928
2929 (define_expand "zero_extendhisi2"
2930 [(set (match_operand:SI 0 "register_operand" "")
2931 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2932 ""
2933 {
2934 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2935 {
2936 operands[1] = force_reg (HImode, operands[1]);
2937 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2938 DONE;
2939 }
2940 })
2941
2942 (define_insn "zero_extendhisi2_and"
2943 [(set (match_operand:SI 0 "register_operand" "=r")
2944 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2945 (clobber (reg:CC 17))]
2946 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2947 "#"
2948 [(set_attr "type" "alu1")
2949 (set_attr "mode" "SI")])
2950
2951 (define_split
2952 [(set (match_operand:SI 0 "register_operand" "")
2953 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2954 (clobber (reg:CC 17))]
2955 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2956 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2957 (clobber (reg:CC 17))])]
2958 "")
2959
2960 (define_insn "*zero_extendhisi2_movzwl"
2961 [(set (match_operand:SI 0 "register_operand" "=r")
2962 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2963 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2964 "movz{wl|x}\t{%1, %0|%0, %1}"
2965 [(set_attr "type" "imovx")
2966 (set_attr "mode" "SI")])
2967
2968 (define_expand "zero_extendqihi2"
2969 [(parallel
2970 [(set (match_operand:HI 0 "register_operand" "")
2971 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2972 (clobber (reg:CC 17))])]
2973 ""
2974 "")
2975
2976 (define_insn "*zero_extendqihi2_and"
2977 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2978 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2979 (clobber (reg:CC 17))]
2980 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2981 "#"
2982 [(set_attr "type" "alu1")
2983 (set_attr "mode" "HI")])
2984
2985 (define_insn "*zero_extendqihi2_movzbw_and"
2986 [(set (match_operand:HI 0 "register_operand" "=r,r")
2987 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2988 (clobber (reg:CC 17))]
2989 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2990 "#"
2991 [(set_attr "type" "imovx,alu1")
2992 (set_attr "mode" "HI")])
2993
2994 (define_insn "*zero_extendqihi2_movzbw"
2995 [(set (match_operand:HI 0 "register_operand" "=r")
2996 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
2997 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
2998 "movz{bw|x}\t{%1, %0|%0, %1}"
2999 [(set_attr "type" "imovx")
3000 (set_attr "mode" "HI")])
3001
3002 ;; For the movzbw case strip only the clobber
3003 (define_split
3004 [(set (match_operand:HI 0 "register_operand" "")
3005 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3006 (clobber (reg:CC 17))]
3007 "reload_completed
3008 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3009 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3010 [(set (match_operand:HI 0 "register_operand" "")
3011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3012
3013 ;; When source and destination does not overlap, clear destination
3014 ;; first and then do the movb
3015 (define_split
3016 [(set (match_operand:HI 0 "register_operand" "")
3017 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3018 (clobber (reg:CC 17))]
3019 "reload_completed
3020 && ANY_QI_REG_P (operands[0])
3021 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3022 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3023 [(set (match_dup 0) (const_int 0))
3024 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3025 "operands[2] = gen_lowpart (QImode, operands[0]);")
3026
3027 ;; Rest is handled by single and.
3028 (define_split
3029 [(set (match_operand:HI 0 "register_operand" "")
3030 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3031 (clobber (reg:CC 17))]
3032 "reload_completed
3033 && true_regnum (operands[0]) == true_regnum (operands[1])"
3034 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3035 (clobber (reg:CC 17))])]
3036 "")
3037
3038 (define_expand "zero_extendqisi2"
3039 [(parallel
3040 [(set (match_operand:SI 0 "register_operand" "")
3041 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3042 (clobber (reg:CC 17))])]
3043 ""
3044 "")
3045
3046 (define_insn "*zero_extendqisi2_and"
3047 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3048 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3049 (clobber (reg:CC 17))]
3050 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3051 "#"
3052 [(set_attr "type" "alu1")
3053 (set_attr "mode" "SI")])
3054
3055 (define_insn "*zero_extendqisi2_movzbw_and"
3056 [(set (match_operand:SI 0 "register_operand" "=r,r")
3057 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3058 (clobber (reg:CC 17))]
3059 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3060 "#"
3061 [(set_attr "type" "imovx,alu1")
3062 (set_attr "mode" "SI")])
3063
3064 (define_insn "*zero_extendqisi2_movzbw"
3065 [(set (match_operand:SI 0 "register_operand" "=r")
3066 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3067 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3068 "movz{bl|x}\t{%1, %0|%0, %1}"
3069 [(set_attr "type" "imovx")
3070 (set_attr "mode" "SI")])
3071
3072 ;; For the movzbl case strip only the clobber
3073 (define_split
3074 [(set (match_operand:SI 0 "register_operand" "")
3075 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3076 (clobber (reg:CC 17))]
3077 "reload_completed
3078 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3079 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3080 [(set (match_dup 0)
3081 (zero_extend:SI (match_dup 1)))])
3082
3083 ;; When source and destination does not overlap, clear destination
3084 ;; first and then do the movb
3085 (define_split
3086 [(set (match_operand:SI 0 "register_operand" "")
3087 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3088 (clobber (reg:CC 17))]
3089 "reload_completed
3090 && ANY_QI_REG_P (operands[0])
3091 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3092 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3093 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3094 [(set (match_dup 0) (const_int 0))
3095 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3096 "operands[2] = gen_lowpart (QImode, operands[0]);")
3097
3098 ;; Rest is handled by single and.
3099 (define_split
3100 [(set (match_operand:SI 0 "register_operand" "")
3101 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3102 (clobber (reg:CC 17))]
3103 "reload_completed
3104 && true_regnum (operands[0]) == true_regnum (operands[1])"
3105 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3106 (clobber (reg:CC 17))])]
3107 "")
3108
3109 ;; %%% Kill me once multi-word ops are sane.
3110 (define_expand "zero_extendsidi2"
3111 [(set (match_operand:DI 0 "register_operand" "=r")
3112 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3113 ""
3114 "if (!TARGET_64BIT)
3115 {
3116 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3117 DONE;
3118 }
3119 ")
3120
3121 (define_insn "zero_extendsidi2_32"
3122 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3123 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3124 (clobber (reg:CC 17))]
3125 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3126 "@
3127 #
3128 #
3129 #
3130 movd\t{%1, %0|%0, %1}
3131 movd\t{%1, %0|%0, %1}"
3132 [(set_attr "mode" "SI,SI,SI,DI,TI")
3133 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3134
3135 (define_insn "*zero_extendsidi2_32_1"
3136 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3137 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3138 (clobber (reg:CC 17))]
3139 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3140 "@
3141 #
3142 #
3143 #
3144 movd\t{%1, %0|%0, %1}
3145 movd\t{%1, %0|%0, %1}"
3146 [(set_attr "mode" "SI,SI,SI,DI,TI")
3147 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3148
3149 (define_insn "zero_extendsidi2_rex64"
3150 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3151 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3152 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3153 "@
3154 mov\t{%k1, %k0|%k0, %k1}
3155 #
3156 movd\t{%1, %0|%0, %1}
3157 movd\t{%1, %0|%0, %1}"
3158 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3159 (set_attr "mode" "SI,DI,DI,TI")])
3160
3161 (define_insn "*zero_extendsidi2_rex64_1"
3162 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3163 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3164 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3165 "@
3166 mov\t{%k1, %k0|%k0, %k1}
3167 #
3168 movd\t{%1, %0|%0, %1}
3169 movd\t{%1, %0|%0, %1}"
3170 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3171 (set_attr "mode" "SI,DI,SI,SI")])
3172
3173 (define_split
3174 [(set (match_operand:DI 0 "memory_operand" "")
3175 (zero_extend:DI (match_dup 0)))]
3176 "TARGET_64BIT"
3177 [(set (match_dup 4) (const_int 0))]
3178 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3179
3180 (define_split
3181 [(set (match_operand:DI 0 "register_operand" "")
3182 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3183 (clobber (reg:CC 17))]
3184 "!TARGET_64BIT && reload_completed
3185 && true_regnum (operands[0]) == true_regnum (operands[1])"
3186 [(set (match_dup 4) (const_int 0))]
3187 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3188
3189 (define_split
3190 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3191 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3192 (clobber (reg:CC 17))]
3193 "!TARGET_64BIT && reload_completed
3194 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3195 [(set (match_dup 3) (match_dup 1))
3196 (set (match_dup 4) (const_int 0))]
3197 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3198
3199 (define_insn "zero_extendhidi2"
3200 [(set (match_operand:DI 0 "register_operand" "=r,r")
3201 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3202 "TARGET_64BIT"
3203 "@
3204 movz{wl|x}\t{%1, %k0|%k0, %1}
3205 movz{wq|x}\t{%1, %0|%0, %1}"
3206 [(set_attr "type" "imovx")
3207 (set_attr "mode" "SI,DI")])
3208
3209 (define_insn "zero_extendqidi2"
3210 [(set (match_operand:DI 0 "register_operand" "=r,r")
3211 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3212 "TARGET_64BIT"
3213 "@
3214 movz{bl|x}\t{%1, %k0|%k0, %1}
3215 movz{bq|x}\t{%1, %0|%0, %1}"
3216 [(set_attr "type" "imovx")
3217 (set_attr "mode" "SI,DI")])
3218 \f
3219 ;; Sign extension instructions
3220
3221 (define_expand "extendsidi2"
3222 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3223 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3224 (clobber (reg:CC 17))
3225 (clobber (match_scratch:SI 2 ""))])]
3226 ""
3227 {
3228 if (TARGET_64BIT)
3229 {
3230 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3231 DONE;
3232 }
3233 })
3234
3235 (define_insn "*extendsidi2_1"
3236 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3237 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3238 (clobber (reg:CC 17))
3239 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3240 "!TARGET_64BIT"
3241 "#")
3242
3243 (define_insn "extendsidi2_rex64"
3244 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3245 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3246 "TARGET_64BIT"
3247 "@
3248 {cltq|cdqe}
3249 movs{lq|x}\t{%1,%0|%0, %1}"
3250 [(set_attr "type" "imovx")
3251 (set_attr "mode" "DI")
3252 (set_attr "prefix_0f" "0")
3253 (set_attr "modrm" "0,1")])
3254
3255 (define_insn "extendhidi2"
3256 [(set (match_operand:DI 0 "register_operand" "=r")
3257 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3258 "TARGET_64BIT"
3259 "movs{wq|x}\t{%1,%0|%0, %1}"
3260 [(set_attr "type" "imovx")
3261 (set_attr "mode" "DI")])
3262
3263 (define_insn "extendqidi2"
3264 [(set (match_operand:DI 0 "register_operand" "=r")
3265 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3266 "TARGET_64BIT"
3267 "movs{bq|x}\t{%1,%0|%0, %1}"
3268 [(set_attr "type" "imovx")
3269 (set_attr "mode" "DI")])
3270
3271 ;; Extend to memory case when source register does 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 && dead_or_set_p (insn, operands[1])
3279 && !reg_mentioned_p (operands[1], operands[0]))"
3280 [(set (match_dup 3) (match_dup 1))
3281 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3282 (clobber (reg:CC 17))])
3283 (set (match_dup 4) (match_dup 1))]
3284 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3285
3286 ;; Extend to memory case when source register does not die.
3287 (define_split
3288 [(set (match_operand:DI 0 "memory_operand" "")
3289 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3290 (clobber (reg:CC 17))
3291 (clobber (match_operand:SI 2 "register_operand" ""))]
3292 "reload_completed"
3293 [(const_int 0)]
3294 {
3295 split_di (&operands[0], 1, &operands[3], &operands[4]);
3296
3297 emit_move_insn (operands[3], operands[1]);
3298
3299 /* Generate a cltd if possible and doing so it profitable. */
3300 if (true_regnum (operands[1]) == 0
3301 && true_regnum (operands[2]) == 1
3302 && (optimize_size || TARGET_USE_CLTD))
3303 {
3304 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3305 }
3306 else
3307 {
3308 emit_move_insn (operands[2], operands[1]);
3309 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3310 }
3311 emit_move_insn (operands[4], operands[2]);
3312 DONE;
3313 })
3314
3315 ;; Extend to register case. Optimize case where source and destination
3316 ;; registers match and cases where we can use cltd.
3317 (define_split
3318 [(set (match_operand:DI 0 "register_operand" "")
3319 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3320 (clobber (reg:CC 17))
3321 (clobber (match_scratch:SI 2 ""))]
3322 "reload_completed"
3323 [(const_int 0)]
3324 {
3325 split_di (&operands[0], 1, &operands[3], &operands[4]);
3326
3327 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3328 emit_move_insn (operands[3], operands[1]);
3329
3330 /* Generate a cltd if possible and doing so it profitable. */
3331 if (true_regnum (operands[3]) == 0
3332 && (optimize_size || TARGET_USE_CLTD))
3333 {
3334 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3335 DONE;
3336 }
3337
3338 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3339 emit_move_insn (operands[4], operands[1]);
3340
3341 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3342 DONE;
3343 })
3344
3345 (define_insn "extendhisi2"
3346 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3347 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3348 ""
3349 {
3350 switch (get_attr_prefix_0f (insn))
3351 {
3352 case 0:
3353 return "{cwtl|cwde}";
3354 default:
3355 return "movs{wl|x}\t{%1,%0|%0, %1}";
3356 }
3357 }
3358 [(set_attr "type" "imovx")
3359 (set_attr "mode" "SI")
3360 (set (attr "prefix_0f")
3361 ;; movsx is short decodable while cwtl is vector decoded.
3362 (if_then_else (and (eq_attr "cpu" "!k6")
3363 (eq_attr "alternative" "0"))
3364 (const_string "0")
3365 (const_string "1")))
3366 (set (attr "modrm")
3367 (if_then_else (eq_attr "prefix_0f" "0")
3368 (const_string "0")
3369 (const_string "1")))])
3370
3371 (define_insn "*extendhisi2_zext"
3372 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3373 (zero_extend:DI
3374 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3375 "TARGET_64BIT"
3376 {
3377 switch (get_attr_prefix_0f (insn))
3378 {
3379 case 0:
3380 return "{cwtl|cwde}";
3381 default:
3382 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3383 }
3384 }
3385 [(set_attr "type" "imovx")
3386 (set_attr "mode" "SI")
3387 (set (attr "prefix_0f")
3388 ;; movsx is short decodable while cwtl is vector decoded.
3389 (if_then_else (and (eq_attr "cpu" "!k6")
3390 (eq_attr "alternative" "0"))
3391 (const_string "0")
3392 (const_string "1")))
3393 (set (attr "modrm")
3394 (if_then_else (eq_attr "prefix_0f" "0")
3395 (const_string "0")
3396 (const_string "1")))])
3397
3398 (define_insn "extendqihi2"
3399 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3400 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3401 ""
3402 {
3403 switch (get_attr_prefix_0f (insn))
3404 {
3405 case 0:
3406 return "{cbtw|cbw}";
3407 default:
3408 return "movs{bw|x}\t{%1,%0|%0, %1}";
3409 }
3410 }
3411 [(set_attr "type" "imovx")
3412 (set_attr "mode" "HI")
3413 (set (attr "prefix_0f")
3414 ;; movsx is short decodable while cwtl is vector decoded.
3415 (if_then_else (and (eq_attr "cpu" "!k6")
3416 (eq_attr "alternative" "0"))
3417 (const_string "0")
3418 (const_string "1")))
3419 (set (attr "modrm")
3420 (if_then_else (eq_attr "prefix_0f" "0")
3421 (const_string "0")
3422 (const_string "1")))])
3423
3424 (define_insn "extendqisi2"
3425 [(set (match_operand:SI 0 "register_operand" "=r")
3426 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3427 ""
3428 "movs{bl|x}\t{%1,%0|%0, %1}"
3429 [(set_attr "type" "imovx")
3430 (set_attr "mode" "SI")])
3431
3432 (define_insn "*extendqisi2_zext"
3433 [(set (match_operand:DI 0 "register_operand" "=r")
3434 (zero_extend:DI
3435 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3436 "TARGET_64BIT"
3437 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3438 [(set_attr "type" "imovx")
3439 (set_attr "mode" "SI")])
3440 \f
3441 ;; Conversions between float and double.
3442
3443 ;; These are all no-ops in the model used for the 80387. So just
3444 ;; emit moves.
3445
3446 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3447 (define_insn "*dummy_extendsfdf2"
3448 [(set (match_operand:DF 0 "push_operand" "=<")
3449 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3450 "0"
3451 "#")
3452
3453 (define_split
3454 [(set (match_operand:DF 0 "push_operand" "")
3455 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3456 "!TARGET_64BIT"
3457 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3458 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3459
3460 (define_split
3461 [(set (match_operand:DF 0 "push_operand" "")
3462 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3463 "TARGET_64BIT"
3464 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3465 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3466
3467 (define_insn "*dummy_extendsfxf2"
3468 [(set (match_operand:XF 0 "push_operand" "=<")
3469 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3470 "0"
3471 "#")
3472
3473 (define_split
3474 [(set (match_operand:XF 0 "push_operand" "")
3475 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3476 ""
3477 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3478 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3479 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3480
3481 (define_split
3482 [(set (match_operand:XF 0 "push_operand" "")
3483 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3484 "TARGET_64BIT"
3485 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3486 (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3487 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3488
3489 (define_split
3490 [(set (match_operand:XF 0 "push_operand" "")
3491 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3492 ""
3493 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
3494 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
3495 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3496
3497 (define_split
3498 [(set (match_operand:XF 0 "push_operand" "")
3499 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3500 "TARGET_64BIT"
3501 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
3502 (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
3503 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3504
3505 (define_expand "extendsfdf2"
3506 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3507 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3508 "TARGET_80387 || TARGET_SSE2"
3509 {
3510 /* ??? Needed for compress_float_constant since all fp constants
3511 are LEGITIMATE_CONSTANT_P. */
3512 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3513 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3514 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3515 operands[1] = force_reg (SFmode, operands[1]);
3516 })
3517
3518 (define_insn "*extendsfdf2_1"
3519 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3520 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3521 "(TARGET_80387 || TARGET_SSE2)
3522 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3523 {
3524 switch (which_alternative)
3525 {
3526 case 0:
3527 if (REG_P (operands[1])
3528 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3529 return "fstp\t%y0";
3530 else if (STACK_TOP_P (operands[0]))
3531 return "fld%z1\t%y1";
3532 else
3533 return "fst\t%y0";
3534
3535 case 1:
3536 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3537 return "fstp%z0\t%y0";
3538
3539 else
3540 return "fst%z0\t%y0";
3541 case 2:
3542 return "cvtss2sd\t{%1, %0|%0, %1}";
3543
3544 default:
3545 abort ();
3546 }
3547 }
3548 [(set_attr "type" "fmov,fmov,ssecvt")
3549 (set_attr "mode" "SF,XF,DF")])
3550
3551 (define_insn "*extendsfdf2_1_sse_only"
3552 [(set (match_operand:DF 0 "register_operand" "=Y")
3553 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3554 "!TARGET_80387 && TARGET_SSE2
3555 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3556 "cvtss2sd\t{%1, %0|%0, %1}"
3557 [(set_attr "type" "ssecvt")
3558 (set_attr "mode" "DF")])
3559
3560 (define_expand "extendsfxf2"
3561 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3562 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3563 "TARGET_80387"
3564 {
3565 /* ??? Needed for compress_float_constant since all fp constants
3566 are LEGITIMATE_CONSTANT_P. */
3567 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3568 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3569 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3570 operands[1] = force_reg (SFmode, operands[1]);
3571 })
3572
3573 (define_insn "*extendsfxf2_1"
3574 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3575 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3576 "TARGET_80387
3577 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3578 {
3579 switch (which_alternative)
3580 {
3581 case 0:
3582 if (REG_P (operands[1])
3583 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3584 return "fstp\t%y0";
3585 else if (STACK_TOP_P (operands[0]))
3586 return "fld%z1\t%y1";
3587 else
3588 return "fst\t%y0";
3589
3590 case 1:
3591 /* There is no non-popping store to memory for XFmode. So if
3592 we need one, follow the store with a load. */
3593 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3594 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3595 else
3596 return "fstp%z0\t%y0";
3597
3598 default:
3599 abort ();
3600 }
3601 }
3602 [(set_attr "type" "fmov")
3603 (set_attr "mode" "SF,XF")])
3604
3605 (define_expand "extenddfxf2"
3606 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3607 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3608 "TARGET_80387"
3609 {
3610 /* ??? Needed for compress_float_constant since all fp constants
3611 are LEGITIMATE_CONSTANT_P. */
3612 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3613 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3614 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3615 operands[1] = force_reg (DFmode, operands[1]);
3616 })
3617
3618 (define_insn "*extenddfxf2_1"
3619 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3620 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3621 "TARGET_80387
3622 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3623 {
3624 switch (which_alternative)
3625 {
3626 case 0:
3627 if (REG_P (operands[1])
3628 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3629 return "fstp\t%y0";
3630 else if (STACK_TOP_P (operands[0]))
3631 return "fld%z1\t%y1";
3632 else
3633 return "fst\t%y0";
3634
3635 case 1:
3636 /* There is no non-popping store to memory for XFmode. So if
3637 we need one, follow the store with a load. */
3638 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3640 else
3641 return "fstp%z0\t%y0";
3642
3643 default:
3644 abort ();
3645 }
3646 }
3647 [(set_attr "type" "fmov")
3648 (set_attr "mode" "DF,XF")])
3649
3650 ;; %%% This seems bad bad news.
3651 ;; This cannot output into an f-reg because there is no way to be sure
3652 ;; of truncating in that case. Otherwise this is just like a simple move
3653 ;; insn. So we pretend we can output to a reg in order to get better
3654 ;; register preferencing, but we really use a stack slot.
3655
3656 (define_expand "truncdfsf2"
3657 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3658 (float_truncate:SF
3659 (match_operand:DF 1 "register_operand" "")))
3660 (clobber (match_dup 2))])]
3661 "TARGET_80387 || TARGET_SSE2"
3662 "
3663 if (TARGET_80387)
3664 operands[2] = assign_386_stack_local (SFmode, 0);
3665 else
3666 {
3667 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3668 DONE;
3669 }
3670 ")
3671
3672 (define_insn "*truncdfsf2_1"
3673 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3674 (float_truncate:SF
3675 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3676 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3677 "TARGET_80387 && !TARGET_SSE2"
3678 {
3679 switch (which_alternative)
3680 {
3681 case 0:
3682 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3683 return "fstp%z0\t%y0";
3684 else
3685 return "fst%z0\t%y0";
3686 default:
3687 abort ();
3688 }
3689 }
3690 [(set_attr "type" "fmov,multi,multi,multi")
3691 (set_attr "mode" "SF,SF,SF,SF")])
3692
3693 (define_insn "*truncdfsf2_1_sse"
3694 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3695 (float_truncate:SF
3696 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3697 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3698 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3699 {
3700 switch (which_alternative)
3701 {
3702 case 0:
3703 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3704 return "fstp%z0\t%y0";
3705 else
3706 return "fst%z0\t%y0";
3707 case 4:
3708 return "#";
3709 default:
3710 abort ();
3711 }
3712 }
3713 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3714 (set_attr "mode" "SF,SF,SF,SF,DF")])
3715
3716 (define_insn "*truncdfsf2_1_sse_nooverlap"
3717 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3718 (float_truncate:SF
3719 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3720 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3721 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3722 {
3723 switch (which_alternative)
3724 {
3725 case 0:
3726 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3727 return "fstp%z0\t%y0";
3728 else
3729 return "fst%z0\t%y0";
3730 case 4:
3731 return "#";
3732 default:
3733 abort ();
3734 }
3735 }
3736 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3737 (set_attr "mode" "SF,SF,SF,SF,DF")])
3738
3739 (define_insn "*truncdfsf2_2"
3740 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3741 (float_truncate:SF
3742 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3743 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3744 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3745 {
3746 switch (which_alternative)
3747 {
3748 case 0:
3749 case 1:
3750 return "cvtsd2ss\t{%1, %0|%0, %1}";
3751 case 2:
3752 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753 return "fstp%z0\t%y0";
3754 else
3755 return "fst%z0\t%y0";
3756 default:
3757 abort ();
3758 }
3759 }
3760 [(set_attr "type" "ssecvt,ssecvt,fmov")
3761 (set_attr "athlon_decode" "vector,double,*")
3762 (set_attr "mode" "SF,SF,SF")])
3763
3764 (define_insn "*truncdfsf2_2_nooverlap"
3765 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3766 (float_truncate:SF
3767 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3768 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3769 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3770 {
3771 switch (which_alternative)
3772 {
3773 case 0:
3774 return "#";
3775 case 1:
3776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777 return "fstp%z0\t%y0";
3778 else
3779 return "fst%z0\t%y0";
3780 default:
3781 abort ();
3782 }
3783 }
3784 [(set_attr "type" "ssecvt,fmov")
3785 (set_attr "mode" "DF,SF")])
3786
3787 (define_insn "*truncdfsf2_3"
3788 [(set (match_operand:SF 0 "memory_operand" "=m")
3789 (float_truncate:SF
3790 (match_operand:DF 1 "register_operand" "f")))]
3791 "TARGET_80387"
3792 {
3793 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3794 return "fstp%z0\t%y0";
3795 else
3796 return "fst%z0\t%y0";
3797 }
3798 [(set_attr "type" "fmov")
3799 (set_attr "mode" "SF")])
3800
3801 (define_insn "truncdfsf2_sse_only"
3802 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3803 (float_truncate:SF
3804 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3805 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3806 "cvtsd2ss\t{%1, %0|%0, %1}"
3807 [(set_attr "type" "ssecvt")
3808 (set_attr "athlon_decode" "vector,double")
3809 (set_attr "mode" "SF")])
3810
3811 (define_insn "*truncdfsf2_sse_only_nooverlap"
3812 [(set (match_operand:SF 0 "register_operand" "=&Y")
3813 (float_truncate:SF
3814 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3815 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3816 "#"
3817 [(set_attr "type" "ssecvt")
3818 (set_attr "mode" "DF")])
3819
3820 (define_split
3821 [(set (match_operand:SF 0 "memory_operand" "")
3822 (float_truncate:SF
3823 (match_operand:DF 1 "register_operand" "")))
3824 (clobber (match_operand:SF 2 "memory_operand" ""))]
3825 "TARGET_80387"
3826 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3827 "")
3828
3829 ; Avoid possible reformatting penalty on the destination by first
3830 ; zeroing it out
3831 (define_split
3832 [(set (match_operand:SF 0 "register_operand" "")
3833 (float_truncate:SF
3834 (match_operand:DF 1 "nonimmediate_operand" "")))
3835 (clobber (match_operand 2 "" ""))]
3836 "TARGET_80387 && reload_completed
3837 && SSE_REG_P (operands[0])
3838 && !STACK_REG_P (operands[1])"
3839 [(const_int 0)]
3840 {
3841 rtx src, dest;
3842 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3843 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3844 else
3845 {
3846 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3847 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3848 /* simplify_gen_subreg refuses to widen memory references. */
3849 if (GET_CODE (src) == SUBREG)
3850 alter_subreg (&src);
3851 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3852 abort ();
3853 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3854 emit_insn (gen_cvtsd2ss (dest, dest, src));
3855 }
3856 DONE;
3857 })
3858
3859 (define_split
3860 [(set (match_operand:SF 0 "register_operand" "")
3861 (float_truncate:SF
3862 (match_operand:DF 1 "nonimmediate_operand" "")))]
3863 "TARGET_80387 && reload_completed
3864 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3865 [(const_int 0)]
3866 {
3867 rtx src, dest;
3868 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3869 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3870 /* simplify_gen_subreg refuses to widen memory references. */
3871 if (GET_CODE (src) == SUBREG)
3872 alter_subreg (&src);
3873 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3874 abort ();
3875 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3876 emit_insn (gen_cvtsd2ss (dest, dest, src));
3877 DONE;
3878 })
3879
3880 (define_split
3881 [(set (match_operand:SF 0 "register_operand" "")
3882 (float_truncate:SF
3883 (match_operand:DF 1 "fp_register_operand" "")))
3884 (clobber (match_operand:SF 2 "memory_operand" ""))]
3885 "TARGET_80387 && reload_completed"
3886 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3887 (set (match_dup 0) (match_dup 2))]
3888 "")
3889
3890 (define_expand "truncxfsf2"
3891 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3892 (float_truncate:SF
3893 (match_operand:XF 1 "register_operand" "")))
3894 (clobber (match_dup 2))])]
3895 "TARGET_80387"
3896 "operands[2] = assign_386_stack_local (SFmode, 0);")
3897
3898 (define_insn "*truncxfsf2_1"
3899 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3900 (float_truncate:SF
3901 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3902 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3903 "TARGET_80387"
3904 {
3905 switch (which_alternative)
3906 {
3907 case 0:
3908 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3909 return "fstp%z0\t%y0";
3910 else
3911 return "fst%z0\t%y0";
3912 default:
3913 abort();
3914 }
3915 }
3916 [(set_attr "type" "fmov,multi,multi,multi")
3917 (set_attr "mode" "SF")])
3918
3919 (define_insn "*truncxfsf2_2"
3920 [(set (match_operand:SF 0 "memory_operand" "=m")
3921 (float_truncate:SF
3922 (match_operand:XF 1 "register_operand" "f")))]
3923 "TARGET_80387"
3924 {
3925 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926 return "fstp%z0\t%y0";
3927 else
3928 return "fst%z0\t%y0";
3929 }
3930 [(set_attr "type" "fmov")
3931 (set_attr "mode" "SF")])
3932
3933 (define_split
3934 [(set (match_operand:SF 0 "memory_operand" "")
3935 (float_truncate:SF
3936 (match_operand:XF 1 "register_operand" "")))
3937 (clobber (match_operand:SF 2 "memory_operand" ""))]
3938 "TARGET_80387"
3939 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3940 "")
3941
3942 (define_split
3943 [(set (match_operand:SF 0 "register_operand" "")
3944 (float_truncate:SF
3945 (match_operand:XF 1 "register_operand" "")))
3946 (clobber (match_operand:SF 2 "memory_operand" ""))]
3947 "TARGET_80387 && reload_completed"
3948 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3949 (set (match_dup 0) (match_dup 2))]
3950 "")
3951
3952 (define_expand "truncxfdf2"
3953 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3954 (float_truncate:DF
3955 (match_operand:XF 1 "register_operand" "")))
3956 (clobber (match_dup 2))])]
3957 "TARGET_80387"
3958 "operands[2] = assign_386_stack_local (DFmode, 0);")
3959
3960 (define_insn "*truncxfdf2_1"
3961 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3962 (float_truncate:DF
3963 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3964 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3965 "TARGET_80387"
3966 {
3967 switch (which_alternative)
3968 {
3969 case 0:
3970 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3971 return "fstp%z0\t%y0";
3972 else
3973 return "fst%z0\t%y0";
3974 default:
3975 abort();
3976 }
3977 abort ();
3978 }
3979 [(set_attr "type" "fmov,multi,multi,multi")
3980 (set_attr "mode" "DF")])
3981
3982 (define_insn "*truncxfdf2_2"
3983 [(set (match_operand:DF 0 "memory_operand" "=m")
3984 (float_truncate:DF
3985 (match_operand:XF 1 "register_operand" "f")))]
3986 "TARGET_80387"
3987 {
3988 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3989 return "fstp%z0\t%y0";
3990 else
3991 return "fst%z0\t%y0";
3992 }
3993 [(set_attr "type" "fmov")
3994 (set_attr "mode" "DF")])
3995
3996 (define_split
3997 [(set (match_operand:DF 0 "memory_operand" "")
3998 (float_truncate:DF
3999 (match_operand:XF 1 "register_operand" "")))
4000 (clobber (match_operand:DF 2 "memory_operand" ""))]
4001 "TARGET_80387"
4002 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4003 "")
4004
4005 (define_split
4006 [(set (match_operand:DF 0 "register_operand" "")
4007 (float_truncate:DF
4008 (match_operand:XF 1 "register_operand" "")))
4009 (clobber (match_operand:DF 2 "memory_operand" ""))]
4010 "TARGET_80387 && reload_completed"
4011 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4012 (set (match_dup 0) (match_dup 2))]
4013 "")
4014
4015 \f
4016 ;; %%% Break up all these bad boys.
4017
4018 ;; Signed conversion to DImode.
4019
4020 (define_expand "fix_truncxfdi2"
4021 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4022 (fix:DI (match_operand:XF 1 "register_operand" "")))
4023 (clobber (reg:CC 17))])]
4024 "TARGET_80387"
4025 "")
4026
4027 (define_expand "fix_truncdfdi2"
4028 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4029 (fix:DI (match_operand:DF 1 "register_operand" "")))
4030 (clobber (reg:CC 17))])]
4031 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4032 {
4033 if (TARGET_64BIT && TARGET_SSE2)
4034 {
4035 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4036 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4037 if (out != operands[0])
4038 emit_move_insn (operands[0], out);
4039 DONE;
4040 }
4041 })
4042
4043 (define_expand "fix_truncsfdi2"
4044 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4045 (fix:DI (match_operand:SF 1 "register_operand" "")))
4046 (clobber (reg:CC 17))])]
4047 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4048 {
4049 if (TARGET_SSE && TARGET_64BIT)
4050 {
4051 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4052 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4053 if (out != operands[0])
4054 emit_move_insn (operands[0], out);
4055 DONE;
4056 }
4057 })
4058
4059 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4060 ;; of the machinery.
4061 (define_insn_and_split "*fix_truncdi_1"
4062 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4063 (fix:DI (match_operand 1 "register_operand" "f,f")))
4064 (clobber (reg:CC 17))]
4065 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4066 && !reload_completed && !reload_in_progress
4067 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4068 "#"
4069 "&& 1"
4070 [(const_int 0)]
4071 {
4072 ix86_optimize_mode_switching = 1;
4073 operands[2] = assign_386_stack_local (HImode, 1);
4074 operands[3] = assign_386_stack_local (HImode, 2);
4075 if (memory_operand (operands[0], VOIDmode))
4076 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4077 operands[2], operands[3]));
4078 else
4079 {
4080 operands[4] = assign_386_stack_local (DImode, 0);
4081 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4082 operands[2], operands[3],
4083 operands[4]));
4084 }
4085 DONE;
4086 }
4087 [(set_attr "type" "fistp")
4088 (set_attr "mode" "DI")])
4089
4090 (define_insn "fix_truncdi_nomemory"
4091 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4092 (fix:DI (match_operand 1 "register_operand" "f,f")))
4093 (use (match_operand:HI 2 "memory_operand" "m,m"))
4094 (use (match_operand:HI 3 "memory_operand" "m,m"))
4095 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4096 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4097 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4098 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4099 "#"
4100 [(set_attr "type" "fistp")
4101 (set_attr "mode" "DI")])
4102
4103 (define_insn "fix_truncdi_memory"
4104 [(set (match_operand:DI 0 "memory_operand" "=m")
4105 (fix:DI (match_operand 1 "register_operand" "f")))
4106 (use (match_operand:HI 2 "memory_operand" "m"))
4107 (use (match_operand:HI 3 "memory_operand" "m"))
4108 (clobber (match_scratch:DF 4 "=&1f"))]
4109 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4110 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4111 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4112 [(set_attr "type" "fistp")
4113 (set_attr "mode" "DI")])
4114
4115 (define_split
4116 [(set (match_operand:DI 0 "register_operand" "")
4117 (fix:DI (match_operand 1 "register_operand" "")))
4118 (use (match_operand:HI 2 "memory_operand" ""))
4119 (use (match_operand:HI 3 "memory_operand" ""))
4120 (clobber (match_operand:DI 4 "memory_operand" ""))
4121 (clobber (match_scratch 5 ""))]
4122 "reload_completed"
4123 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4124 (use (match_dup 2))
4125 (use (match_dup 3))
4126 (clobber (match_dup 5))])
4127 (set (match_dup 0) (match_dup 4))]
4128 "")
4129
4130 (define_split
4131 [(set (match_operand:DI 0 "memory_operand" "")
4132 (fix:DI (match_operand 1 "register_operand" "")))
4133 (use (match_operand:HI 2 "memory_operand" ""))
4134 (use (match_operand:HI 3 "memory_operand" ""))
4135 (clobber (match_operand:DI 4 "memory_operand" ""))
4136 (clobber (match_scratch 5 ""))]
4137 "reload_completed"
4138 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4139 (use (match_dup 2))
4140 (use (match_dup 3))
4141 (clobber (match_dup 5))])]
4142 "")
4143
4144 ;; When SSE available, it is always faster to use it!
4145 (define_insn "fix_truncsfdi_sse"
4146 [(set (match_operand:DI 0 "register_operand" "=r,r")
4147 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4148 "TARGET_64BIT && TARGET_SSE"
4149 "cvttss2si{q}\t{%1, %0|%0, %1}"
4150 [(set_attr "type" "sseicvt")
4151 (set_attr "mode" "SF")
4152 (set_attr "athlon_decode" "double,vector")])
4153
4154 ;; Avoid vector decoded form of the instruction.
4155 (define_peephole2
4156 [(match_scratch:SF 2 "x")
4157 (set (match_operand:DI 0 "register_operand" "")
4158 (fix:DI (match_operand:SF 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 (define_insn "fix_truncdfdi_sse"
4165 [(set (match_operand:DI 0 "register_operand" "=r,r")
4166 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4167 "TARGET_64BIT && TARGET_SSE2"
4168 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4169 [(set_attr "type" "sseicvt,sseicvt")
4170 (set_attr "mode" "DF")
4171 (set_attr "athlon_decode" "double,vector")])
4172
4173 ;; Avoid vector decoded form of the instruction.
4174 (define_peephole2
4175 [(match_scratch:DF 2 "Y")
4176 (set (match_operand:DI 0 "register_operand" "")
4177 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4178 "TARGET_K8 && !optimize_size"
4179 [(set (match_dup 2) (match_dup 1))
4180 (set (match_dup 0) (fix:DI (match_dup 2)))]
4181 "")
4182
4183 ;; Signed conversion to SImode.
4184
4185 (define_expand "fix_truncxfsi2"
4186 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4187 (fix:SI (match_operand:XF 1 "register_operand" "")))
4188 (clobber (reg:CC 17))])]
4189 "TARGET_80387"
4190 "")
4191
4192 (define_expand "fix_truncdfsi2"
4193 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4194 (fix:SI (match_operand:DF 1 "register_operand" "")))
4195 (clobber (reg:CC 17))])]
4196 "TARGET_80387 || TARGET_SSE2"
4197 {
4198 if (TARGET_SSE2)
4199 {
4200 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4201 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4202 if (out != operands[0])
4203 emit_move_insn (operands[0], out);
4204 DONE;
4205 }
4206 })
4207
4208 (define_expand "fix_truncsfsi2"
4209 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4210 (fix:SI (match_operand:SF 1 "register_operand" "")))
4211 (clobber (reg:CC 17))])]
4212 "TARGET_80387 || TARGET_SSE"
4213 {
4214 if (TARGET_SSE)
4215 {
4216 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4217 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4218 if (out != operands[0])
4219 emit_move_insn (operands[0], out);
4220 DONE;
4221 }
4222 })
4223
4224 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4225 ;; of the machinery.
4226 (define_insn_and_split "*fix_truncsi_1"
4227 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4228 (fix:SI (match_operand 1 "register_operand" "f,f")))
4229 (clobber (reg:CC 17))]
4230 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4231 && !reload_completed && !reload_in_progress
4232 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4233 "#"
4234 "&& 1"
4235 [(const_int 0)]
4236 {
4237 ix86_optimize_mode_switching = 1;
4238 operands[2] = assign_386_stack_local (HImode, 1);
4239 operands[3] = assign_386_stack_local (HImode, 2);
4240 if (memory_operand (operands[0], VOIDmode))
4241 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4242 operands[2], operands[3]));
4243 else
4244 {
4245 operands[4] = assign_386_stack_local (SImode, 0);
4246 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4247 operands[2], operands[3],
4248 operands[4]));
4249 }
4250 DONE;
4251 }
4252 [(set_attr "type" "fistp")
4253 (set_attr "mode" "SI")])
4254
4255 (define_insn "fix_truncsi_nomemory"
4256 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4257 (fix:SI (match_operand 1 "register_operand" "f,f")))
4258 (use (match_operand:HI 2 "memory_operand" "m,m"))
4259 (use (match_operand:HI 3 "memory_operand" "m,m"))
4260 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4261 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4262 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4263 "#"
4264 [(set_attr "type" "fistp")
4265 (set_attr "mode" "SI")])
4266
4267 (define_insn "fix_truncsi_memory"
4268 [(set (match_operand:SI 0 "memory_operand" "=m")
4269 (fix:SI (match_operand 1 "register_operand" "f")))
4270 (use (match_operand:HI 2 "memory_operand" "m"))
4271 (use (match_operand:HI 3 "memory_operand" "m"))]
4272 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4273 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4274 "* return output_fix_trunc (insn, operands);"
4275 [(set_attr "type" "fistp")
4276 (set_attr "mode" "SI")])
4277
4278 ;; When SSE available, it is always faster to use it!
4279 (define_insn "fix_truncsfsi_sse"
4280 [(set (match_operand:SI 0 "register_operand" "=r,r")
4281 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4282 "TARGET_SSE"
4283 "cvttss2si\t{%1, %0|%0, %1}"
4284 [(set_attr "type" "sseicvt")
4285 (set_attr "mode" "DF")
4286 (set_attr "athlon_decode" "double,vector")])
4287
4288 ;; Avoid vector decoded form of the instruction.
4289 (define_peephole2
4290 [(match_scratch:SF 2 "x")
4291 (set (match_operand:SI 0 "register_operand" "")
4292 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4293 "TARGET_K8 && !optimize_size"
4294 [(set (match_dup 2) (match_dup 1))
4295 (set (match_dup 0) (fix:SI (match_dup 2)))]
4296 "")
4297
4298 (define_insn "fix_truncdfsi_sse"
4299 [(set (match_operand:SI 0 "register_operand" "=r,r")
4300 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4301 "TARGET_SSE2"
4302 "cvttsd2si\t{%1, %0|%0, %1}"
4303 [(set_attr "type" "sseicvt")
4304 (set_attr "mode" "DF")
4305 (set_attr "athlon_decode" "double,vector")])
4306
4307 ;; Avoid vector decoded form of the instruction.
4308 (define_peephole2
4309 [(match_scratch:DF 2 "Y")
4310 (set (match_operand:SI 0 "register_operand" "")
4311 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4312 "TARGET_K8 && !optimize_size"
4313 [(set (match_dup 2) (match_dup 1))
4314 (set (match_dup 0) (fix:SI (match_dup 2)))]
4315 "")
4316
4317 (define_split
4318 [(set (match_operand:SI 0 "register_operand" "")
4319 (fix:SI (match_operand 1 "register_operand" "")))
4320 (use (match_operand:HI 2 "memory_operand" ""))
4321 (use (match_operand:HI 3 "memory_operand" ""))
4322 (clobber (match_operand:SI 4 "memory_operand" ""))]
4323 "reload_completed"
4324 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4325 (use (match_dup 2))
4326 (use (match_dup 3))])
4327 (set (match_dup 0) (match_dup 4))]
4328 "")
4329
4330 (define_split
4331 [(set (match_operand:SI 0 "memory_operand" "")
4332 (fix:SI (match_operand 1 "register_operand" "")))
4333 (use (match_operand:HI 2 "memory_operand" ""))
4334 (use (match_operand:HI 3 "memory_operand" ""))
4335 (clobber (match_operand:SI 4 "memory_operand" ""))]
4336 "reload_completed"
4337 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4338 (use (match_dup 2))
4339 (use (match_dup 3))])]
4340 "")
4341
4342 ;; Signed conversion to HImode.
4343
4344 (define_expand "fix_truncxfhi2"
4345 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4346 (fix:HI (match_operand:XF 1 "register_operand" "")))
4347 (clobber (reg:CC 17))])]
4348 "TARGET_80387"
4349 "")
4350
4351 (define_expand "fix_truncdfhi2"
4352 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4353 (fix:HI (match_operand:DF 1 "register_operand" "")))
4354 (clobber (reg:CC 17))])]
4355 "TARGET_80387 && !TARGET_SSE2"
4356 "")
4357
4358 (define_expand "fix_truncsfhi2"
4359 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4360 (fix:HI (match_operand:SF 1 "register_operand" "")))
4361 (clobber (reg:CC 17))])]
4362 "TARGET_80387 && !TARGET_SSE"
4363 "")
4364
4365 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4366 ;; of the machinery.
4367 (define_insn_and_split "*fix_trunchi_1"
4368 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4369 (fix:HI (match_operand 1 "register_operand" "f,f")))
4370 (clobber (reg:CC 17))]
4371 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372 && !reload_completed && !reload_in_progress
4373 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374 "#"
4375 ""
4376 [(const_int 0)]
4377 {
4378 ix86_optimize_mode_switching = 1;
4379 operands[2] = assign_386_stack_local (HImode, 1);
4380 operands[3] = assign_386_stack_local (HImode, 2);
4381 if (memory_operand (operands[0], VOIDmode))
4382 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4383 operands[2], operands[3]));
4384 else
4385 {
4386 operands[4] = assign_386_stack_local (HImode, 0);
4387 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4388 operands[2], operands[3],
4389 operands[4]));
4390 }
4391 DONE;
4392 }
4393 [(set_attr "type" "fistp")
4394 (set_attr "mode" "HI")])
4395
4396 (define_insn "fix_trunchi_nomemory"
4397 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4398 (fix:HI (match_operand 1 "register_operand" "f,f")))
4399 (use (match_operand:HI 2 "memory_operand" "m,m"))
4400 (use (match_operand:HI 3 "memory_operand" "m,m"))
4401 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4402 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4403 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4404 "#"
4405 [(set_attr "type" "fistp")
4406 (set_attr "mode" "HI")])
4407
4408 (define_insn "fix_trunchi_memory"
4409 [(set (match_operand:HI 0 "memory_operand" "=m")
4410 (fix:HI (match_operand 1 "register_operand" "f")))
4411 (use (match_operand:HI 2 "memory_operand" "m"))
4412 (use (match_operand:HI 3 "memory_operand" "m"))]
4413 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4415 "* return output_fix_trunc (insn, operands);"
4416 [(set_attr "type" "fistp")
4417 (set_attr "mode" "HI")])
4418
4419 (define_split
4420 [(set (match_operand:HI 0 "memory_operand" "")
4421 (fix:HI (match_operand 1 "register_operand" "")))
4422 (use (match_operand:HI 2 "memory_operand" ""))
4423 (use (match_operand:HI 3 "memory_operand" ""))
4424 (clobber (match_operand:HI 4 "memory_operand" ""))]
4425 "reload_completed"
4426 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4427 (use (match_dup 2))
4428 (use (match_dup 3))])]
4429 "")
4430
4431 (define_split
4432 [(set (match_operand:HI 0 "register_operand" "")
4433 (fix:HI (match_operand 1 "register_operand" "")))
4434 (use (match_operand:HI 2 "memory_operand" ""))
4435 (use (match_operand:HI 3 "memory_operand" ""))
4436 (clobber (match_operand:HI 4 "memory_operand" ""))]
4437 "reload_completed"
4438 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4439 (use (match_dup 2))
4440 (use (match_dup 3))
4441 (clobber (match_dup 4))])
4442 (set (match_dup 0) (match_dup 4))]
4443 "")
4444
4445 ;; %% Not used yet.
4446 (define_insn "x86_fnstcw_1"
4447 [(set (match_operand:HI 0 "memory_operand" "=m")
4448 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4449 "TARGET_80387"
4450 "fnstcw\t%0"
4451 [(set_attr "length" "2")
4452 (set_attr "mode" "HI")
4453 (set_attr "unit" "i387")
4454 (set_attr "ppro_uops" "few")])
4455
4456 (define_insn "x86_fldcw_1"
4457 [(set (reg:HI 18)
4458 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4459 "TARGET_80387"
4460 "fldcw\t%0"
4461 [(set_attr "length" "2")
4462 (set_attr "mode" "HI")
4463 (set_attr "unit" "i387")
4464 (set_attr "athlon_decode" "vector")
4465 (set_attr "ppro_uops" "few")])
4466 \f
4467 ;; Conversion between fixed point and floating point.
4468
4469 ;; Even though we only accept memory inputs, the backend _really_
4470 ;; wants to be able to do this between registers.
4471
4472 (define_expand "floathisf2"
4473 [(set (match_operand:SF 0 "register_operand" "")
4474 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4475 "TARGET_SSE || TARGET_80387"
4476 {
4477 if (TARGET_SSE && TARGET_SSE_MATH)
4478 {
4479 emit_insn (gen_floatsisf2 (operands[0],
4480 convert_to_mode (SImode, operands[1], 0)));
4481 DONE;
4482 }
4483 })
4484
4485 (define_insn "*floathisf2_1"
4486 [(set (match_operand:SF 0 "register_operand" "=f,f")
4487 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4488 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4489 "@
4490 fild%z1\t%1
4491 #"
4492 [(set_attr "type" "fmov,multi")
4493 (set_attr "mode" "SF")
4494 (set_attr "fp_int_src" "true")])
4495
4496 (define_expand "floatsisf2"
4497 [(set (match_operand:SF 0 "register_operand" "")
4498 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4499 "TARGET_SSE || TARGET_80387"
4500 "")
4501
4502 (define_insn "*floatsisf2_i387"
4503 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4504 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4505 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4506 "@
4507 fild%z1\t%1
4508 #
4509 cvtsi2ss\t{%1, %0|%0, %1}
4510 cvtsi2ss\t{%1, %0|%0, %1}"
4511 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4512 (set_attr "mode" "SF")
4513 (set_attr "athlon_decode" "*,*,vector,double")
4514 (set_attr "fp_int_src" "true")])
4515
4516 (define_insn "*floatsisf2_sse"
4517 [(set (match_operand:SF 0 "register_operand" "=x,x")
4518 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4519 "TARGET_SSE"
4520 "cvtsi2ss\t{%1, %0|%0, %1}"
4521 [(set_attr "type" "sseicvt")
4522 (set_attr "mode" "SF")
4523 (set_attr "athlon_decode" "vector,double")
4524 (set_attr "fp_int_src" "true")])
4525
4526 ; Avoid possible reformatting penalty on the destination by first
4527 ; zeroing it out
4528 (define_split
4529 [(set (match_operand:SF 0 "register_operand" "")
4530 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4531 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4532 && SSE_REG_P (operands[0])"
4533 [(const_int 0)]
4534 {
4535 rtx dest;
4536 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4537 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4538 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4539 DONE;
4540 })
4541
4542 (define_expand "floatdisf2"
4543 [(set (match_operand:SF 0 "register_operand" "")
4544 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4545 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4546 "")
4547
4548 (define_insn "*floatdisf2_i387_only"
4549 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4550 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4551 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4552 "@
4553 fild%z1\t%1
4554 #"
4555 [(set_attr "type" "fmov,multi")
4556 (set_attr "mode" "SF")
4557 (set_attr "fp_int_src" "true")])
4558
4559 (define_insn "*floatdisf2_i387"
4560 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4561 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4563 "@
4564 fild%z1\t%1
4565 #
4566 cvtsi2ss{q}\t{%1, %0|%0, %1}
4567 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569 (set_attr "mode" "SF")
4570 (set_attr "athlon_decode" "*,*,vector,double")
4571 (set_attr "fp_int_src" "true")])
4572
4573 (define_insn "*floatdisf2_sse"
4574 [(set (match_operand:SF 0 "register_operand" "=x,x")
4575 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4576 "TARGET_64BIT && TARGET_SSE"
4577 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4578 [(set_attr "type" "sseicvt")
4579 (set_attr "mode" "SF")
4580 (set_attr "athlon_decode" "vector,double")
4581 (set_attr "fp_int_src" "true")])
4582
4583 ; Avoid possible reformatting penalty on the destination by first
4584 ; zeroing it out
4585 (define_split
4586 [(set (match_operand:SF 0 "register_operand" "")
4587 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4588 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4589 && SSE_REG_P (operands[0])"
4590 [(const_int 0)]
4591 {
4592 rtx dest;
4593 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4594 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4595 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4596 DONE;
4597 })
4598
4599 (define_expand "floathidf2"
4600 [(set (match_operand:DF 0 "register_operand" "")
4601 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4602 "TARGET_SSE2 || TARGET_80387"
4603 {
4604 if (TARGET_SSE && TARGET_SSE_MATH)
4605 {
4606 emit_insn (gen_floatsidf2 (operands[0],
4607 convert_to_mode (SImode, operands[1], 0)));
4608 DONE;
4609 }
4610 })
4611
4612 (define_insn "*floathidf2_1"
4613 [(set (match_operand:DF 0 "register_operand" "=f,f")
4614 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4615 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4616 "@
4617 fild%z1\t%1
4618 #"
4619 [(set_attr "type" "fmov,multi")
4620 (set_attr "mode" "DF")
4621 (set_attr "fp_int_src" "true")])
4622
4623 (define_expand "floatsidf2"
4624 [(set (match_operand:DF 0 "register_operand" "")
4625 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4626 "TARGET_80387 || TARGET_SSE2"
4627 "")
4628
4629 (define_insn "*floatsidf2_i387"
4630 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4631 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4632 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4633 "@
4634 fild%z1\t%1
4635 #
4636 cvtsi2sd\t{%1, %0|%0, %1}
4637 cvtsi2sd\t{%1, %0|%0, %1}"
4638 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4639 (set_attr "mode" "DF")
4640 (set_attr "athlon_decode" "*,*,double,direct")
4641 (set_attr "fp_int_src" "true")])
4642
4643 (define_insn "*floatsidf2_sse"
4644 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4645 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4646 "TARGET_SSE2"
4647 "cvtsi2sd\t{%1, %0|%0, %1}"
4648 [(set_attr "type" "sseicvt")
4649 (set_attr "mode" "DF")
4650 (set_attr "athlon_decode" "double,direct")
4651 (set_attr "fp_int_src" "true")])
4652
4653 (define_expand "floatdidf2"
4654 [(set (match_operand:DF 0 "register_operand" "")
4655 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4656 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4657 "")
4658
4659 (define_insn "*floatdidf2_i387_only"
4660 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4661 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4662 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4663 "@
4664 fild%z1\t%1
4665 #"
4666 [(set_attr "type" "fmov,multi")
4667 (set_attr "mode" "DF")
4668 (set_attr "fp_int_src" "true")])
4669
4670 (define_insn "*floatdidf2_i387"
4671 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4672 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4673 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4674 "@
4675 fild%z1\t%1
4676 #
4677 cvtsi2sd{q}\t{%1, %0|%0, %1}
4678 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4679 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4680 (set_attr "mode" "DF")
4681 (set_attr "athlon_decode" "*,*,double,direct")
4682 (set_attr "fp_int_src" "true")])
4683
4684 (define_insn "*floatdidf2_sse"
4685 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4686 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4687 "TARGET_SSE2"
4688 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4689 [(set_attr "type" "sseicvt")
4690 (set_attr "mode" "DF")
4691 (set_attr "athlon_decode" "double,direct")
4692 (set_attr "fp_int_src" "true")])
4693
4694 (define_insn "floathixf2"
4695 [(set (match_operand:XF 0 "register_operand" "=f,f")
4696 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4697 "TARGET_80387"
4698 "@
4699 fild%z1\t%1
4700 #"
4701 [(set_attr "type" "fmov,multi")
4702 (set_attr "mode" "XF")
4703 (set_attr "fp_int_src" "true")])
4704
4705 (define_insn "floatsixf2"
4706 [(set (match_operand:XF 0 "register_operand" "=f,f")
4707 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4708 "TARGET_80387"
4709 "@
4710 fild%z1\t%1
4711 #"
4712 [(set_attr "type" "fmov,multi")
4713 (set_attr "mode" "XF")
4714 (set_attr "fp_int_src" "true")])
4715
4716 (define_insn "floatdixf2"
4717 [(set (match_operand:XF 0 "register_operand" "=f,f")
4718 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4719 "TARGET_80387"
4720 "@
4721 fild%z1\t%1
4722 #"
4723 [(set_attr "type" "fmov,multi")
4724 (set_attr "mode" "XF")
4725 (set_attr "fp_int_src" "true")])
4726
4727 ;; %%% Kill these when reload knows how to do it.
4728 (define_split
4729 [(set (match_operand 0 "fp_register_operand" "")
4730 (float (match_operand 1 "register_operand" "")))]
4731 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4732 [(const_int 0)]
4733 {
4734 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4735 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4736 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4737 ix86_free_from_memory (GET_MODE (operands[1]));
4738 DONE;
4739 })
4740
4741 (define_expand "floatunssisf2"
4742 [(use (match_operand:SF 0 "register_operand" ""))
4743 (use (match_operand:SI 1 "register_operand" ""))]
4744 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4745 "x86_emit_floatuns (operands); DONE;")
4746
4747 (define_expand "floatunsdisf2"
4748 [(use (match_operand:SF 0 "register_operand" ""))
4749 (use (match_operand:DI 1 "register_operand" ""))]
4750 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4751 "x86_emit_floatuns (operands); DONE;")
4752
4753 (define_expand "floatunsdidf2"
4754 [(use (match_operand:DF 0 "register_operand" ""))
4755 (use (match_operand:DI 1 "register_operand" ""))]
4756 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4757 "x86_emit_floatuns (operands); DONE;")
4758 \f
4759 ;; SSE extract/set expanders
4760
4761 (define_expand "vec_setv2df"
4762 [(match_operand:V2DF 0 "register_operand" "")
4763 (match_operand:DF 1 "register_operand" "")
4764 (match_operand 2 "const_int_operand" "")]
4765 "TARGET_SSE2"
4766 {
4767 switch (INTVAL (operands[2]))
4768 {
4769 case 0:
4770 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4771 simplify_gen_subreg (V2DFmode, operands[1],
4772 DFmode, 0)));
4773 break;
4774 case 1:
4775 {
4776 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4777
4778 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4779 }
4780 break;
4781 default:
4782 abort ();
4783 }
4784 DONE;
4785 })
4786
4787 (define_expand "vec_extractv2df"
4788 [(match_operand:DF 0 "register_operand" "")
4789 (match_operand:V2DF 1 "register_operand" "")
4790 (match_operand 2 "const_int_operand" "")]
4791 "TARGET_SSE2"
4792 {
4793 switch (INTVAL (operands[2]))
4794 {
4795 case 0:
4796 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4797 break;
4798 case 1:
4799 {
4800 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4801
4802 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4803 }
4804 break;
4805 default:
4806 abort ();
4807 }
4808 DONE;
4809 })
4810
4811 (define_expand "vec_initv2df"
4812 [(match_operand:V2DF 0 "register_operand" "")
4813 (match_operand 1 "" "")]
4814 "TARGET_SSE2"
4815 {
4816 ix86_expand_vector_init (operands[0], operands[1]);
4817 DONE;
4818 })
4819
4820 (define_expand "vec_setv4sf"
4821 [(match_operand:V4SF 0 "register_operand" "")
4822 (match_operand:SF 1 "register_operand" "")
4823 (match_operand 2 "const_int_operand" "")]
4824 "TARGET_SSE"
4825 {
4826 switch (INTVAL (operands[2]))
4827 {
4828 case 0:
4829 emit_insn (gen_sse_movss (operands[0], operands[0],
4830 simplify_gen_subreg (V4SFmode, operands[1],
4831 SFmode, 0)));
4832 break;
4833 case 1:
4834 {
4835 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4836 rtx tmp = gen_reg_rtx (V4SFmode);
4837
4838 emit_move_insn (tmp, operands[0]);
4839 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4840 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4841 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4842 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4843 }
4844 case 2:
4845 {
4846 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4847 rtx tmp = gen_reg_rtx (V4SFmode);
4848
4849 emit_move_insn (tmp, operands[0]);
4850 emit_insn (gen_sse_movss (tmp, tmp, op1));
4851 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4852 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4853 }
4854 break;
4855 case 3:
4856 {
4857 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4858 rtx tmp = gen_reg_rtx (V4SFmode);
4859
4860 emit_move_insn (tmp, operands[0]);
4861 emit_insn (gen_sse_movss (tmp, tmp, op1));
4862 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4863 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4864 }
4865 break;
4866 default:
4867 abort ();
4868 }
4869 DONE;
4870 })
4871
4872 (define_expand "vec_extractv4sf"
4873 [(match_operand:SF 0 "register_operand" "")
4874 (match_operand:V4SF 1 "register_operand" "")
4875 (match_operand 2 "const_int_operand" "")]
4876 "TARGET_SSE"
4877 {
4878 switch (INTVAL (operands[2]))
4879 {
4880 case 0:
4881 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4882 break;
4883 case 1:
4884 {
4885 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4886 rtx tmp = gen_reg_rtx (V4SFmode);
4887
4888 emit_move_insn (tmp, operands[1]);
4889 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4890 const1_rtx));
4891 }
4892 case 2:
4893 {
4894 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4895 rtx tmp = gen_reg_rtx (V4SFmode);
4896
4897 emit_move_insn (tmp, operands[1]);
4898 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4899 }
4900 case 3:
4901 {
4902 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4903 rtx tmp = gen_reg_rtx (V4SFmode);
4904
4905 emit_move_insn (tmp, operands[1]);
4906 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4907 GEN_INT (3)));
4908 }
4909 default:
4910 abort ();
4911 }
4912 DONE;
4913 })
4914
4915 (define_expand "vec_initv4sf"
4916 [(match_operand:V4SF 0 "register_operand" "")
4917 (match_operand 1 "" "")]
4918 "TARGET_SSE"
4919 {
4920 ix86_expand_vector_init (operands[0], operands[1]);
4921 DONE;
4922 })
4923 \f
4924 ;; Add instructions
4925
4926 ;; %%% splits for addsidi3
4927 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4928 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4929 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4930
4931 (define_expand "adddi3"
4932 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4934 (match_operand:DI 2 "x86_64_general_operand" "")))
4935 (clobber (reg:CC 17))]
4936 ""
4937 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4938
4939 (define_insn "*adddi3_1"
4940 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4941 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4942 (match_operand:DI 2 "general_operand" "roiF,riF")))
4943 (clobber (reg:CC 17))]
4944 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4945 "#")
4946
4947 (define_split
4948 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4949 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4950 (match_operand:DI 2 "general_operand" "")))
4951 (clobber (reg:CC 17))]
4952 "!TARGET_64BIT && reload_completed"
4953 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
4954 UNSPEC_ADD_CARRY))
4955 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4956 (parallel [(set (match_dup 3)
4957 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
4958 (match_dup 4))
4959 (match_dup 5)))
4960 (clobber (reg:CC 17))])]
4961 "split_di (operands+0, 1, operands+0, operands+3);
4962 split_di (operands+1, 1, operands+1, operands+4);
4963 split_di (operands+2, 1, operands+2, operands+5);")
4964
4965 (define_insn "adddi3_carry_rex64"
4966 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4967 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4968 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4969 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4970 (clobber (reg:CC 17))]
4971 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4972 "adc{q}\t{%2, %0|%0, %2}"
4973 [(set_attr "type" "alu")
4974 (set_attr "pent_pair" "pu")
4975 (set_attr "mode" "DI")
4976 (set_attr "ppro_uops" "few")])
4977
4978 (define_insn "*adddi3_cc_rex64"
4979 [(set (reg:CC 17)
4980 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4981 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4982 UNSPEC_ADD_CARRY))
4983 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4984 (plus:DI (match_dup 1) (match_dup 2)))]
4985 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4986 "add{q}\t{%2, %0|%0, %2}"
4987 [(set_attr "type" "alu")
4988 (set_attr "mode" "DI")])
4989
4990 (define_insn "addqi3_carry"
4991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4992 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4993 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4994 (match_operand:QI 2 "general_operand" "qi,qm")))
4995 (clobber (reg:CC 17))]
4996 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4997 "adc{b}\t{%2, %0|%0, %2}"
4998 [(set_attr "type" "alu")
4999 (set_attr "pent_pair" "pu")
5000 (set_attr "mode" "QI")
5001 (set_attr "ppro_uops" "few")])
5002
5003 (define_insn "addhi3_carry"
5004 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5005 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5006 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5007 (match_operand:HI 2 "general_operand" "ri,rm")))
5008 (clobber (reg:CC 17))]
5009 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5010 "adc{w}\t{%2, %0|%0, %2}"
5011 [(set_attr "type" "alu")
5012 (set_attr "pent_pair" "pu")
5013 (set_attr "mode" "HI")
5014 (set_attr "ppro_uops" "few")])
5015
5016 (define_insn "addsi3_carry"
5017 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5018 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5019 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5020 (match_operand:SI 2 "general_operand" "ri,rm")))
5021 (clobber (reg:CC 17))]
5022 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5023 "adc{l}\t{%2, %0|%0, %2}"
5024 [(set_attr "type" "alu")
5025 (set_attr "pent_pair" "pu")
5026 (set_attr "mode" "SI")
5027 (set_attr "ppro_uops" "few")])
5028
5029 (define_insn "*addsi3_carry_zext"
5030 [(set (match_operand:DI 0 "register_operand" "=r")
5031 (zero_extend:DI
5032 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5033 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5034 (match_operand:SI 2 "general_operand" "rim"))))
5035 (clobber (reg:CC 17))]
5036 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5037 "adc{l}\t{%2, %k0|%k0, %2}"
5038 [(set_attr "type" "alu")
5039 (set_attr "pent_pair" "pu")
5040 (set_attr "mode" "SI")
5041 (set_attr "ppro_uops" "few")])
5042
5043 (define_insn "*addsi3_cc"
5044 [(set (reg:CC 17)
5045 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5046 (match_operand:SI 2 "general_operand" "ri,rm")]
5047 UNSPEC_ADD_CARRY))
5048 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5049 (plus:SI (match_dup 1) (match_dup 2)))]
5050 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5051 "add{l}\t{%2, %0|%0, %2}"
5052 [(set_attr "type" "alu")
5053 (set_attr "mode" "SI")])
5054
5055 (define_insn "addqi3_cc"
5056 [(set (reg:CC 17)
5057 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5058 (match_operand:QI 2 "general_operand" "qi,qm")]
5059 UNSPEC_ADD_CARRY))
5060 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5061 (plus:QI (match_dup 1) (match_dup 2)))]
5062 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5063 "add{b}\t{%2, %0|%0, %2}"
5064 [(set_attr "type" "alu")
5065 (set_attr "mode" "QI")])
5066
5067 (define_expand "addsi3"
5068 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5069 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5070 (match_operand:SI 2 "general_operand" "")))
5071 (clobber (reg:CC 17))])]
5072 ""
5073 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5074
5075 (define_insn "*lea_1"
5076 [(set (match_operand:SI 0 "register_operand" "=r")
5077 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5078 "!TARGET_64BIT"
5079 "lea{l}\t{%a1, %0|%0, %a1}"
5080 [(set_attr "type" "lea")
5081 (set_attr "mode" "SI")])
5082
5083 (define_insn "*lea_1_rex64"
5084 [(set (match_operand:SI 0 "register_operand" "=r")
5085 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5086 "TARGET_64BIT"
5087 "lea{l}\t{%a1, %0|%0, %a1}"
5088 [(set_attr "type" "lea")
5089 (set_attr "mode" "SI")])
5090
5091 (define_insn "*lea_1_zext"
5092 [(set (match_operand:DI 0 "register_operand" "=r")
5093 (zero_extend:DI
5094 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5095 "TARGET_64BIT"
5096 "lea{l}\t{%a1, %k0|%k0, %a1}"
5097 [(set_attr "type" "lea")
5098 (set_attr "mode" "SI")])
5099
5100 (define_insn "*lea_2_rex64"
5101 [(set (match_operand:DI 0 "register_operand" "=r")
5102 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5103 "TARGET_64BIT"
5104 "lea{q}\t{%a1, %0|%0, %a1}"
5105 [(set_attr "type" "lea")
5106 (set_attr "mode" "DI")])
5107
5108 ;; The lea patterns for non-Pmodes needs to be matched by several
5109 ;; insns converted to real lea by splitters.
5110
5111 (define_insn_and_split "*lea_general_1"
5112 [(set (match_operand 0 "register_operand" "=r")
5113 (plus (plus (match_operand 1 "index_register_operand" "r")
5114 (match_operand 2 "register_operand" "r"))
5115 (match_operand 3 "immediate_operand" "i")))]
5116 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5117 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5118 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5119 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5120 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5121 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5122 || GET_MODE (operands[3]) == VOIDmode)"
5123 "#"
5124 "&& reload_completed"
5125 [(const_int 0)]
5126 {
5127 rtx pat;
5128 operands[0] = gen_lowpart (SImode, operands[0]);
5129 operands[1] = gen_lowpart (Pmode, operands[1]);
5130 operands[2] = gen_lowpart (Pmode, operands[2]);
5131 operands[3] = gen_lowpart (Pmode, operands[3]);
5132 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5133 operands[3]);
5134 if (Pmode != SImode)
5135 pat = gen_rtx_SUBREG (SImode, pat, 0);
5136 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5137 DONE;
5138 }
5139 [(set_attr "type" "lea")
5140 (set_attr "mode" "SI")])
5141
5142 (define_insn_and_split "*lea_general_1_zext"
5143 [(set (match_operand:DI 0 "register_operand" "=r")
5144 (zero_extend:DI
5145 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5146 (match_operand:SI 2 "register_operand" "r"))
5147 (match_operand:SI 3 "immediate_operand" "i"))))]
5148 "TARGET_64BIT"
5149 "#"
5150 "&& reload_completed"
5151 [(set (match_dup 0)
5152 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5153 (match_dup 2))
5154 (match_dup 3)) 0)))]
5155 {
5156 operands[1] = gen_lowpart (Pmode, operands[1]);
5157 operands[2] = gen_lowpart (Pmode, operands[2]);
5158 operands[3] = gen_lowpart (Pmode, operands[3]);
5159 }
5160 [(set_attr "type" "lea")
5161 (set_attr "mode" "SI")])
5162
5163 (define_insn_and_split "*lea_general_2"
5164 [(set (match_operand 0 "register_operand" "=r")
5165 (plus (mult (match_operand 1 "index_register_operand" "r")
5166 (match_operand 2 "const248_operand" "i"))
5167 (match_operand 3 "nonmemory_operand" "ri")))]
5168 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5169 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5170 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5171 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5172 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5173 || GET_MODE (operands[3]) == VOIDmode)"
5174 "#"
5175 "&& reload_completed"
5176 [(const_int 0)]
5177 {
5178 rtx pat;
5179 operands[0] = gen_lowpart (SImode, operands[0]);
5180 operands[1] = gen_lowpart (Pmode, operands[1]);
5181 operands[3] = gen_lowpart (Pmode, operands[3]);
5182 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5183 operands[3]);
5184 if (Pmode != SImode)
5185 pat = gen_rtx_SUBREG (SImode, pat, 0);
5186 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5187 DONE;
5188 }
5189 [(set_attr "type" "lea")
5190 (set_attr "mode" "SI")])
5191
5192 (define_insn_and_split "*lea_general_2_zext"
5193 [(set (match_operand:DI 0 "register_operand" "=r")
5194 (zero_extend:DI
5195 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5196 (match_operand:SI 2 "const248_operand" "n"))
5197 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5198 "TARGET_64BIT"
5199 "#"
5200 "&& reload_completed"
5201 [(set (match_dup 0)
5202 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5203 (match_dup 2))
5204 (match_dup 3)) 0)))]
5205 {
5206 operands[1] = gen_lowpart (Pmode, operands[1]);
5207 operands[3] = gen_lowpart (Pmode, operands[3]);
5208 }
5209 [(set_attr "type" "lea")
5210 (set_attr "mode" "SI")])
5211
5212 (define_insn_and_split "*lea_general_3"
5213 [(set (match_operand 0 "register_operand" "=r")
5214 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5215 (match_operand 2 "const248_operand" "i"))
5216 (match_operand 3 "register_operand" "r"))
5217 (match_operand 4 "immediate_operand" "i")))]
5218 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5219 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5220 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5221 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5222 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5223 "#"
5224 "&& reload_completed"
5225 [(const_int 0)]
5226 {
5227 rtx pat;
5228 operands[0] = gen_lowpart (SImode, operands[0]);
5229 operands[1] = gen_lowpart (Pmode, operands[1]);
5230 operands[3] = gen_lowpart (Pmode, operands[3]);
5231 operands[4] = gen_lowpart (Pmode, operands[4]);
5232 pat = gen_rtx_PLUS (Pmode,
5233 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5234 operands[2]),
5235 operands[3]),
5236 operands[4]);
5237 if (Pmode != SImode)
5238 pat = gen_rtx_SUBREG (SImode, pat, 0);
5239 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5240 DONE;
5241 }
5242 [(set_attr "type" "lea")
5243 (set_attr "mode" "SI")])
5244
5245 (define_insn_and_split "*lea_general_3_zext"
5246 [(set (match_operand:DI 0 "register_operand" "=r")
5247 (zero_extend:DI
5248 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5249 (match_operand:SI 2 "const248_operand" "n"))
5250 (match_operand:SI 3 "register_operand" "r"))
5251 (match_operand:SI 4 "immediate_operand" "i"))))]
5252 "TARGET_64BIT"
5253 "#"
5254 "&& reload_completed"
5255 [(set (match_dup 0)
5256 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5257 (match_dup 2))
5258 (match_dup 3))
5259 (match_dup 4)) 0)))]
5260 {
5261 operands[1] = gen_lowpart (Pmode, operands[1]);
5262 operands[3] = gen_lowpart (Pmode, operands[3]);
5263 operands[4] = gen_lowpart (Pmode, operands[4]);
5264 }
5265 [(set_attr "type" "lea")
5266 (set_attr "mode" "SI")])
5267
5268 (define_insn "*adddi_1_rex64"
5269 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5270 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5271 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5272 (clobber (reg:CC 17))]
5273 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5274 {
5275 switch (get_attr_type (insn))
5276 {
5277 case TYPE_LEA:
5278 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5279 return "lea{q}\t{%a2, %0|%0, %a2}";
5280
5281 case TYPE_INCDEC:
5282 if (! rtx_equal_p (operands[0], operands[1]))
5283 abort ();
5284 if (operands[2] == const1_rtx)
5285 return "inc{q}\t%0";
5286 else if (operands[2] == constm1_rtx)
5287 return "dec{q}\t%0";
5288 else
5289 abort ();
5290
5291 default:
5292 if (! rtx_equal_p (operands[0], operands[1]))
5293 abort ();
5294
5295 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5296 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5297 if (GET_CODE (operands[2]) == CONST_INT
5298 /* Avoid overflows. */
5299 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5300 && (INTVAL (operands[2]) == 128
5301 || (INTVAL (operands[2]) < 0
5302 && INTVAL (operands[2]) != -128)))
5303 {
5304 operands[2] = GEN_INT (-INTVAL (operands[2]));
5305 return "sub{q}\t{%2, %0|%0, %2}";
5306 }
5307 return "add{q}\t{%2, %0|%0, %2}";
5308 }
5309 }
5310 [(set (attr "type")
5311 (cond [(eq_attr "alternative" "2")
5312 (const_string "lea")
5313 ; Current assemblers are broken and do not allow @GOTOFF in
5314 ; ought but a memory context.
5315 (match_operand:DI 2 "pic_symbolic_operand" "")
5316 (const_string "lea")
5317 (match_operand:DI 2 "incdec_operand" "")
5318 (const_string "incdec")
5319 ]
5320 (const_string "alu")))
5321 (set_attr "mode" "DI")])
5322
5323 ;; Convert lea to the lea pattern to avoid flags dependency.
5324 (define_split
5325 [(set (match_operand:DI 0 "register_operand" "")
5326 (plus:DI (match_operand:DI 1 "register_operand" "")
5327 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5328 (clobber (reg:CC 17))]
5329 "TARGET_64BIT && reload_completed
5330 && true_regnum (operands[0]) != true_regnum (operands[1])"
5331 [(set (match_dup 0)
5332 (plus:DI (match_dup 1)
5333 (match_dup 2)))]
5334 "")
5335
5336 (define_insn "*adddi_2_rex64"
5337 [(set (reg 17)
5338 (compare
5339 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5340 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5341 (const_int 0)))
5342 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5343 (plus:DI (match_dup 1) (match_dup 2)))]
5344 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5345 && ix86_binary_operator_ok (PLUS, DImode, operands)
5346 /* Current assemblers are broken and do not allow @GOTOFF in
5347 ought but a memory context. */
5348 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5349 {
5350 switch (get_attr_type (insn))
5351 {
5352 case TYPE_INCDEC:
5353 if (! rtx_equal_p (operands[0], operands[1]))
5354 abort ();
5355 if (operands[2] == const1_rtx)
5356 return "inc{q}\t%0";
5357 else if (operands[2] == constm1_rtx)
5358 return "dec{q}\t%0";
5359 else
5360 abort ();
5361
5362 default:
5363 if (! rtx_equal_p (operands[0], operands[1]))
5364 abort ();
5365 /* ???? We ought to handle there the 32bit case too
5366 - do we need new constraint? */
5367 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5368 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5369 if (GET_CODE (operands[2]) == CONST_INT
5370 /* Avoid overflows. */
5371 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5372 && (INTVAL (operands[2]) == 128
5373 || (INTVAL (operands[2]) < 0
5374 && INTVAL (operands[2]) != -128)))
5375 {
5376 operands[2] = GEN_INT (-INTVAL (operands[2]));
5377 return "sub{q}\t{%2, %0|%0, %2}";
5378 }
5379 return "add{q}\t{%2, %0|%0, %2}";
5380 }
5381 }
5382 [(set (attr "type")
5383 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5384 (const_string "incdec")
5385 (const_string "alu")))
5386 (set_attr "mode" "DI")])
5387
5388 (define_insn "*adddi_3_rex64"
5389 [(set (reg 17)
5390 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5391 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5392 (clobber (match_scratch:DI 0 "=r"))]
5393 "TARGET_64BIT
5394 && ix86_match_ccmode (insn, CCZmode)
5395 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5396 /* Current assemblers are broken and do not allow @GOTOFF in
5397 ought but a memory context. */
5398 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5399 {
5400 switch (get_attr_type (insn))
5401 {
5402 case TYPE_INCDEC:
5403 if (! rtx_equal_p (operands[0], operands[1]))
5404 abort ();
5405 if (operands[2] == const1_rtx)
5406 return "inc{q}\t%0";
5407 else if (operands[2] == constm1_rtx)
5408 return "dec{q}\t%0";
5409 else
5410 abort ();
5411
5412 default:
5413 if (! rtx_equal_p (operands[0], operands[1]))
5414 abort ();
5415 /* ???? We ought to handle there the 32bit case too
5416 - do we need new constraint? */
5417 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5418 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5419 if (GET_CODE (operands[2]) == CONST_INT
5420 /* Avoid overflows. */
5421 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5422 && (INTVAL (operands[2]) == 128
5423 || (INTVAL (operands[2]) < 0
5424 && INTVAL (operands[2]) != -128)))
5425 {
5426 operands[2] = GEN_INT (-INTVAL (operands[2]));
5427 return "sub{q}\t{%2, %0|%0, %2}";
5428 }
5429 return "add{q}\t{%2, %0|%0, %2}";
5430 }
5431 }
5432 [(set (attr "type")
5433 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5434 (const_string "incdec")
5435 (const_string "alu")))
5436 (set_attr "mode" "DI")])
5437
5438 ; For comparisons against 1, -1 and 128, we may generate better code
5439 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5440 ; is matched then. We can't accept general immediate, because for
5441 ; case of overflows, the result is messed up.
5442 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5443 ; when negated.
5444 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5445 ; only for comparisons not depending on it.
5446 (define_insn "*adddi_4_rex64"
5447 [(set (reg 17)
5448 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5449 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5450 (clobber (match_scratch:DI 0 "=rm"))]
5451 "TARGET_64BIT
5452 && ix86_match_ccmode (insn, CCGCmode)"
5453 {
5454 switch (get_attr_type (insn))
5455 {
5456 case TYPE_INCDEC:
5457 if (operands[2] == constm1_rtx)
5458 return "inc{q}\t%0";
5459 else if (operands[2] == const1_rtx)
5460 return "dec{q}\t%0";
5461 else
5462 abort();
5463
5464 default:
5465 if (! rtx_equal_p (operands[0], operands[1]))
5466 abort ();
5467 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5468 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5469 if ((INTVAL (operands[2]) == -128
5470 || (INTVAL (operands[2]) > 0
5471 && INTVAL (operands[2]) != 128))
5472 /* Avoid overflows. */
5473 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5474 return "sub{q}\t{%2, %0|%0, %2}";
5475 operands[2] = GEN_INT (-INTVAL (operands[2]));
5476 return "add{q}\t{%2, %0|%0, %2}";
5477 }
5478 }
5479 [(set (attr "type")
5480 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5481 (const_string "incdec")
5482 (const_string "alu")))
5483 (set_attr "mode" "DI")])
5484
5485 (define_insn "*adddi_5_rex64"
5486 [(set (reg 17)
5487 (compare
5488 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5489 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5490 (const_int 0)))
5491 (clobber (match_scratch:DI 0 "=r"))]
5492 "TARGET_64BIT
5493 && ix86_match_ccmode (insn, CCGOCmode)
5494 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5495 /* Current assemblers are broken and do not allow @GOTOFF in
5496 ought but a memory context. */
5497 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5498 {
5499 switch (get_attr_type (insn))
5500 {
5501 case TYPE_INCDEC:
5502 if (! rtx_equal_p (operands[0], operands[1]))
5503 abort ();
5504 if (operands[2] == const1_rtx)
5505 return "inc{q}\t%0";
5506 else if (operands[2] == constm1_rtx)
5507 return "dec{q}\t%0";
5508 else
5509 abort();
5510
5511 default:
5512 if (! rtx_equal_p (operands[0], operands[1]))
5513 abort ();
5514 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5515 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5516 if (GET_CODE (operands[2]) == CONST_INT
5517 /* Avoid overflows. */
5518 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5519 && (INTVAL (operands[2]) == 128
5520 || (INTVAL (operands[2]) < 0
5521 && INTVAL (operands[2]) != -128)))
5522 {
5523 operands[2] = GEN_INT (-INTVAL (operands[2]));
5524 return "sub{q}\t{%2, %0|%0, %2}";
5525 }
5526 return "add{q}\t{%2, %0|%0, %2}";
5527 }
5528 }
5529 [(set (attr "type")
5530 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5531 (const_string "incdec")
5532 (const_string "alu")))
5533 (set_attr "mode" "DI")])
5534
5535
5536 (define_insn "*addsi_1"
5537 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5538 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5539 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5540 (clobber (reg:CC 17))]
5541 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5542 {
5543 switch (get_attr_type (insn))
5544 {
5545 case TYPE_LEA:
5546 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5547 return "lea{l}\t{%a2, %0|%0, %a2}";
5548
5549 case TYPE_INCDEC:
5550 if (! rtx_equal_p (operands[0], operands[1]))
5551 abort ();
5552 if (operands[2] == const1_rtx)
5553 return "inc{l}\t%0";
5554 else if (operands[2] == constm1_rtx)
5555 return "dec{l}\t%0";
5556 else
5557 abort();
5558
5559 default:
5560 if (! rtx_equal_p (operands[0], operands[1]))
5561 abort ();
5562
5563 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5564 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5565 if (GET_CODE (operands[2]) == CONST_INT
5566 && (INTVAL (operands[2]) == 128
5567 || (INTVAL (operands[2]) < 0
5568 && INTVAL (operands[2]) != -128)))
5569 {
5570 operands[2] = GEN_INT (-INTVAL (operands[2]));
5571 return "sub{l}\t{%2, %0|%0, %2}";
5572 }
5573 return "add{l}\t{%2, %0|%0, %2}";
5574 }
5575 }
5576 [(set (attr "type")
5577 (cond [(eq_attr "alternative" "2")
5578 (const_string "lea")
5579 ; Current assemblers are broken and do not allow @GOTOFF in
5580 ; ought but a memory context.
5581 (match_operand:SI 2 "pic_symbolic_operand" "")
5582 (const_string "lea")
5583 (match_operand:SI 2 "incdec_operand" "")
5584 (const_string "incdec")
5585 ]
5586 (const_string "alu")))
5587 (set_attr "mode" "SI")])
5588
5589 ;; Convert lea to the lea pattern to avoid flags dependency.
5590 (define_split
5591 [(set (match_operand 0 "register_operand" "")
5592 (plus (match_operand 1 "register_operand" "")
5593 (match_operand 2 "nonmemory_operand" "")))
5594 (clobber (reg:CC 17))]
5595 "reload_completed
5596 && true_regnum (operands[0]) != true_regnum (operands[1])"
5597 [(const_int 0)]
5598 {
5599 rtx pat;
5600 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5601 may confuse gen_lowpart. */
5602 if (GET_MODE (operands[0]) != Pmode)
5603 {
5604 operands[1] = gen_lowpart (Pmode, operands[1]);
5605 operands[2] = gen_lowpart (Pmode, operands[2]);
5606 }
5607 operands[0] = gen_lowpart (SImode, operands[0]);
5608 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5609 if (Pmode != SImode)
5610 pat = gen_rtx_SUBREG (SImode, pat, 0);
5611 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5612 DONE;
5613 })
5614
5615 ;; It may seem that nonimmediate operand is proper one for operand 1.
5616 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5617 ;; we take care in ix86_binary_operator_ok to not allow two memory
5618 ;; operands so proper swapping will be done in reload. This allow
5619 ;; patterns constructed from addsi_1 to match.
5620 (define_insn "addsi_1_zext"
5621 [(set (match_operand:DI 0 "register_operand" "=r,r")
5622 (zero_extend:DI
5623 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5624 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5625 (clobber (reg:CC 17))]
5626 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5627 {
5628 switch (get_attr_type (insn))
5629 {
5630 case TYPE_LEA:
5631 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5632 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5633
5634 case TYPE_INCDEC:
5635 if (operands[2] == const1_rtx)
5636 return "inc{l}\t%k0";
5637 else if (operands[2] == constm1_rtx)
5638 return "dec{l}\t%k0";
5639 else
5640 abort();
5641
5642 default:
5643 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5644 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5645 if (GET_CODE (operands[2]) == CONST_INT
5646 && (INTVAL (operands[2]) == 128
5647 || (INTVAL (operands[2]) < 0
5648 && INTVAL (operands[2]) != -128)))
5649 {
5650 operands[2] = GEN_INT (-INTVAL (operands[2]));
5651 return "sub{l}\t{%2, %k0|%k0, %2}";
5652 }
5653 return "add{l}\t{%2, %k0|%k0, %2}";
5654 }
5655 }
5656 [(set (attr "type")
5657 (cond [(eq_attr "alternative" "1")
5658 (const_string "lea")
5659 ; Current assemblers are broken and do not allow @GOTOFF in
5660 ; ought but a memory context.
5661 (match_operand:SI 2 "pic_symbolic_operand" "")
5662 (const_string "lea")
5663 (match_operand:SI 2 "incdec_operand" "")
5664 (const_string "incdec")
5665 ]
5666 (const_string "alu")))
5667 (set_attr "mode" "SI")])
5668
5669 ;; Convert lea to the lea pattern to avoid flags dependency.
5670 (define_split
5671 [(set (match_operand:DI 0 "register_operand" "")
5672 (zero_extend:DI
5673 (plus:SI (match_operand:SI 1 "register_operand" "")
5674 (match_operand:SI 2 "nonmemory_operand" ""))))
5675 (clobber (reg:CC 17))]
5676 "TARGET_64BIT && reload_completed
5677 && true_regnum (operands[0]) != true_regnum (operands[1])"
5678 [(set (match_dup 0)
5679 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5680 {
5681 operands[1] = gen_lowpart (Pmode, operands[1]);
5682 operands[2] = gen_lowpart (Pmode, operands[2]);
5683 })
5684
5685 (define_insn "*addsi_2"
5686 [(set (reg 17)
5687 (compare
5688 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5689 (match_operand:SI 2 "general_operand" "rmni,rni"))
5690 (const_int 0)))
5691 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5692 (plus:SI (match_dup 1) (match_dup 2)))]
5693 "ix86_match_ccmode (insn, CCGOCmode)
5694 && ix86_binary_operator_ok (PLUS, SImode, operands)
5695 /* Current assemblers are broken and do not allow @GOTOFF in
5696 ought but a memory context. */
5697 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5698 {
5699 switch (get_attr_type (insn))
5700 {
5701 case TYPE_INCDEC:
5702 if (! rtx_equal_p (operands[0], operands[1]))
5703 abort ();
5704 if (operands[2] == const1_rtx)
5705 return "inc{l}\t%0";
5706 else if (operands[2] == constm1_rtx)
5707 return "dec{l}\t%0";
5708 else
5709 abort();
5710
5711 default:
5712 if (! rtx_equal_p (operands[0], operands[1]))
5713 abort ();
5714 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5715 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5716 if (GET_CODE (operands[2]) == CONST_INT
5717 && (INTVAL (operands[2]) == 128
5718 || (INTVAL (operands[2]) < 0
5719 && INTVAL (operands[2]) != -128)))
5720 {
5721 operands[2] = GEN_INT (-INTVAL (operands[2]));
5722 return "sub{l}\t{%2, %0|%0, %2}";
5723 }
5724 return "add{l}\t{%2, %0|%0, %2}";
5725 }
5726 }
5727 [(set (attr "type")
5728 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5729 (const_string "incdec")
5730 (const_string "alu")))
5731 (set_attr "mode" "SI")])
5732
5733 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5734 (define_insn "*addsi_2_zext"
5735 [(set (reg 17)
5736 (compare
5737 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5738 (match_operand:SI 2 "general_operand" "rmni"))
5739 (const_int 0)))
5740 (set (match_operand:DI 0 "register_operand" "=r")
5741 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5743 && ix86_binary_operator_ok (PLUS, SImode, operands)
5744 /* Current assemblers are broken and do not allow @GOTOFF in
5745 ought but a memory context. */
5746 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5747 {
5748 switch (get_attr_type (insn))
5749 {
5750 case TYPE_INCDEC:
5751 if (operands[2] == const1_rtx)
5752 return "inc{l}\t%k0";
5753 else if (operands[2] == constm1_rtx)
5754 return "dec{l}\t%k0";
5755 else
5756 abort();
5757
5758 default:
5759 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5760 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5761 if (GET_CODE (operands[2]) == CONST_INT
5762 && (INTVAL (operands[2]) == 128
5763 || (INTVAL (operands[2]) < 0
5764 && INTVAL (operands[2]) != -128)))
5765 {
5766 operands[2] = GEN_INT (-INTVAL (operands[2]));
5767 return "sub{l}\t{%2, %k0|%k0, %2}";
5768 }
5769 return "add{l}\t{%2, %k0|%k0, %2}";
5770 }
5771 }
5772 [(set (attr "type")
5773 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5774 (const_string "incdec")
5775 (const_string "alu")))
5776 (set_attr "mode" "SI")])
5777
5778 (define_insn "*addsi_3"
5779 [(set (reg 17)
5780 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5781 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5782 (clobber (match_scratch:SI 0 "=r"))]
5783 "ix86_match_ccmode (insn, CCZmode)
5784 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5785 /* Current assemblers are broken and do not allow @GOTOFF in
5786 ought but a memory context. */
5787 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5788 {
5789 switch (get_attr_type (insn))
5790 {
5791 case TYPE_INCDEC:
5792 if (! rtx_equal_p (operands[0], operands[1]))
5793 abort ();
5794 if (operands[2] == const1_rtx)
5795 return "inc{l}\t%0";
5796 else if (operands[2] == constm1_rtx)
5797 return "dec{l}\t%0";
5798 else
5799 abort();
5800
5801 default:
5802 if (! rtx_equal_p (operands[0], operands[1]))
5803 abort ();
5804 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5805 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5806 if (GET_CODE (operands[2]) == CONST_INT
5807 && (INTVAL (operands[2]) == 128
5808 || (INTVAL (operands[2]) < 0
5809 && INTVAL (operands[2]) != -128)))
5810 {
5811 operands[2] = GEN_INT (-INTVAL (operands[2]));
5812 return "sub{l}\t{%2, %0|%0, %2}";
5813 }
5814 return "add{l}\t{%2, %0|%0, %2}";
5815 }
5816 }
5817 [(set (attr "type")
5818 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5819 (const_string "incdec")
5820 (const_string "alu")))
5821 (set_attr "mode" "SI")])
5822
5823 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5824 (define_insn "*addsi_3_zext"
5825 [(set (reg 17)
5826 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5827 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5828 (set (match_operand:DI 0 "register_operand" "=r")
5829 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5830 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5831 && ix86_binary_operator_ok (PLUS, SImode, operands)
5832 /* Current assemblers are broken and do not allow @GOTOFF in
5833 ought but a memory context. */
5834 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5835 {
5836 switch (get_attr_type (insn))
5837 {
5838 case TYPE_INCDEC:
5839 if (operands[2] == const1_rtx)
5840 return "inc{l}\t%k0";
5841 else if (operands[2] == constm1_rtx)
5842 return "dec{l}\t%k0";
5843 else
5844 abort();
5845
5846 default:
5847 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5848 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5849 if (GET_CODE (operands[2]) == CONST_INT
5850 && (INTVAL (operands[2]) == 128
5851 || (INTVAL (operands[2]) < 0
5852 && INTVAL (operands[2]) != -128)))
5853 {
5854 operands[2] = GEN_INT (-INTVAL (operands[2]));
5855 return "sub{l}\t{%2, %k0|%k0, %2}";
5856 }
5857 return "add{l}\t{%2, %k0|%k0, %2}";
5858 }
5859 }
5860 [(set (attr "type")
5861 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5862 (const_string "incdec")
5863 (const_string "alu")))
5864 (set_attr "mode" "SI")])
5865
5866 ; For comparisons against 1, -1 and 128, we may generate better code
5867 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5868 ; is matched then. We can't accept general immediate, because for
5869 ; case of overflows, the result is messed up.
5870 ; This pattern also don't hold of 0x80000000, since the value overflows
5871 ; when negated.
5872 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5873 ; only for comparisons not depending on it.
5874 (define_insn "*addsi_4"
5875 [(set (reg 17)
5876 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5877 (match_operand:SI 2 "const_int_operand" "n")))
5878 (clobber (match_scratch:SI 0 "=rm"))]
5879 "ix86_match_ccmode (insn, CCGCmode)
5880 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5881 {
5882 switch (get_attr_type (insn))
5883 {
5884 case TYPE_INCDEC:
5885 if (operands[2] == constm1_rtx)
5886 return "inc{l}\t%0";
5887 else if (operands[2] == const1_rtx)
5888 return "dec{l}\t%0";
5889 else
5890 abort();
5891
5892 default:
5893 if (! rtx_equal_p (operands[0], operands[1]))
5894 abort ();
5895 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5896 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5897 if ((INTVAL (operands[2]) == -128
5898 || (INTVAL (operands[2]) > 0
5899 && INTVAL (operands[2]) != 128)))
5900 return "sub{l}\t{%2, %0|%0, %2}";
5901 operands[2] = GEN_INT (-INTVAL (operands[2]));
5902 return "add{l}\t{%2, %0|%0, %2}";
5903 }
5904 }
5905 [(set (attr "type")
5906 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5907 (const_string "incdec")
5908 (const_string "alu")))
5909 (set_attr "mode" "SI")])
5910
5911 (define_insn "*addsi_5"
5912 [(set (reg 17)
5913 (compare
5914 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5915 (match_operand:SI 2 "general_operand" "rmni"))
5916 (const_int 0)))
5917 (clobber (match_scratch:SI 0 "=r"))]
5918 "ix86_match_ccmode (insn, CCGOCmode)
5919 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5920 /* Current assemblers are broken and do not allow @GOTOFF in
5921 ought but a memory context. */
5922 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5923 {
5924 switch (get_attr_type (insn))
5925 {
5926 case TYPE_INCDEC:
5927 if (! rtx_equal_p (operands[0], operands[1]))
5928 abort ();
5929 if (operands[2] == const1_rtx)
5930 return "inc{l}\t%0";
5931 else if (operands[2] == constm1_rtx)
5932 return "dec{l}\t%0";
5933 else
5934 abort();
5935
5936 default:
5937 if (! rtx_equal_p (operands[0], operands[1]))
5938 abort ();
5939 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5940 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5941 if (GET_CODE (operands[2]) == CONST_INT
5942 && (INTVAL (operands[2]) == 128
5943 || (INTVAL (operands[2]) < 0
5944 && INTVAL (operands[2]) != -128)))
5945 {
5946 operands[2] = GEN_INT (-INTVAL (operands[2]));
5947 return "sub{l}\t{%2, %0|%0, %2}";
5948 }
5949 return "add{l}\t{%2, %0|%0, %2}";
5950 }
5951 }
5952 [(set (attr "type")
5953 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5954 (const_string "incdec")
5955 (const_string "alu")))
5956 (set_attr "mode" "SI")])
5957
5958 (define_expand "addhi3"
5959 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5960 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5961 (match_operand:HI 2 "general_operand" "")))
5962 (clobber (reg:CC 17))])]
5963 "TARGET_HIMODE_MATH"
5964 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5965
5966 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5967 ;; type optimizations enabled by define-splits. This is not important
5968 ;; for PII, and in fact harmful because of partial register stalls.
5969
5970 (define_insn "*addhi_1_lea"
5971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5972 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5973 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
5974 (clobber (reg:CC 17))]
5975 "!TARGET_PARTIAL_REG_STALL
5976 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5977 {
5978 switch (get_attr_type (insn))
5979 {
5980 case TYPE_LEA:
5981 return "#";
5982 case TYPE_INCDEC:
5983 if (operands[2] == const1_rtx)
5984 return "inc{w}\t%0";
5985 else if (operands[2] == constm1_rtx)
5986 return "dec{w}\t%0";
5987 abort();
5988
5989 default:
5990 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5991 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5992 if (GET_CODE (operands[2]) == CONST_INT
5993 && (INTVAL (operands[2]) == 128
5994 || (INTVAL (operands[2]) < 0
5995 && INTVAL (operands[2]) != -128)))
5996 {
5997 operands[2] = GEN_INT (-INTVAL (operands[2]));
5998 return "sub{w}\t{%2, %0|%0, %2}";
5999 }
6000 return "add{w}\t{%2, %0|%0, %2}";
6001 }
6002 }
6003 [(set (attr "type")
6004 (if_then_else (eq_attr "alternative" "2")
6005 (const_string "lea")
6006 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007 (const_string "incdec")
6008 (const_string "alu"))))
6009 (set_attr "mode" "HI,HI,SI")])
6010
6011 (define_insn "*addhi_1"
6012 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6013 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6014 (match_operand:HI 2 "general_operand" "ri,rm")))
6015 (clobber (reg:CC 17))]
6016 "TARGET_PARTIAL_REG_STALL
6017 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6018 {
6019 switch (get_attr_type (insn))
6020 {
6021 case TYPE_INCDEC:
6022 if (operands[2] == const1_rtx)
6023 return "inc{w}\t%0";
6024 else if (operands[2] == constm1_rtx)
6025 return "dec{w}\t%0";
6026 abort();
6027
6028 default:
6029 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6030 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6031 if (GET_CODE (operands[2]) == CONST_INT
6032 && (INTVAL (operands[2]) == 128
6033 || (INTVAL (operands[2]) < 0
6034 && INTVAL (operands[2]) != -128)))
6035 {
6036 operands[2] = GEN_INT (-INTVAL (operands[2]));
6037 return "sub{w}\t{%2, %0|%0, %2}";
6038 }
6039 return "add{w}\t{%2, %0|%0, %2}";
6040 }
6041 }
6042 [(set (attr "type")
6043 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6044 (const_string "incdec")
6045 (const_string "alu")))
6046 (set_attr "mode" "HI")])
6047
6048 (define_insn "*addhi_2"
6049 [(set (reg 17)
6050 (compare
6051 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6052 (match_operand:HI 2 "general_operand" "rmni,rni"))
6053 (const_int 0)))
6054 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6055 (plus:HI (match_dup 1) (match_dup 2)))]
6056 "ix86_match_ccmode (insn, CCGOCmode)
6057 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6058 {
6059 switch (get_attr_type (insn))
6060 {
6061 case TYPE_INCDEC:
6062 if (operands[2] == const1_rtx)
6063 return "inc{w}\t%0";
6064 else if (operands[2] == constm1_rtx)
6065 return "dec{w}\t%0";
6066 abort();
6067
6068 default:
6069 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6070 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6071 if (GET_CODE (operands[2]) == CONST_INT
6072 && (INTVAL (operands[2]) == 128
6073 || (INTVAL (operands[2]) < 0
6074 && INTVAL (operands[2]) != -128)))
6075 {
6076 operands[2] = GEN_INT (-INTVAL (operands[2]));
6077 return "sub{w}\t{%2, %0|%0, %2}";
6078 }
6079 return "add{w}\t{%2, %0|%0, %2}";
6080 }
6081 }
6082 [(set (attr "type")
6083 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6084 (const_string "incdec")
6085 (const_string "alu")))
6086 (set_attr "mode" "HI")])
6087
6088 (define_insn "*addhi_3"
6089 [(set (reg 17)
6090 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6091 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6092 (clobber (match_scratch:HI 0 "=r"))]
6093 "ix86_match_ccmode (insn, CCZmode)
6094 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6095 {
6096 switch (get_attr_type (insn))
6097 {
6098 case TYPE_INCDEC:
6099 if (operands[2] == const1_rtx)
6100 return "inc{w}\t%0";
6101 else if (operands[2] == constm1_rtx)
6102 return "dec{w}\t%0";
6103 abort();
6104
6105 default:
6106 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6108 if (GET_CODE (operands[2]) == CONST_INT
6109 && (INTVAL (operands[2]) == 128
6110 || (INTVAL (operands[2]) < 0
6111 && INTVAL (operands[2]) != -128)))
6112 {
6113 operands[2] = GEN_INT (-INTVAL (operands[2]));
6114 return "sub{w}\t{%2, %0|%0, %2}";
6115 }
6116 return "add{w}\t{%2, %0|%0, %2}";
6117 }
6118 }
6119 [(set (attr "type")
6120 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set_attr "mode" "HI")])
6124
6125 ; See comments above addsi_3_imm for details.
6126 (define_insn "*addhi_4"
6127 [(set (reg 17)
6128 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6129 (match_operand:HI 2 "const_int_operand" "n")))
6130 (clobber (match_scratch:HI 0 "=rm"))]
6131 "ix86_match_ccmode (insn, CCGCmode)
6132 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6133 {
6134 switch (get_attr_type (insn))
6135 {
6136 case TYPE_INCDEC:
6137 if (operands[2] == constm1_rtx)
6138 return "inc{w}\t%0";
6139 else if (operands[2] == const1_rtx)
6140 return "dec{w}\t%0";
6141 else
6142 abort();
6143
6144 default:
6145 if (! rtx_equal_p (operands[0], operands[1]))
6146 abort ();
6147 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6148 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6149 if ((INTVAL (operands[2]) == -128
6150 || (INTVAL (operands[2]) > 0
6151 && INTVAL (operands[2]) != 128)))
6152 return "sub{w}\t{%2, %0|%0, %2}";
6153 operands[2] = GEN_INT (-INTVAL (operands[2]));
6154 return "add{w}\t{%2, %0|%0, %2}";
6155 }
6156 }
6157 [(set (attr "type")
6158 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6159 (const_string "incdec")
6160 (const_string "alu")))
6161 (set_attr "mode" "SI")])
6162
6163
6164 (define_insn "*addhi_5"
6165 [(set (reg 17)
6166 (compare
6167 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6168 (match_operand:HI 2 "general_operand" "rmni"))
6169 (const_int 0)))
6170 (clobber (match_scratch:HI 0 "=r"))]
6171 "ix86_match_ccmode (insn, CCGOCmode)
6172 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6173 {
6174 switch (get_attr_type (insn))
6175 {
6176 case TYPE_INCDEC:
6177 if (operands[2] == const1_rtx)
6178 return "inc{w}\t%0";
6179 else if (operands[2] == constm1_rtx)
6180 return "dec{w}\t%0";
6181 abort();
6182
6183 default:
6184 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6185 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6186 if (GET_CODE (operands[2]) == CONST_INT
6187 && (INTVAL (operands[2]) == 128
6188 || (INTVAL (operands[2]) < 0
6189 && INTVAL (operands[2]) != -128)))
6190 {
6191 operands[2] = GEN_INT (-INTVAL (operands[2]));
6192 return "sub{w}\t{%2, %0|%0, %2}";
6193 }
6194 return "add{w}\t{%2, %0|%0, %2}";
6195 }
6196 }
6197 [(set (attr "type")
6198 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6199 (const_string "incdec")
6200 (const_string "alu")))
6201 (set_attr "mode" "HI")])
6202
6203 (define_expand "addqi3"
6204 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6205 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6206 (match_operand:QI 2 "general_operand" "")))
6207 (clobber (reg:CC 17))])]
6208 "TARGET_QIMODE_MATH"
6209 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6210
6211 ;; %%% Potential partial reg stall on alternative 2. What to do?
6212 (define_insn "*addqi_1_lea"
6213 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6214 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6215 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6216 (clobber (reg:CC 17))]
6217 "!TARGET_PARTIAL_REG_STALL
6218 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6219 {
6220 int widen = (which_alternative == 2);
6221 switch (get_attr_type (insn))
6222 {
6223 case TYPE_LEA:
6224 return "#";
6225 case TYPE_INCDEC:
6226 if (operands[2] == const1_rtx)
6227 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6228 else if (operands[2] == constm1_rtx)
6229 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6230 abort();
6231
6232 default:
6233 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6234 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6235 if (GET_CODE (operands[2]) == CONST_INT
6236 && (INTVAL (operands[2]) == 128
6237 || (INTVAL (operands[2]) < 0
6238 && INTVAL (operands[2]) != -128)))
6239 {
6240 operands[2] = GEN_INT (-INTVAL (operands[2]));
6241 if (widen)
6242 return "sub{l}\t{%2, %k0|%k0, %2}";
6243 else
6244 return "sub{b}\t{%2, %0|%0, %2}";
6245 }
6246 if (widen)
6247 return "add{l}\t{%k2, %k0|%k0, %k2}";
6248 else
6249 return "add{b}\t{%2, %0|%0, %2}";
6250 }
6251 }
6252 [(set (attr "type")
6253 (if_then_else (eq_attr "alternative" "3")
6254 (const_string "lea")
6255 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6256 (const_string "incdec")
6257 (const_string "alu"))))
6258 (set_attr "mode" "QI,QI,SI,SI")])
6259
6260 (define_insn "*addqi_1"
6261 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6262 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6263 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6264 (clobber (reg:CC 17))]
6265 "TARGET_PARTIAL_REG_STALL
6266 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6267 {
6268 int widen = (which_alternative == 2);
6269 switch (get_attr_type (insn))
6270 {
6271 case TYPE_INCDEC:
6272 if (operands[2] == const1_rtx)
6273 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6274 else if (operands[2] == constm1_rtx)
6275 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6276 abort();
6277
6278 default:
6279 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6280 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6281 if (GET_CODE (operands[2]) == CONST_INT
6282 && (INTVAL (operands[2]) == 128
6283 || (INTVAL (operands[2]) < 0
6284 && INTVAL (operands[2]) != -128)))
6285 {
6286 operands[2] = GEN_INT (-INTVAL (operands[2]));
6287 if (widen)
6288 return "sub{l}\t{%2, %k0|%k0, %2}";
6289 else
6290 return "sub{b}\t{%2, %0|%0, %2}";
6291 }
6292 if (widen)
6293 return "add{l}\t{%k2, %k0|%k0, %k2}";
6294 else
6295 return "add{b}\t{%2, %0|%0, %2}";
6296 }
6297 }
6298 [(set (attr "type")
6299 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6300 (const_string "incdec")
6301 (const_string "alu")))
6302 (set_attr "mode" "QI,QI,SI")])
6303
6304 (define_insn "*addqi_1_slp"
6305 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6306 (plus:QI (match_dup 0)
6307 (match_operand:QI 1 "general_operand" "qn,qnm")))
6308 (clobber (reg:CC 17))]
6309 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6310 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6311 {
6312 switch (get_attr_type (insn))
6313 {
6314 case TYPE_INCDEC:
6315 if (operands[1] == const1_rtx)
6316 return "inc{b}\t%0";
6317 else if (operands[1] == constm1_rtx)
6318 return "dec{b}\t%0";
6319 abort();
6320
6321 default:
6322 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6323 if (GET_CODE (operands[1]) == CONST_INT
6324 && INTVAL (operands[1]) < 0)
6325 {
6326 operands[1] = GEN_INT (-INTVAL (operands[1]));
6327 return "sub{b}\t{%1, %0|%0, %1}";
6328 }
6329 return "add{b}\t{%1, %0|%0, %1}";
6330 }
6331 }
6332 [(set (attr "type")
6333 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6334 (const_string "incdec")
6335 (const_string "alu1")))
6336 (set_attr "mode" "QI")])
6337
6338 (define_insn "*addqi_2"
6339 [(set (reg 17)
6340 (compare
6341 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6342 (match_operand:QI 2 "general_operand" "qmni,qni"))
6343 (const_int 0)))
6344 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6345 (plus:QI (match_dup 1) (match_dup 2)))]
6346 "ix86_match_ccmode (insn, CCGOCmode)
6347 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6348 {
6349 switch (get_attr_type (insn))
6350 {
6351 case TYPE_INCDEC:
6352 if (operands[2] == const1_rtx)
6353 return "inc{b}\t%0";
6354 else if (operands[2] == constm1_rtx
6355 || (GET_CODE (operands[2]) == CONST_INT
6356 && INTVAL (operands[2]) == 255))
6357 return "dec{b}\t%0";
6358 abort();
6359
6360 default:
6361 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6362 if (GET_CODE (operands[2]) == CONST_INT
6363 && INTVAL (operands[2]) < 0)
6364 {
6365 operands[2] = GEN_INT (-INTVAL (operands[2]));
6366 return "sub{b}\t{%2, %0|%0, %2}";
6367 }
6368 return "add{b}\t{%2, %0|%0, %2}";
6369 }
6370 }
6371 [(set (attr "type")
6372 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6373 (const_string "incdec")
6374 (const_string "alu")))
6375 (set_attr "mode" "QI")])
6376
6377 (define_insn "*addqi_3"
6378 [(set (reg 17)
6379 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6380 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6381 (clobber (match_scratch:QI 0 "=q"))]
6382 "ix86_match_ccmode (insn, CCZmode)
6383 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6384 {
6385 switch (get_attr_type (insn))
6386 {
6387 case TYPE_INCDEC:
6388 if (operands[2] == const1_rtx)
6389 return "inc{b}\t%0";
6390 else if (operands[2] == constm1_rtx
6391 || (GET_CODE (operands[2]) == CONST_INT
6392 && INTVAL (operands[2]) == 255))
6393 return "dec{b}\t%0";
6394 abort();
6395
6396 default:
6397 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6398 if (GET_CODE (operands[2]) == CONST_INT
6399 && INTVAL (operands[2]) < 0)
6400 {
6401 operands[2] = GEN_INT (-INTVAL (operands[2]));
6402 return "sub{b}\t{%2, %0|%0, %2}";
6403 }
6404 return "add{b}\t{%2, %0|%0, %2}";
6405 }
6406 }
6407 [(set (attr "type")
6408 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6409 (const_string "incdec")
6410 (const_string "alu")))
6411 (set_attr "mode" "QI")])
6412
6413 ; See comments above addsi_3_imm for details.
6414 (define_insn "*addqi_4"
6415 [(set (reg 17)
6416 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6417 (match_operand:QI 2 "const_int_operand" "n")))
6418 (clobber (match_scratch:QI 0 "=qm"))]
6419 "ix86_match_ccmode (insn, CCGCmode)
6420 && (INTVAL (operands[2]) & 0xff) != 0x80"
6421 {
6422 switch (get_attr_type (insn))
6423 {
6424 case TYPE_INCDEC:
6425 if (operands[2] == constm1_rtx
6426 || (GET_CODE (operands[2]) == CONST_INT
6427 && INTVAL (operands[2]) == 255))
6428 return "inc{b}\t%0";
6429 else if (operands[2] == const1_rtx)
6430 return "dec{b}\t%0";
6431 else
6432 abort();
6433
6434 default:
6435 if (! rtx_equal_p (operands[0], operands[1]))
6436 abort ();
6437 if (INTVAL (operands[2]) < 0)
6438 {
6439 operands[2] = GEN_INT (-INTVAL (operands[2]));
6440 return "add{b}\t{%2, %0|%0, %2}";
6441 }
6442 return "sub{b}\t{%2, %0|%0, %2}";
6443 }
6444 }
6445 [(set (attr "type")
6446 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6447 (const_string "incdec")
6448 (const_string "alu")))
6449 (set_attr "mode" "QI")])
6450
6451
6452 (define_insn "*addqi_5"
6453 [(set (reg 17)
6454 (compare
6455 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6456 (match_operand:QI 2 "general_operand" "qmni"))
6457 (const_int 0)))
6458 (clobber (match_scratch:QI 0 "=q"))]
6459 "ix86_match_ccmode (insn, CCGOCmode)
6460 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6461 {
6462 switch (get_attr_type (insn))
6463 {
6464 case TYPE_INCDEC:
6465 if (operands[2] == const1_rtx)
6466 return "inc{b}\t%0";
6467 else if (operands[2] == constm1_rtx
6468 || (GET_CODE (operands[2]) == CONST_INT
6469 && INTVAL (operands[2]) == 255))
6470 return "dec{b}\t%0";
6471 abort();
6472
6473 default:
6474 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6475 if (GET_CODE (operands[2]) == CONST_INT
6476 && INTVAL (operands[2]) < 0)
6477 {
6478 operands[2] = GEN_INT (-INTVAL (operands[2]));
6479 return "sub{b}\t{%2, %0|%0, %2}";
6480 }
6481 return "add{b}\t{%2, %0|%0, %2}";
6482 }
6483 }
6484 [(set (attr "type")
6485 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6486 (const_string "incdec")
6487 (const_string "alu")))
6488 (set_attr "mode" "QI")])
6489
6490
6491 (define_insn "addqi_ext_1"
6492 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6493 (const_int 8)
6494 (const_int 8))
6495 (plus:SI
6496 (zero_extract:SI
6497 (match_operand 1 "ext_register_operand" "0")
6498 (const_int 8)
6499 (const_int 8))
6500 (match_operand:QI 2 "general_operand" "Qmn")))
6501 (clobber (reg:CC 17))]
6502 "!TARGET_64BIT"
6503 {
6504 switch (get_attr_type (insn))
6505 {
6506 case TYPE_INCDEC:
6507 if (operands[2] == const1_rtx)
6508 return "inc{b}\t%h0";
6509 else if (operands[2] == constm1_rtx
6510 || (GET_CODE (operands[2]) == CONST_INT
6511 && INTVAL (operands[2]) == 255))
6512 return "dec{b}\t%h0";
6513 abort();
6514
6515 default:
6516 return "add{b}\t{%2, %h0|%h0, %2}";
6517 }
6518 }
6519 [(set (attr "type")
6520 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521 (const_string "incdec")
6522 (const_string "alu")))
6523 (set_attr "mode" "QI")])
6524
6525 (define_insn "*addqi_ext_1_rex64"
6526 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6527 (const_int 8)
6528 (const_int 8))
6529 (plus:SI
6530 (zero_extract:SI
6531 (match_operand 1 "ext_register_operand" "0")
6532 (const_int 8)
6533 (const_int 8))
6534 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6535 (clobber (reg:CC 17))]
6536 "TARGET_64BIT"
6537 {
6538 switch (get_attr_type (insn))
6539 {
6540 case TYPE_INCDEC:
6541 if (operands[2] == const1_rtx)
6542 return "inc{b}\t%h0";
6543 else if (operands[2] == constm1_rtx
6544 || (GET_CODE (operands[2]) == CONST_INT
6545 && INTVAL (operands[2]) == 255))
6546 return "dec{b}\t%h0";
6547 abort();
6548
6549 default:
6550 return "add{b}\t{%2, %h0|%h0, %2}";
6551 }
6552 }
6553 [(set (attr "type")
6554 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6555 (const_string "incdec")
6556 (const_string "alu")))
6557 (set_attr "mode" "QI")])
6558
6559 (define_insn "*addqi_ext_2"
6560 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6561 (const_int 8)
6562 (const_int 8))
6563 (plus:SI
6564 (zero_extract:SI
6565 (match_operand 1 "ext_register_operand" "%0")
6566 (const_int 8)
6567 (const_int 8))
6568 (zero_extract:SI
6569 (match_operand 2 "ext_register_operand" "Q")
6570 (const_int 8)
6571 (const_int 8))))
6572 (clobber (reg:CC 17))]
6573 ""
6574 "add{b}\t{%h2, %h0|%h0, %h2}"
6575 [(set_attr "type" "alu")
6576 (set_attr "mode" "QI")])
6577
6578 ;; The patterns that match these are at the end of this file.
6579
6580 (define_expand "addxf3"
6581 [(set (match_operand:XF 0 "register_operand" "")
6582 (plus:XF (match_operand:XF 1 "register_operand" "")
6583 (match_operand:XF 2 "register_operand" "")))]
6584 "TARGET_80387"
6585 "")
6586
6587 (define_expand "adddf3"
6588 [(set (match_operand:DF 0 "register_operand" "")
6589 (plus:DF (match_operand:DF 1 "register_operand" "")
6590 (match_operand:DF 2 "nonimmediate_operand" "")))]
6591 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6592 "")
6593
6594 (define_expand "addsf3"
6595 [(set (match_operand:SF 0 "register_operand" "")
6596 (plus:SF (match_operand:SF 1 "register_operand" "")
6597 (match_operand:SF 2 "nonimmediate_operand" "")))]
6598 "TARGET_80387 || TARGET_SSE_MATH"
6599 "")
6600 \f
6601 ;; Subtract instructions
6602
6603 ;; %%% splits for subsidi3
6604
6605 (define_expand "subdi3"
6606 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6607 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6608 (match_operand:DI 2 "x86_64_general_operand" "")))
6609 (clobber (reg:CC 17))])]
6610 ""
6611 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6612
6613 (define_insn "*subdi3_1"
6614 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6615 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6616 (match_operand:DI 2 "general_operand" "roiF,riF")))
6617 (clobber (reg:CC 17))]
6618 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6619 "#")
6620
6621 (define_split
6622 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6623 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6624 (match_operand:DI 2 "general_operand" "")))
6625 (clobber (reg:CC 17))]
6626 "!TARGET_64BIT && reload_completed"
6627 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6628 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6629 (parallel [(set (match_dup 3)
6630 (minus:SI (match_dup 4)
6631 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6632 (match_dup 5))))
6633 (clobber (reg:CC 17))])]
6634 "split_di (operands+0, 1, operands+0, operands+3);
6635 split_di (operands+1, 1, operands+1, operands+4);
6636 split_di (operands+2, 1, operands+2, operands+5);")
6637
6638 (define_insn "subdi3_carry_rex64"
6639 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6640 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6641 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6642 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6643 (clobber (reg:CC 17))]
6644 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6645 "sbb{q}\t{%2, %0|%0, %2}"
6646 [(set_attr "type" "alu")
6647 (set_attr "pent_pair" "pu")
6648 (set_attr "ppro_uops" "few")
6649 (set_attr "mode" "DI")])
6650
6651 (define_insn "*subdi_1_rex64"
6652 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6653 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6654 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6655 (clobber (reg:CC 17))]
6656 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6657 "sub{q}\t{%2, %0|%0, %2}"
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "DI")])
6660
6661 (define_insn "*subdi_2_rex64"
6662 [(set (reg 17)
6663 (compare
6664 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6665 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6666 (const_int 0)))
6667 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6668 (minus:DI (match_dup 1) (match_dup 2)))]
6669 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6670 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6671 "sub{q}\t{%2, %0|%0, %2}"
6672 [(set_attr "type" "alu")
6673 (set_attr "mode" "DI")])
6674
6675 (define_insn "*subdi_3_rex63"
6676 [(set (reg 17)
6677 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6678 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6679 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6680 (minus:DI (match_dup 1) (match_dup 2)))]
6681 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6682 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6683 "sub{q}\t{%2, %0|%0, %2}"
6684 [(set_attr "type" "alu")
6685 (set_attr "mode" "DI")])
6686
6687 (define_insn "subqi3_carry"
6688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6689 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6690 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6691 (match_operand:QI 2 "general_operand" "qi,qm"))))
6692 (clobber (reg:CC 17))]
6693 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6694 "sbb{b}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "pent_pair" "pu")
6697 (set_attr "ppro_uops" "few")
6698 (set_attr "mode" "QI")])
6699
6700 (define_insn "subhi3_carry"
6701 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6704 (match_operand:HI 2 "general_operand" "ri,rm"))))
6705 (clobber (reg:CC 17))]
6706 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6707 "sbb{w}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "pent_pair" "pu")
6710 (set_attr "ppro_uops" "few")
6711 (set_attr "mode" "HI")])
6712
6713 (define_insn "subsi3_carry"
6714 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6715 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6717 (match_operand:SI 2 "general_operand" "ri,rm"))))
6718 (clobber (reg:CC 17))]
6719 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6720 "sbb{l}\t{%2, %0|%0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "pent_pair" "pu")
6723 (set_attr "ppro_uops" "few")
6724 (set_attr "mode" "SI")])
6725
6726 (define_insn "subsi3_carry_zext"
6727 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6728 (zero_extend:DI
6729 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6730 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6731 (match_operand:SI 2 "general_operand" "ri,rm")))))
6732 (clobber (reg:CC 17))]
6733 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734 "sbb{l}\t{%2, %k0|%k0, %2}"
6735 [(set_attr "type" "alu")
6736 (set_attr "pent_pair" "pu")
6737 (set_attr "ppro_uops" "few")
6738 (set_attr "mode" "SI")])
6739
6740 (define_expand "subsi3"
6741 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6742 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6743 (match_operand:SI 2 "general_operand" "")))
6744 (clobber (reg:CC 17))])]
6745 ""
6746 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6747
6748 (define_insn "*subsi_1"
6749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6750 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:SI 2 "general_operand" "ri,rm")))
6752 (clobber (reg:CC 17))]
6753 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6754 "sub{l}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "SI")])
6757
6758 (define_insn "*subsi_1_zext"
6759 [(set (match_operand:DI 0 "register_operand" "=r")
6760 (zero_extend:DI
6761 (minus:SI (match_operand:SI 1 "register_operand" "0")
6762 (match_operand:SI 2 "general_operand" "rim"))))
6763 (clobber (reg:CC 17))]
6764 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6765 "sub{l}\t{%2, %k0|%k0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "SI")])
6768
6769 (define_insn "*subsi_2"
6770 [(set (reg 17)
6771 (compare
6772 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:SI 2 "general_operand" "ri,rm"))
6774 (const_int 0)))
6775 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6776 (minus:SI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779 "sub{l}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "SI")])
6782
6783 (define_insn "*subsi_2_zext"
6784 [(set (reg 17)
6785 (compare
6786 (minus:SI (match_operand:SI 1 "register_operand" "0")
6787 (match_operand:SI 2 "general_operand" "rim"))
6788 (const_int 0)))
6789 (set (match_operand:DI 0 "register_operand" "=r")
6790 (zero_extend:DI
6791 (minus:SI (match_dup 1)
6792 (match_dup 2))))]
6793 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6794 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6795 "sub{l}\t{%2, %k0|%k0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "mode" "SI")])
6798
6799 (define_insn "*subsi_3"
6800 [(set (reg 17)
6801 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:SI 2 "general_operand" "ri,rm")))
6803 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6804 (minus:SI (match_dup 1) (match_dup 2)))]
6805 "ix86_match_ccmode (insn, CCmode)
6806 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6807 "sub{l}\t{%2, %0|%0, %2}"
6808 [(set_attr "type" "alu")
6809 (set_attr "mode" "SI")])
6810
6811 (define_insn "*subsi_3_zext"
6812 [(set (reg 17)
6813 (compare (match_operand:SI 1 "register_operand" "0")
6814 (match_operand:SI 2 "general_operand" "rim")))
6815 (set (match_operand:DI 0 "register_operand" "=r")
6816 (zero_extend:DI
6817 (minus:SI (match_dup 1)
6818 (match_dup 2))))]
6819 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6820 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6821 "sub{q}\t{%2, %0|%0, %2}"
6822 [(set_attr "type" "alu")
6823 (set_attr "mode" "DI")])
6824
6825 (define_expand "subhi3"
6826 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6827 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6828 (match_operand:HI 2 "general_operand" "")))
6829 (clobber (reg:CC 17))])]
6830 "TARGET_HIMODE_MATH"
6831 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6832
6833 (define_insn "*subhi_1"
6834 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6835 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:HI 2 "general_operand" "ri,rm")))
6837 (clobber (reg:CC 17))]
6838 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6839 "sub{w}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "HI")])
6842
6843 (define_insn "*subhi_2"
6844 [(set (reg 17)
6845 (compare
6846 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6847 (match_operand:HI 2 "general_operand" "ri,rm"))
6848 (const_int 0)))
6849 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6850 (minus:HI (match_dup 1) (match_dup 2)))]
6851 "ix86_match_ccmode (insn, CCGOCmode)
6852 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6853 "sub{w}\t{%2, %0|%0, %2}"
6854 [(set_attr "type" "alu")
6855 (set_attr "mode" "HI")])
6856
6857 (define_insn "*subhi_3"
6858 [(set (reg 17)
6859 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6860 (match_operand:HI 2 "general_operand" "ri,rm")))
6861 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6862 (minus:HI (match_dup 1) (match_dup 2)))]
6863 "ix86_match_ccmode (insn, CCmode)
6864 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6865 "sub{w}\t{%2, %0|%0, %2}"
6866 [(set_attr "type" "alu")
6867 (set_attr "mode" "HI")])
6868
6869 (define_expand "subqi3"
6870 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6871 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6872 (match_operand:QI 2 "general_operand" "")))
6873 (clobber (reg:CC 17))])]
6874 "TARGET_QIMODE_MATH"
6875 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6876
6877 (define_insn "*subqi_1"
6878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880 (match_operand:QI 2 "general_operand" "qn,qmn")))
6881 (clobber (reg:CC 17))]
6882 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6883 "sub{b}\t{%2, %0|%0, %2}"
6884 [(set_attr "type" "alu")
6885 (set_attr "mode" "QI")])
6886
6887 (define_insn "*subqi_1_slp"
6888 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6889 (minus:QI (match_dup 0)
6890 (match_operand:QI 1 "general_operand" "qn,qmn")))
6891 (clobber (reg:CC 17))]
6892 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6893 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6894 "sub{b}\t{%1, %0|%0, %1}"
6895 [(set_attr "type" "alu1")
6896 (set_attr "mode" "QI")])
6897
6898 (define_insn "*subqi_2"
6899 [(set (reg 17)
6900 (compare
6901 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6902 (match_operand:QI 2 "general_operand" "qi,qm"))
6903 (const_int 0)))
6904 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6905 (minus:HI (match_dup 1) (match_dup 2)))]
6906 "ix86_match_ccmode (insn, CCGOCmode)
6907 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6908 "sub{b}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "mode" "QI")])
6911
6912 (define_insn "*subqi_3"
6913 [(set (reg 17)
6914 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6915 (match_operand:QI 2 "general_operand" "qi,qm")))
6916 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6917 (minus:HI (match_dup 1) (match_dup 2)))]
6918 "ix86_match_ccmode (insn, CCmode)
6919 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6920 "sub{b}\t{%2, %0|%0, %2}"
6921 [(set_attr "type" "alu")
6922 (set_attr "mode" "QI")])
6923
6924 ;; The patterns that match these are at the end of this file.
6925
6926 (define_expand "subxf3"
6927 [(set (match_operand:XF 0 "register_operand" "")
6928 (minus:XF (match_operand:XF 1 "register_operand" "")
6929 (match_operand:XF 2 "register_operand" "")))]
6930 "TARGET_80387"
6931 "")
6932
6933 (define_expand "subdf3"
6934 [(set (match_operand:DF 0 "register_operand" "")
6935 (minus:DF (match_operand:DF 1 "register_operand" "")
6936 (match_operand:DF 2 "nonimmediate_operand" "")))]
6937 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6938 "")
6939
6940 (define_expand "subsf3"
6941 [(set (match_operand:SF 0 "register_operand" "")
6942 (minus:SF (match_operand:SF 1 "register_operand" "")
6943 (match_operand:SF 2 "nonimmediate_operand" "")))]
6944 "TARGET_80387 || TARGET_SSE_MATH"
6945 "")
6946 \f
6947 ;; Multiply instructions
6948
6949 (define_expand "muldi3"
6950 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6951 (mult:DI (match_operand:DI 1 "register_operand" "")
6952 (match_operand:DI 2 "x86_64_general_operand" "")))
6953 (clobber (reg:CC 17))])]
6954 "TARGET_64BIT"
6955 "")
6956
6957 (define_insn "*muldi3_1_rex64"
6958 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6959 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6960 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6961 (clobber (reg:CC 17))]
6962 "TARGET_64BIT
6963 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6964 "@
6965 imul{q}\t{%2, %1, %0|%0, %1, %2}
6966 imul{q}\t{%2, %1, %0|%0, %1, %2}
6967 imul{q}\t{%2, %0|%0, %2}"
6968 [(set_attr "type" "imul")
6969 (set_attr "prefix_0f" "0,0,1")
6970 (set (attr "athlon_decode")
6971 (cond [(eq_attr "cpu" "athlon")
6972 (const_string "vector")
6973 (eq_attr "alternative" "1")
6974 (const_string "vector")
6975 (and (eq_attr "alternative" "2")
6976 (match_operand 1 "memory_operand" ""))
6977 (const_string "vector")]
6978 (const_string "direct")))
6979 (set_attr "mode" "DI")])
6980
6981 (define_expand "mulsi3"
6982 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6983 (mult:SI (match_operand:SI 1 "register_operand" "")
6984 (match_operand:SI 2 "general_operand" "")))
6985 (clobber (reg:CC 17))])]
6986 ""
6987 "")
6988
6989 (define_insn "*mulsi3_1"
6990 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6991 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6992 (match_operand:SI 2 "general_operand" "K,i,mr")))
6993 (clobber (reg:CC 17))]
6994 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6995 "@
6996 imul{l}\t{%2, %1, %0|%0, %1, %2}
6997 imul{l}\t{%2, %1, %0|%0, %1, %2}
6998 imul{l}\t{%2, %0|%0, %2}"
6999 [(set_attr "type" "imul")
7000 (set_attr "prefix_0f" "0,0,1")
7001 (set (attr "athlon_decode")
7002 (cond [(eq_attr "cpu" "athlon")
7003 (const_string "vector")
7004 (eq_attr "alternative" "1")
7005 (const_string "vector")
7006 (and (eq_attr "alternative" "2")
7007 (match_operand 1 "memory_operand" ""))
7008 (const_string "vector")]
7009 (const_string "direct")))
7010 (set_attr "mode" "SI")])
7011
7012 (define_insn "*mulsi3_1_zext"
7013 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7014 (zero_extend:DI
7015 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7016 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7017 (clobber (reg:CC 17))]
7018 "TARGET_64BIT
7019 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7020 "@
7021 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7022 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7023 imul{l}\t{%2, %k0|%k0, %2}"
7024 [(set_attr "type" "imul")
7025 (set_attr "prefix_0f" "0,0,1")
7026 (set (attr "athlon_decode")
7027 (cond [(eq_attr "cpu" "athlon")
7028 (const_string "vector")
7029 (eq_attr "alternative" "1")
7030 (const_string "vector")
7031 (and (eq_attr "alternative" "2")
7032 (match_operand 1 "memory_operand" ""))
7033 (const_string "vector")]
7034 (const_string "direct")))
7035 (set_attr "mode" "SI")])
7036
7037 (define_expand "mulhi3"
7038 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7039 (mult:HI (match_operand:HI 1 "register_operand" "")
7040 (match_operand:HI 2 "general_operand" "")))
7041 (clobber (reg:CC 17))])]
7042 "TARGET_HIMODE_MATH"
7043 "")
7044
7045 (define_insn "*mulhi3_1"
7046 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7047 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7048 (match_operand:HI 2 "general_operand" "K,i,mr")))
7049 (clobber (reg:CC 17))]
7050 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7051 "@
7052 imul{w}\t{%2, %1, %0|%0, %1, %2}
7053 imul{w}\t{%2, %1, %0|%0, %1, %2}
7054 imul{w}\t{%2, %0|%0, %2}"
7055 [(set_attr "type" "imul")
7056 (set_attr "prefix_0f" "0,0,1")
7057 (set (attr "athlon_decode")
7058 (cond [(eq_attr "cpu" "athlon")
7059 (const_string "vector")
7060 (eq_attr "alternative" "1,2")
7061 (const_string "vector")]
7062 (const_string "direct")))
7063 (set_attr "mode" "HI")])
7064
7065 (define_expand "mulqi3"
7066 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7067 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7068 (match_operand:QI 2 "register_operand" "")))
7069 (clobber (reg:CC 17))])]
7070 "TARGET_QIMODE_MATH"
7071 "")
7072
7073 (define_insn "*mulqi3_1"
7074 [(set (match_operand:QI 0 "register_operand" "=a")
7075 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7076 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7077 (clobber (reg:CC 17))]
7078 "TARGET_QIMODE_MATH
7079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7080 "mul{b}\t%2"
7081 [(set_attr "type" "imul")
7082 (set_attr "length_immediate" "0")
7083 (set (attr "athlon_decode")
7084 (if_then_else (eq_attr "cpu" "athlon")
7085 (const_string "vector")
7086 (const_string "direct")))
7087 (set_attr "mode" "QI")])
7088
7089 (define_expand "umulqihi3"
7090 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7091 (mult:HI (zero_extend:HI
7092 (match_operand:QI 1 "nonimmediate_operand" ""))
7093 (zero_extend:HI
7094 (match_operand:QI 2 "register_operand" ""))))
7095 (clobber (reg:CC 17))])]
7096 "TARGET_QIMODE_MATH"
7097 "")
7098
7099 (define_insn "*umulqihi3_1"
7100 [(set (match_operand:HI 0 "register_operand" "=a")
7101 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7102 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7103 (clobber (reg:CC 17))]
7104 "TARGET_QIMODE_MATH
7105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7106 "mul{b}\t%2"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "direct")))
7113 (set_attr "mode" "QI")])
7114
7115 (define_expand "mulqihi3"
7116 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7117 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7118 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7119 (clobber (reg:CC 17))])]
7120 "TARGET_QIMODE_MATH"
7121 "")
7122
7123 (define_insn "*mulqihi3_insn"
7124 [(set (match_operand:HI 0 "register_operand" "=a")
7125 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7126 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7127 (clobber (reg:CC 17))]
7128 "TARGET_QIMODE_MATH
7129 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7130 "imul{b}\t%2"
7131 [(set_attr "type" "imul")
7132 (set_attr "length_immediate" "0")
7133 (set (attr "athlon_decode")
7134 (if_then_else (eq_attr "cpu" "athlon")
7135 (const_string "vector")
7136 (const_string "direct")))
7137 (set_attr "mode" "QI")])
7138
7139 (define_expand "umulditi3"
7140 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7141 (mult:TI (zero_extend:TI
7142 (match_operand:DI 1 "nonimmediate_operand" ""))
7143 (zero_extend:TI
7144 (match_operand:DI 2 "register_operand" ""))))
7145 (clobber (reg:CC 17))])]
7146 "TARGET_64BIT"
7147 "")
7148
7149 (define_insn "*umulditi3_insn"
7150 [(set (match_operand:TI 0 "register_operand" "=A")
7151 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7152 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7153 (clobber (reg:CC 17))]
7154 "TARGET_64BIT
7155 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7156 "mul{q}\t%2"
7157 [(set_attr "type" "imul")
7158 (set_attr "ppro_uops" "few")
7159 (set_attr "length_immediate" "0")
7160 (set (attr "athlon_decode")
7161 (if_then_else (eq_attr "cpu" "athlon")
7162 (const_string "vector")
7163 (const_string "double")))
7164 (set_attr "mode" "DI")])
7165
7166 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7167 (define_expand "umulsidi3"
7168 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7169 (mult:DI (zero_extend:DI
7170 (match_operand:SI 1 "nonimmediate_operand" ""))
7171 (zero_extend:DI
7172 (match_operand:SI 2 "register_operand" ""))))
7173 (clobber (reg:CC 17))])]
7174 "!TARGET_64BIT"
7175 "")
7176
7177 (define_insn "*umulsidi3_insn"
7178 [(set (match_operand:DI 0 "register_operand" "=A")
7179 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7180 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7181 (clobber (reg:CC 17))]
7182 "!TARGET_64BIT
7183 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7184 "mul{l}\t%2"
7185 [(set_attr "type" "imul")
7186 (set_attr "ppro_uops" "few")
7187 (set_attr "length_immediate" "0")
7188 (set (attr "athlon_decode")
7189 (if_then_else (eq_attr "cpu" "athlon")
7190 (const_string "vector")
7191 (const_string "double")))
7192 (set_attr "mode" "SI")])
7193
7194 (define_expand "mulditi3"
7195 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7196 (mult:TI (sign_extend:TI
7197 (match_operand:DI 1 "nonimmediate_operand" ""))
7198 (sign_extend:TI
7199 (match_operand:DI 2 "register_operand" ""))))
7200 (clobber (reg:CC 17))])]
7201 "TARGET_64BIT"
7202 "")
7203
7204 (define_insn "*mulditi3_insn"
7205 [(set (match_operand:TI 0 "register_operand" "=A")
7206 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7207 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7208 (clobber (reg:CC 17))]
7209 "TARGET_64BIT
7210 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7211 "imul{q}\t%2"
7212 [(set_attr "type" "imul")
7213 (set_attr "length_immediate" "0")
7214 (set (attr "athlon_decode")
7215 (if_then_else (eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (const_string "double")))
7218 (set_attr "mode" "DI")])
7219
7220 (define_expand "mulsidi3"
7221 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7222 (mult:DI (sign_extend:DI
7223 (match_operand:SI 1 "nonimmediate_operand" ""))
7224 (sign_extend:DI
7225 (match_operand:SI 2 "register_operand" ""))))
7226 (clobber (reg:CC 17))])]
7227 "!TARGET_64BIT"
7228 "")
7229
7230 (define_insn "*mulsidi3_insn"
7231 [(set (match_operand:DI 0 "register_operand" "=A")
7232 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7233 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7234 (clobber (reg:CC 17))]
7235 "!TARGET_64BIT
7236 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7237 "imul{l}\t%2"
7238 [(set_attr "type" "imul")
7239 (set_attr "length_immediate" "0")
7240 (set (attr "athlon_decode")
7241 (if_then_else (eq_attr "cpu" "athlon")
7242 (const_string "vector")
7243 (const_string "double")))
7244 (set_attr "mode" "SI")])
7245
7246 (define_expand "umuldi3_highpart"
7247 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7248 (truncate:DI
7249 (lshiftrt:TI
7250 (mult:TI (zero_extend:TI
7251 (match_operand:DI 1 "nonimmediate_operand" ""))
7252 (zero_extend:TI
7253 (match_operand:DI 2 "register_operand" "")))
7254 (const_int 64))))
7255 (clobber (match_scratch:DI 3 ""))
7256 (clobber (reg:CC 17))])]
7257 "TARGET_64BIT"
7258 "")
7259
7260 (define_insn "*umuldi3_highpart_rex64"
7261 [(set (match_operand:DI 0 "register_operand" "=d")
7262 (truncate:DI
7263 (lshiftrt:TI
7264 (mult:TI (zero_extend:TI
7265 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7266 (zero_extend:TI
7267 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7268 (const_int 64))))
7269 (clobber (match_scratch:DI 3 "=1"))
7270 (clobber (reg:CC 17))]
7271 "TARGET_64BIT
7272 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7273 "mul{q}\t%2"
7274 [(set_attr "type" "imul")
7275 (set_attr "ppro_uops" "few")
7276 (set_attr "length_immediate" "0")
7277 (set (attr "athlon_decode")
7278 (if_then_else (eq_attr "cpu" "athlon")
7279 (const_string "vector")
7280 (const_string "double")))
7281 (set_attr "mode" "DI")])
7282
7283 (define_expand "umulsi3_highpart"
7284 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7285 (truncate:SI
7286 (lshiftrt:DI
7287 (mult:DI (zero_extend:DI
7288 (match_operand:SI 1 "nonimmediate_operand" ""))
7289 (zero_extend:DI
7290 (match_operand:SI 2 "register_operand" "")))
7291 (const_int 32))))
7292 (clobber (match_scratch:SI 3 ""))
7293 (clobber (reg:CC 17))])]
7294 ""
7295 "")
7296
7297 (define_insn "*umulsi3_highpart_insn"
7298 [(set (match_operand:SI 0 "register_operand" "=d")
7299 (truncate:SI
7300 (lshiftrt:DI
7301 (mult:DI (zero_extend:DI
7302 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7303 (zero_extend:DI
7304 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7305 (const_int 32))))
7306 (clobber (match_scratch:SI 3 "=1"))
7307 (clobber (reg:CC 17))]
7308 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7309 "mul{l}\t%2"
7310 [(set_attr "type" "imul")
7311 (set_attr "ppro_uops" "few")
7312 (set_attr "length_immediate" "0")
7313 (set (attr "athlon_decode")
7314 (if_then_else (eq_attr "cpu" "athlon")
7315 (const_string "vector")
7316 (const_string "double")))
7317 (set_attr "mode" "SI")])
7318
7319 (define_insn "*umulsi3_highpart_zext"
7320 [(set (match_operand:DI 0 "register_operand" "=d")
7321 (zero_extend:DI (truncate:SI
7322 (lshiftrt:DI
7323 (mult:DI (zero_extend:DI
7324 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7325 (zero_extend:DI
7326 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7327 (const_int 32)))))
7328 (clobber (match_scratch:SI 3 "=1"))
7329 (clobber (reg:CC 17))]
7330 "TARGET_64BIT
7331 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7332 "mul{l}\t%2"
7333 [(set_attr "type" "imul")
7334 (set_attr "ppro_uops" "few")
7335 (set_attr "length_immediate" "0")
7336 (set (attr "athlon_decode")
7337 (if_then_else (eq_attr "cpu" "athlon")
7338 (const_string "vector")
7339 (const_string "double")))
7340 (set_attr "mode" "SI")])
7341
7342 (define_expand "smuldi3_highpart"
7343 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7344 (truncate:DI
7345 (lshiftrt:TI
7346 (mult:TI (sign_extend:TI
7347 (match_operand:DI 1 "nonimmediate_operand" ""))
7348 (sign_extend:TI
7349 (match_operand:DI 2 "register_operand" "")))
7350 (const_int 64))))
7351 (clobber (match_scratch:DI 3 ""))
7352 (clobber (reg:CC 17))])]
7353 "TARGET_64BIT"
7354 "")
7355
7356 (define_insn "*smuldi3_highpart_rex64"
7357 [(set (match_operand:DI 0 "register_operand" "=d")
7358 (truncate:DI
7359 (lshiftrt:TI
7360 (mult:TI (sign_extend:TI
7361 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7362 (sign_extend:TI
7363 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7364 (const_int 64))))
7365 (clobber (match_scratch:DI 3 "=1"))
7366 (clobber (reg:CC 17))]
7367 "TARGET_64BIT
7368 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7369 "imul{q}\t%2"
7370 [(set_attr "type" "imul")
7371 (set_attr "ppro_uops" "few")
7372 (set (attr "athlon_decode")
7373 (if_then_else (eq_attr "cpu" "athlon")
7374 (const_string "vector")
7375 (const_string "double")))
7376 (set_attr "mode" "DI")])
7377
7378 (define_expand "smulsi3_highpart"
7379 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7380 (truncate:SI
7381 (lshiftrt:DI
7382 (mult:DI (sign_extend:DI
7383 (match_operand:SI 1 "nonimmediate_operand" ""))
7384 (sign_extend:DI
7385 (match_operand:SI 2 "register_operand" "")))
7386 (const_int 32))))
7387 (clobber (match_scratch:SI 3 ""))
7388 (clobber (reg:CC 17))])]
7389 ""
7390 "")
7391
7392 (define_insn "*smulsi3_highpart_insn"
7393 [(set (match_operand:SI 0 "register_operand" "=d")
7394 (truncate:SI
7395 (lshiftrt:DI
7396 (mult:DI (sign_extend:DI
7397 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7398 (sign_extend:DI
7399 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7400 (const_int 32))))
7401 (clobber (match_scratch:SI 3 "=1"))
7402 (clobber (reg:CC 17))]
7403 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7404 "imul{l}\t%2"
7405 [(set_attr "type" "imul")
7406 (set_attr "ppro_uops" "few")
7407 (set (attr "athlon_decode")
7408 (if_then_else (eq_attr "cpu" "athlon")
7409 (const_string "vector")
7410 (const_string "double")))
7411 (set_attr "mode" "SI")])
7412
7413 (define_insn "*smulsi3_highpart_zext"
7414 [(set (match_operand:DI 0 "register_operand" "=d")
7415 (zero_extend:DI (truncate:SI
7416 (lshiftrt:DI
7417 (mult:DI (sign_extend:DI
7418 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7419 (sign_extend:DI
7420 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7421 (const_int 32)))))
7422 (clobber (match_scratch:SI 3 "=1"))
7423 (clobber (reg:CC 17))]
7424 "TARGET_64BIT
7425 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7426 "imul{l}\t%2"
7427 [(set_attr "type" "imul")
7428 (set_attr "ppro_uops" "few")
7429 (set (attr "athlon_decode")
7430 (if_then_else (eq_attr "cpu" "athlon")
7431 (const_string "vector")
7432 (const_string "double")))
7433 (set_attr "mode" "SI")])
7434
7435 ;; The patterns that match these are at the end of this file.
7436
7437 (define_expand "mulxf3"
7438 [(set (match_operand:XF 0 "register_operand" "")
7439 (mult:XF (match_operand:XF 1 "register_operand" "")
7440 (match_operand:XF 2 "register_operand" "")))]
7441 "TARGET_80387"
7442 "")
7443
7444 (define_expand "muldf3"
7445 [(set (match_operand:DF 0 "register_operand" "")
7446 (mult:DF (match_operand:DF 1 "register_operand" "")
7447 (match_operand:DF 2 "nonimmediate_operand" "")))]
7448 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7449 "")
7450
7451 (define_expand "mulsf3"
7452 [(set (match_operand:SF 0 "register_operand" "")
7453 (mult:SF (match_operand:SF 1 "register_operand" "")
7454 (match_operand:SF 2 "nonimmediate_operand" "")))]
7455 "TARGET_80387 || TARGET_SSE_MATH"
7456 "")
7457 \f
7458 ;; Divide instructions
7459
7460 (define_insn "divqi3"
7461 [(set (match_operand:QI 0 "register_operand" "=a")
7462 (div:QI (match_operand:HI 1 "register_operand" "0")
7463 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7464 (clobber (reg:CC 17))]
7465 "TARGET_QIMODE_MATH"
7466 "idiv{b}\t%2"
7467 [(set_attr "type" "idiv")
7468 (set_attr "mode" "QI")
7469 (set_attr "ppro_uops" "few")])
7470
7471 (define_insn "udivqi3"
7472 [(set (match_operand:QI 0 "register_operand" "=a")
7473 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7474 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7475 (clobber (reg:CC 17))]
7476 "TARGET_QIMODE_MATH"
7477 "div{b}\t%2"
7478 [(set_attr "type" "idiv")
7479 (set_attr "mode" "QI")
7480 (set_attr "ppro_uops" "few")])
7481
7482 ;; The patterns that match these are at the end of this file.
7483
7484 (define_expand "divxf3"
7485 [(set (match_operand:XF 0 "register_operand" "")
7486 (div:XF (match_operand:XF 1 "register_operand" "")
7487 (match_operand:XF 2 "register_operand" "")))]
7488 "TARGET_80387"
7489 "")
7490
7491 (define_expand "divdf3"
7492 [(set (match_operand:DF 0 "register_operand" "")
7493 (div:DF (match_operand:DF 1 "register_operand" "")
7494 (match_operand:DF 2 "nonimmediate_operand" "")))]
7495 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7496 "")
7497
7498 (define_expand "divsf3"
7499 [(set (match_operand:SF 0 "register_operand" "")
7500 (div:SF (match_operand:SF 1 "register_operand" "")
7501 (match_operand:SF 2 "nonimmediate_operand" "")))]
7502 "TARGET_80387 || TARGET_SSE_MATH"
7503 "")
7504 \f
7505 ;; Remainder instructions.
7506
7507 (define_expand "divmoddi4"
7508 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7509 (div:DI (match_operand:DI 1 "register_operand" "")
7510 (match_operand:DI 2 "nonimmediate_operand" "")))
7511 (set (match_operand:DI 3 "register_operand" "")
7512 (mod:DI (match_dup 1) (match_dup 2)))
7513 (clobber (reg:CC 17))])]
7514 "TARGET_64BIT"
7515 "")
7516
7517 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7518 ;; Penalize eax case slightly because it results in worse scheduling
7519 ;; of code.
7520 (define_insn "*divmoddi4_nocltd_rex64"
7521 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7522 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7523 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7524 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7525 (mod:DI (match_dup 2) (match_dup 3)))
7526 (clobber (reg:CC 17))]
7527 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7528 "#"
7529 [(set_attr "type" "multi")])
7530
7531 (define_insn "*divmoddi4_cltd_rex64"
7532 [(set (match_operand:DI 0 "register_operand" "=a")
7533 (div:DI (match_operand:DI 2 "register_operand" "a")
7534 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7535 (set (match_operand:DI 1 "register_operand" "=&d")
7536 (mod:DI (match_dup 2) (match_dup 3)))
7537 (clobber (reg:CC 17))]
7538 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7539 "#"
7540 [(set_attr "type" "multi")])
7541
7542 (define_insn "*divmoddi_noext_rex64"
7543 [(set (match_operand:DI 0 "register_operand" "=a")
7544 (div:DI (match_operand:DI 1 "register_operand" "0")
7545 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546 (set (match_operand:DI 3 "register_operand" "=d")
7547 (mod:DI (match_dup 1) (match_dup 2)))
7548 (use (match_operand:DI 4 "register_operand" "3"))
7549 (clobber (reg:CC 17))]
7550 "TARGET_64BIT"
7551 "idiv{q}\t%2"
7552 [(set_attr "type" "idiv")
7553 (set_attr "mode" "DI")
7554 (set_attr "ppro_uops" "few")])
7555
7556 (define_split
7557 [(set (match_operand:DI 0 "register_operand" "")
7558 (div:DI (match_operand:DI 1 "register_operand" "")
7559 (match_operand:DI 2 "nonimmediate_operand" "")))
7560 (set (match_operand:DI 3 "register_operand" "")
7561 (mod:DI (match_dup 1) (match_dup 2)))
7562 (clobber (reg:CC 17))]
7563 "TARGET_64BIT && reload_completed"
7564 [(parallel [(set (match_dup 3)
7565 (ashiftrt:DI (match_dup 4) (const_int 63)))
7566 (clobber (reg:CC 17))])
7567 (parallel [(set (match_dup 0)
7568 (div:DI (reg:DI 0) (match_dup 2)))
7569 (set (match_dup 3)
7570 (mod:DI (reg:DI 0) (match_dup 2)))
7571 (use (match_dup 3))
7572 (clobber (reg:CC 17))])]
7573 {
7574 /* Avoid use of cltd in favor of a mov+shift. */
7575 if (!TARGET_USE_CLTD && !optimize_size)
7576 {
7577 if (true_regnum (operands[1]))
7578 emit_move_insn (operands[0], operands[1]);
7579 else
7580 emit_move_insn (operands[3], operands[1]);
7581 operands[4] = operands[3];
7582 }
7583 else
7584 {
7585 if (true_regnum (operands[1]))
7586 abort();
7587 operands[4] = operands[1];
7588 }
7589 })
7590
7591
7592 (define_expand "divmodsi4"
7593 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7594 (div:SI (match_operand:SI 1 "register_operand" "")
7595 (match_operand:SI 2 "nonimmediate_operand" "")))
7596 (set (match_operand:SI 3 "register_operand" "")
7597 (mod:SI (match_dup 1) (match_dup 2)))
7598 (clobber (reg:CC 17))])]
7599 ""
7600 "")
7601
7602 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7603 ;; Penalize eax case slightly because it results in worse scheduling
7604 ;; of code.
7605 (define_insn "*divmodsi4_nocltd"
7606 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7607 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7608 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7609 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7610 (mod:SI (match_dup 2) (match_dup 3)))
7611 (clobber (reg:CC 17))]
7612 "!optimize_size && !TARGET_USE_CLTD"
7613 "#"
7614 [(set_attr "type" "multi")])
7615
7616 (define_insn "*divmodsi4_cltd"
7617 [(set (match_operand:SI 0 "register_operand" "=a")
7618 (div:SI (match_operand:SI 2 "register_operand" "a")
7619 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7620 (set (match_operand:SI 1 "register_operand" "=&d")
7621 (mod:SI (match_dup 2) (match_dup 3)))
7622 (clobber (reg:CC 17))]
7623 "optimize_size || TARGET_USE_CLTD"
7624 "#"
7625 [(set_attr "type" "multi")])
7626
7627 (define_insn "*divmodsi_noext"
7628 [(set (match_operand:SI 0 "register_operand" "=a")
7629 (div:SI (match_operand:SI 1 "register_operand" "0")
7630 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7631 (set (match_operand:SI 3 "register_operand" "=d")
7632 (mod:SI (match_dup 1) (match_dup 2)))
7633 (use (match_operand:SI 4 "register_operand" "3"))
7634 (clobber (reg:CC 17))]
7635 ""
7636 "idiv{l}\t%2"
7637 [(set_attr "type" "idiv")
7638 (set_attr "mode" "SI")
7639 (set_attr "ppro_uops" "few")])
7640
7641 (define_split
7642 [(set (match_operand:SI 0 "register_operand" "")
7643 (div:SI (match_operand:SI 1 "register_operand" "")
7644 (match_operand:SI 2 "nonimmediate_operand" "")))
7645 (set (match_operand:SI 3 "register_operand" "")
7646 (mod:SI (match_dup 1) (match_dup 2)))
7647 (clobber (reg:CC 17))]
7648 "reload_completed"
7649 [(parallel [(set (match_dup 3)
7650 (ashiftrt:SI (match_dup 4) (const_int 31)))
7651 (clobber (reg:CC 17))])
7652 (parallel [(set (match_dup 0)
7653 (div:SI (reg:SI 0) (match_dup 2)))
7654 (set (match_dup 3)
7655 (mod:SI (reg:SI 0) (match_dup 2)))
7656 (use (match_dup 3))
7657 (clobber (reg:CC 17))])]
7658 {
7659 /* Avoid use of cltd in favor of a mov+shift. */
7660 if (!TARGET_USE_CLTD && !optimize_size)
7661 {
7662 if (true_regnum (operands[1]))
7663 emit_move_insn (operands[0], operands[1]);
7664 else
7665 emit_move_insn (operands[3], operands[1]);
7666 operands[4] = operands[3];
7667 }
7668 else
7669 {
7670 if (true_regnum (operands[1]))
7671 abort();
7672 operands[4] = operands[1];
7673 }
7674 })
7675 ;; %%% Split me.
7676 (define_insn "divmodhi4"
7677 [(set (match_operand:HI 0 "register_operand" "=a")
7678 (div:HI (match_operand:HI 1 "register_operand" "0")
7679 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7680 (set (match_operand:HI 3 "register_operand" "=&d")
7681 (mod:HI (match_dup 1) (match_dup 2)))
7682 (clobber (reg:CC 17))]
7683 "TARGET_HIMODE_MATH"
7684 "cwtd\;idiv{w}\t%2"
7685 [(set_attr "type" "multi")
7686 (set_attr "length_immediate" "0")
7687 (set_attr "mode" "SI")])
7688
7689 (define_insn "udivmoddi4"
7690 [(set (match_operand:DI 0 "register_operand" "=a")
7691 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7692 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7693 (set (match_operand:DI 3 "register_operand" "=&d")
7694 (umod:DI (match_dup 1) (match_dup 2)))
7695 (clobber (reg:CC 17))]
7696 "TARGET_64BIT"
7697 "xor{q}\t%3, %3\;div{q}\t%2"
7698 [(set_attr "type" "multi")
7699 (set_attr "length_immediate" "0")
7700 (set_attr "mode" "DI")])
7701
7702 (define_insn "*udivmoddi4_noext"
7703 [(set (match_operand:DI 0 "register_operand" "=a")
7704 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7705 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7706 (set (match_operand:DI 3 "register_operand" "=d")
7707 (umod:DI (match_dup 1) (match_dup 2)))
7708 (use (match_dup 3))
7709 (clobber (reg:CC 17))]
7710 "TARGET_64BIT"
7711 "div{q}\t%2"
7712 [(set_attr "type" "idiv")
7713 (set_attr "ppro_uops" "few")
7714 (set_attr "mode" "DI")])
7715
7716 (define_split
7717 [(set (match_operand:DI 0 "register_operand" "")
7718 (udiv:DI (match_operand:DI 1 "register_operand" "")
7719 (match_operand:DI 2 "nonimmediate_operand" "")))
7720 (set (match_operand:DI 3 "register_operand" "")
7721 (umod:DI (match_dup 1) (match_dup 2)))
7722 (clobber (reg:CC 17))]
7723 "TARGET_64BIT && reload_completed"
7724 [(set (match_dup 3) (const_int 0))
7725 (parallel [(set (match_dup 0)
7726 (udiv:DI (match_dup 1) (match_dup 2)))
7727 (set (match_dup 3)
7728 (umod:DI (match_dup 1) (match_dup 2)))
7729 (use (match_dup 3))
7730 (clobber (reg:CC 17))])]
7731 "")
7732
7733 (define_insn "udivmodsi4"
7734 [(set (match_operand:SI 0 "register_operand" "=a")
7735 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7736 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7737 (set (match_operand:SI 3 "register_operand" "=&d")
7738 (umod:SI (match_dup 1) (match_dup 2)))
7739 (clobber (reg:CC 17))]
7740 ""
7741 "xor{l}\t%3, %3\;div{l}\t%2"
7742 [(set_attr "type" "multi")
7743 (set_attr "length_immediate" "0")
7744 (set_attr "mode" "SI")])
7745
7746 (define_insn "*udivmodsi4_noext"
7747 [(set (match_operand:SI 0 "register_operand" "=a")
7748 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7749 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7750 (set (match_operand:SI 3 "register_operand" "=d")
7751 (umod:SI (match_dup 1) (match_dup 2)))
7752 (use (match_dup 3))
7753 (clobber (reg:CC 17))]
7754 ""
7755 "div{l}\t%2"
7756 [(set_attr "type" "idiv")
7757 (set_attr "ppro_uops" "few")
7758 (set_attr "mode" "SI")])
7759
7760 (define_split
7761 [(set (match_operand:SI 0 "register_operand" "")
7762 (udiv:SI (match_operand:SI 1 "register_operand" "")
7763 (match_operand:SI 2 "nonimmediate_operand" "")))
7764 (set (match_operand:SI 3 "register_operand" "")
7765 (umod:SI (match_dup 1) (match_dup 2)))
7766 (clobber (reg:CC 17))]
7767 "reload_completed"
7768 [(set (match_dup 3) (const_int 0))
7769 (parallel [(set (match_dup 0)
7770 (udiv:SI (match_dup 1) (match_dup 2)))
7771 (set (match_dup 3)
7772 (umod:SI (match_dup 1) (match_dup 2)))
7773 (use (match_dup 3))
7774 (clobber (reg:CC 17))])]
7775 "")
7776
7777 (define_expand "udivmodhi4"
7778 [(set (match_dup 4) (const_int 0))
7779 (parallel [(set (match_operand:HI 0 "register_operand" "")
7780 (udiv:HI (match_operand:HI 1 "register_operand" "")
7781 (match_operand:HI 2 "nonimmediate_operand" "")))
7782 (set (match_operand:HI 3 "register_operand" "")
7783 (umod:HI (match_dup 1) (match_dup 2)))
7784 (use (match_dup 4))
7785 (clobber (reg:CC 17))])]
7786 "TARGET_HIMODE_MATH"
7787 "operands[4] = gen_reg_rtx (HImode);")
7788
7789 (define_insn "*udivmodhi_noext"
7790 [(set (match_operand:HI 0 "register_operand" "=a")
7791 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7792 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7793 (set (match_operand:HI 3 "register_operand" "=d")
7794 (umod:HI (match_dup 1) (match_dup 2)))
7795 (use (match_operand:HI 4 "register_operand" "3"))
7796 (clobber (reg:CC 17))]
7797 ""
7798 "div{w}\t%2"
7799 [(set_attr "type" "idiv")
7800 (set_attr "mode" "HI")
7801 (set_attr "ppro_uops" "few")])
7802
7803 ;; We can not use div/idiv for double division, because it causes
7804 ;; "division by zero" on the overflow and that's not what we expect
7805 ;; from truncate. Because true (non truncating) double division is
7806 ;; never generated, we can't create this insn anyway.
7807 ;
7808 ;(define_insn ""
7809 ; [(set (match_operand:SI 0 "register_operand" "=a")
7810 ; (truncate:SI
7811 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7812 ; (zero_extend:DI
7813 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7814 ; (set (match_operand:SI 3 "register_operand" "=d")
7815 ; (truncate:SI
7816 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7817 ; (clobber (reg:CC 17))]
7818 ; ""
7819 ; "div{l}\t{%2, %0|%0, %2}"
7820 ; [(set_attr "type" "idiv")
7821 ; (set_attr "ppro_uops" "few")])
7822 \f
7823 ;;- Logical AND instructions
7824
7825 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7826 ;; Note that this excludes ah.
7827
7828 (define_insn "*testdi_1_rex64"
7829 [(set (reg 17)
7830 (compare
7831 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7832 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7833 (const_int 0)))]
7834 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836 "@
7837 test{l}\t{%k1, %k0|%k0, %k1}
7838 test{l}\t{%k1, %k0|%k0, %k1}
7839 test{q}\t{%1, %0|%0, %1}
7840 test{q}\t{%1, %0|%0, %1}
7841 test{q}\t{%1, %0|%0, %1}"
7842 [(set_attr "type" "test")
7843 (set_attr "modrm" "0,1,0,1,1")
7844 (set_attr "mode" "SI,SI,DI,DI,DI")
7845 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7846
7847 (define_insn "testsi_1"
7848 [(set (reg 17)
7849 (compare
7850 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7851 (match_operand:SI 1 "general_operand" "in,in,rin"))
7852 (const_int 0)))]
7853 "ix86_match_ccmode (insn, CCNOmode)
7854 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7855 "test{l}\t{%1, %0|%0, %1}"
7856 [(set_attr "type" "test")
7857 (set_attr "modrm" "0,1,1")
7858 (set_attr "mode" "SI")
7859 (set_attr "pent_pair" "uv,np,uv")])
7860
7861 (define_expand "testsi_ccno_1"
7862 [(set (reg:CCNO 17)
7863 (compare:CCNO
7864 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7865 (match_operand:SI 1 "nonmemory_operand" ""))
7866 (const_int 0)))]
7867 ""
7868 "")
7869
7870 (define_insn "*testhi_1"
7871 [(set (reg 17)
7872 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7873 (match_operand:HI 1 "general_operand" "n,n,rn"))
7874 (const_int 0)))]
7875 "ix86_match_ccmode (insn, CCNOmode)
7876 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7877 "test{w}\t{%1, %0|%0, %1}"
7878 [(set_attr "type" "test")
7879 (set_attr "modrm" "0,1,1")
7880 (set_attr "mode" "HI")
7881 (set_attr "pent_pair" "uv,np,uv")])
7882
7883 (define_expand "testqi_ccz_1"
7884 [(set (reg:CCZ 17)
7885 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7886 (match_operand:QI 1 "nonmemory_operand" ""))
7887 (const_int 0)))]
7888 ""
7889 "")
7890
7891 (define_insn "*testqi_1"
7892 [(set (reg 17)
7893 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7894 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7895 (const_int 0)))]
7896 "ix86_match_ccmode (insn, CCNOmode)
7897 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7898 {
7899 if (which_alternative == 3)
7900 {
7901 if (GET_CODE (operands[1]) == CONST_INT
7902 && (INTVAL (operands[1]) & 0xffffff00))
7903 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7904 return "test{l}\t{%1, %k0|%k0, %1}";
7905 }
7906 return "test{b}\t{%1, %0|%0, %1}";
7907 }
7908 [(set_attr "type" "test")
7909 (set_attr "modrm" "0,1,1,1")
7910 (set_attr "mode" "QI,QI,QI,SI")
7911 (set_attr "pent_pair" "uv,np,uv,np")])
7912
7913 (define_expand "testqi_ext_ccno_0"
7914 [(set (reg:CCNO 17)
7915 (compare:CCNO
7916 (and:SI
7917 (zero_extract:SI
7918 (match_operand 0 "ext_register_operand" "")
7919 (const_int 8)
7920 (const_int 8))
7921 (match_operand 1 "const_int_operand" ""))
7922 (const_int 0)))]
7923 ""
7924 "")
7925
7926 (define_insn "*testqi_ext_0"
7927 [(set (reg 17)
7928 (compare
7929 (and:SI
7930 (zero_extract:SI
7931 (match_operand 0 "ext_register_operand" "Q")
7932 (const_int 8)
7933 (const_int 8))
7934 (match_operand 1 "const_int_operand" "n"))
7935 (const_int 0)))]
7936 "ix86_match_ccmode (insn, CCNOmode)"
7937 "test{b}\t{%1, %h0|%h0, %1}"
7938 [(set_attr "type" "test")
7939 (set_attr "mode" "QI")
7940 (set_attr "length_immediate" "1")
7941 (set_attr "pent_pair" "np")])
7942
7943 (define_insn "*testqi_ext_1"
7944 [(set (reg 17)
7945 (compare
7946 (and:SI
7947 (zero_extract:SI
7948 (match_operand 0 "ext_register_operand" "Q")
7949 (const_int 8)
7950 (const_int 8))
7951 (zero_extend:SI
7952 (match_operand:QI 1 "general_operand" "Qm")))
7953 (const_int 0)))]
7954 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7955 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7956 "test{b}\t{%1, %h0|%h0, %1}"
7957 [(set_attr "type" "test")
7958 (set_attr "mode" "QI")])
7959
7960 (define_insn "*testqi_ext_1_rex64"
7961 [(set (reg 17)
7962 (compare
7963 (and:SI
7964 (zero_extract:SI
7965 (match_operand 0 "ext_register_operand" "Q")
7966 (const_int 8)
7967 (const_int 8))
7968 (zero_extend:SI
7969 (match_operand:QI 1 "register_operand" "Q")))
7970 (const_int 0)))]
7971 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7972 "test{b}\t{%1, %h0|%h0, %1}"
7973 [(set_attr "type" "test")
7974 (set_attr "mode" "QI")])
7975
7976 (define_insn "*testqi_ext_2"
7977 [(set (reg 17)
7978 (compare
7979 (and:SI
7980 (zero_extract:SI
7981 (match_operand 0 "ext_register_operand" "Q")
7982 (const_int 8)
7983 (const_int 8))
7984 (zero_extract:SI
7985 (match_operand 1 "ext_register_operand" "Q")
7986 (const_int 8)
7987 (const_int 8)))
7988 (const_int 0)))]
7989 "ix86_match_ccmode (insn, CCNOmode)"
7990 "test{b}\t{%h1, %h0|%h0, %h1}"
7991 [(set_attr "type" "test")
7992 (set_attr "mode" "QI")])
7993
7994 ;; Combine likes to form bit extractions for some tests. Humor it.
7995 (define_insn "*testqi_ext_3"
7996 [(set (reg 17)
7997 (compare (zero_extract:SI
7998 (match_operand 0 "nonimmediate_operand" "rm")
7999 (match_operand:SI 1 "const_int_operand" "")
8000 (match_operand:SI 2 "const_int_operand" ""))
8001 (const_int 0)))]
8002 "ix86_match_ccmode (insn, CCNOmode)
8003 && (GET_MODE (operands[0]) == SImode
8004 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8005 || GET_MODE (operands[0]) == HImode
8006 || GET_MODE (operands[0]) == QImode)"
8007 "#")
8008
8009 (define_insn "*testqi_ext_3_rex64"
8010 [(set (reg 17)
8011 (compare (zero_extract:DI
8012 (match_operand 0 "nonimmediate_operand" "rm")
8013 (match_operand:DI 1 "const_int_operand" "")
8014 (match_operand:DI 2 "const_int_operand" ""))
8015 (const_int 0)))]
8016 "TARGET_64BIT
8017 && ix86_match_ccmode (insn, CCNOmode)
8018 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8019 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8020 /* Ensure that resulting mask is zero or sign extended operand. */
8021 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8022 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8023 && INTVAL (operands[1]) > 32))
8024 && (GET_MODE (operands[0]) == SImode
8025 || GET_MODE (operands[0]) == DImode
8026 || GET_MODE (operands[0]) == HImode
8027 || GET_MODE (operands[0]) == QImode)"
8028 "#")
8029
8030 (define_split
8031 [(set (reg 17)
8032 (compare (zero_extract
8033 (match_operand 0 "nonimmediate_operand" "")
8034 (match_operand 1 "const_int_operand" "")
8035 (match_operand 2 "const_int_operand" ""))
8036 (const_int 0)))]
8037 "ix86_match_ccmode (insn, CCNOmode)"
8038 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8039 {
8040 HOST_WIDE_INT len = INTVAL (operands[1]);
8041 HOST_WIDE_INT pos = INTVAL (operands[2]);
8042 HOST_WIDE_INT mask;
8043 enum machine_mode mode, submode;
8044
8045 mode = GET_MODE (operands[0]);
8046 if (GET_CODE (operands[0]) == MEM)
8047 {
8048 /* ??? Combine likes to put non-volatile mem extractions in QImode
8049 no matter the size of the test. So find a mode that works. */
8050 if (! MEM_VOLATILE_P (operands[0]))
8051 {
8052 mode = smallest_mode_for_size (pos + len, MODE_INT);
8053 operands[0] = adjust_address (operands[0], mode, 0);
8054 }
8055 }
8056 else if (GET_CODE (operands[0]) == SUBREG
8057 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8058 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8059 && pos + len <= GET_MODE_BITSIZE (submode))
8060 {
8061 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8062 mode = submode;
8063 operands[0] = SUBREG_REG (operands[0]);
8064 }
8065 else if (mode == HImode && pos + len <= 8)
8066 {
8067 /* Small HImode tests can be converted to QImode. */
8068 mode = QImode;
8069 operands[0] = gen_lowpart (QImode, operands[0]);
8070 }
8071
8072 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8073 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8074
8075 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8076 })
8077
8078 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8079 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8080 ;; this is relatively important trick.
8081 ;; Do the conversion only post-reload to avoid limiting of the register class
8082 ;; to QI regs.
8083 (define_split
8084 [(set (reg 17)
8085 (compare
8086 (and (match_operand 0 "register_operand" "")
8087 (match_operand 1 "const_int_operand" ""))
8088 (const_int 0)))]
8089 "reload_completed
8090 && QI_REG_P (operands[0])
8091 && ((ix86_match_ccmode (insn, CCZmode)
8092 && !(INTVAL (operands[1]) & ~(255 << 8)))
8093 || (ix86_match_ccmode (insn, CCNOmode)
8094 && !(INTVAL (operands[1]) & ~(127 << 8))))
8095 && GET_MODE (operands[0]) != QImode"
8096 [(set (reg:CCNO 17)
8097 (compare:CCNO
8098 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8099 (match_dup 1))
8100 (const_int 0)))]
8101 "operands[0] = gen_lowpart (SImode, operands[0]);
8102 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8103
8104 (define_split
8105 [(set (reg 17)
8106 (compare
8107 (and (match_operand 0 "nonimmediate_operand" "")
8108 (match_operand 1 "const_int_operand" ""))
8109 (const_int 0)))]
8110 "reload_completed
8111 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8112 && ((ix86_match_ccmode (insn, CCZmode)
8113 && !(INTVAL (operands[1]) & ~255))
8114 || (ix86_match_ccmode (insn, CCNOmode)
8115 && !(INTVAL (operands[1]) & ~127)))
8116 && GET_MODE (operands[0]) != QImode"
8117 [(set (reg:CCNO 17)
8118 (compare:CCNO
8119 (and:QI (match_dup 0)
8120 (match_dup 1))
8121 (const_int 0)))]
8122 "operands[0] = gen_lowpart (QImode, operands[0]);
8123 operands[1] = gen_lowpart (QImode, operands[1]);")
8124
8125
8126 ;; %%% This used to optimize known byte-wide and operations to memory,
8127 ;; and sometimes to QImode registers. If this is considered useful,
8128 ;; it should be done with splitters.
8129
8130 (define_expand "anddi3"
8131 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8132 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8133 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8134 (clobber (reg:CC 17))]
8135 "TARGET_64BIT"
8136 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8137
8138 (define_insn "*anddi_1_rex64"
8139 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8140 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8141 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8142 (clobber (reg:CC 17))]
8143 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8144 {
8145 switch (get_attr_type (insn))
8146 {
8147 case TYPE_IMOVX:
8148 {
8149 enum machine_mode mode;
8150
8151 if (GET_CODE (operands[2]) != CONST_INT)
8152 abort ();
8153 if (INTVAL (operands[2]) == 0xff)
8154 mode = QImode;
8155 else if (INTVAL (operands[2]) == 0xffff)
8156 mode = HImode;
8157 else
8158 abort ();
8159
8160 operands[1] = gen_lowpart (mode, operands[1]);
8161 if (mode == QImode)
8162 return "movz{bq|x}\t{%1,%0|%0, %1}";
8163 else
8164 return "movz{wq|x}\t{%1,%0|%0, %1}";
8165 }
8166
8167 default:
8168 if (! rtx_equal_p (operands[0], operands[1]))
8169 abort ();
8170 if (get_attr_mode (insn) == MODE_SI)
8171 return "and{l}\t{%k2, %k0|%k0, %k2}";
8172 else
8173 return "and{q}\t{%2, %0|%0, %2}";
8174 }
8175 }
8176 [(set_attr "type" "alu,alu,alu,imovx")
8177 (set_attr "length_immediate" "*,*,*,0")
8178 (set_attr "mode" "SI,DI,DI,DI")])
8179
8180 (define_insn "*anddi_2"
8181 [(set (reg 17)
8182 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8183 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8184 (const_int 0)))
8185 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8186 (and:DI (match_dup 1) (match_dup 2)))]
8187 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8188 && ix86_binary_operator_ok (AND, DImode, operands)"
8189 "@
8190 and{l}\t{%k2, %k0|%k0, %k2}
8191 and{q}\t{%2, %0|%0, %2}
8192 and{q}\t{%2, %0|%0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "SI,DI,DI")])
8195
8196 (define_expand "andsi3"
8197 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8198 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8199 (match_operand:SI 2 "general_operand" "")))
8200 (clobber (reg:CC 17))]
8201 ""
8202 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8203
8204 (define_insn "*andsi_1"
8205 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8206 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8207 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8208 (clobber (reg:CC 17))]
8209 "ix86_binary_operator_ok (AND, SImode, operands)"
8210 {
8211 switch (get_attr_type (insn))
8212 {
8213 case TYPE_IMOVX:
8214 {
8215 enum machine_mode mode;
8216
8217 if (GET_CODE (operands[2]) != CONST_INT)
8218 abort ();
8219 if (INTVAL (operands[2]) == 0xff)
8220 mode = QImode;
8221 else if (INTVAL (operands[2]) == 0xffff)
8222 mode = HImode;
8223 else
8224 abort ();
8225
8226 operands[1] = gen_lowpart (mode, operands[1]);
8227 if (mode == QImode)
8228 return "movz{bl|x}\t{%1,%0|%0, %1}";
8229 else
8230 return "movz{wl|x}\t{%1,%0|%0, %1}";
8231 }
8232
8233 default:
8234 if (! rtx_equal_p (operands[0], operands[1]))
8235 abort ();
8236 return "and{l}\t{%2, %0|%0, %2}";
8237 }
8238 }
8239 [(set_attr "type" "alu,alu,imovx")
8240 (set_attr "length_immediate" "*,*,0")
8241 (set_attr "mode" "SI")])
8242
8243 (define_split
8244 [(set (match_operand 0 "register_operand" "")
8245 (and (match_dup 0)
8246 (const_int -65536)))
8247 (clobber (reg:CC 17))]
8248 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8249 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8250 "operands[1] = gen_lowpart (HImode, operands[0]);")
8251
8252 (define_split
8253 [(set (match_operand 0 "ext_register_operand" "")
8254 (and (match_dup 0)
8255 (const_int -256)))
8256 (clobber (reg:CC 17))]
8257 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8258 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8259 "operands[1] = gen_lowpart (QImode, operands[0]);")
8260
8261 (define_split
8262 [(set (match_operand 0 "ext_register_operand" "")
8263 (and (match_dup 0)
8264 (const_int -65281)))
8265 (clobber (reg:CC 17))]
8266 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8267 [(parallel [(set (zero_extract:SI (match_dup 0)
8268 (const_int 8)
8269 (const_int 8))
8270 (xor:SI
8271 (zero_extract:SI (match_dup 0)
8272 (const_int 8)
8273 (const_int 8))
8274 (zero_extract:SI (match_dup 0)
8275 (const_int 8)
8276 (const_int 8))))
8277 (clobber (reg:CC 17))])]
8278 "operands[0] = gen_lowpart (SImode, operands[0]);")
8279
8280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8281 (define_insn "*andsi_1_zext"
8282 [(set (match_operand:DI 0 "register_operand" "=r")
8283 (zero_extend:DI
8284 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8285 (match_operand:SI 2 "general_operand" "rim"))))
8286 (clobber (reg:CC 17))]
8287 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8288 "and{l}\t{%2, %k0|%k0, %2}"
8289 [(set_attr "type" "alu")
8290 (set_attr "mode" "SI")])
8291
8292 (define_insn "*andsi_2"
8293 [(set (reg 17)
8294 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8295 (match_operand:SI 2 "general_operand" "rim,ri"))
8296 (const_int 0)))
8297 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8298 (and:SI (match_dup 1) (match_dup 2)))]
8299 "ix86_match_ccmode (insn, CCNOmode)
8300 && ix86_binary_operator_ok (AND, SImode, operands)"
8301 "and{l}\t{%2, %0|%0, %2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "SI")])
8304
8305 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8306 (define_insn "*andsi_2_zext"
8307 [(set (reg 17)
8308 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8309 (match_operand:SI 2 "general_operand" "rim"))
8310 (const_int 0)))
8311 (set (match_operand:DI 0 "register_operand" "=r")
8312 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8313 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8314 && ix86_binary_operator_ok (AND, SImode, operands)"
8315 "and{l}\t{%2, %k0|%k0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "mode" "SI")])
8318
8319 (define_expand "andhi3"
8320 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8321 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8322 (match_operand:HI 2 "general_operand" "")))
8323 (clobber (reg:CC 17))]
8324 "TARGET_HIMODE_MATH"
8325 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8326
8327 (define_insn "*andhi_1"
8328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8329 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8330 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8331 (clobber (reg:CC 17))]
8332 "ix86_binary_operator_ok (AND, HImode, operands)"
8333 {
8334 switch (get_attr_type (insn))
8335 {
8336 case TYPE_IMOVX:
8337 if (GET_CODE (operands[2]) != CONST_INT)
8338 abort ();
8339 if (INTVAL (operands[2]) == 0xff)
8340 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8341 abort ();
8342
8343 default:
8344 if (! rtx_equal_p (operands[0], operands[1]))
8345 abort ();
8346
8347 return "and{w}\t{%2, %0|%0, %2}";
8348 }
8349 }
8350 [(set_attr "type" "alu,alu,imovx")
8351 (set_attr "length_immediate" "*,*,0")
8352 (set_attr "mode" "HI,HI,SI")])
8353
8354 (define_insn "*andhi_2"
8355 [(set (reg 17)
8356 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357 (match_operand:HI 2 "general_operand" "rim,ri"))
8358 (const_int 0)))
8359 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360 (and:HI (match_dup 1) (match_dup 2)))]
8361 "ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (AND, HImode, operands)"
8363 "and{w}\t{%2, %0|%0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "HI")])
8366
8367 (define_expand "andqi3"
8368 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370 (match_operand:QI 2 "general_operand" "")))
8371 (clobber (reg:CC 17))]
8372 "TARGET_QIMODE_MATH"
8373 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375 ;; %%% Potential partial reg stall on alternative 2. What to do?
8376 (define_insn "*andqi_1"
8377 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380 (clobber (reg:CC 17))]
8381 "ix86_binary_operator_ok (AND, QImode, operands)"
8382 "@
8383 and{b}\t{%2, %0|%0, %2}
8384 and{b}\t{%2, %0|%0, %2}
8385 and{l}\t{%k2, %k0|%k0, %k2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_1_slp"
8390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391 (and:QI (match_dup 0)
8392 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393 (clobber (reg:CC 17))]
8394 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396 "and{b}\t{%1, %0|%0, %1}"
8397 [(set_attr "type" "alu1")
8398 (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_2"
8401 [(set (reg 17)
8402 (compare (and:QI
8403 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405 (const_int 0)))
8406 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407 (and:QI (match_dup 1) (match_dup 2)))]
8408 "ix86_match_ccmode (insn, CCNOmode)
8409 && ix86_binary_operator_ok (AND, QImode, operands)"
8410 {
8411 if (which_alternative == 2)
8412 {
8413 if (GET_CODE (operands[2]) == CONST_INT
8414 && (INTVAL (operands[2]) & 0xffffff00))
8415 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8416 return "and{l}\t{%2, %k0|%k0, %2}";
8417 }
8418 return "and{b}\t{%2, %0|%0, %2}";
8419 }
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "QI,QI,SI")])
8422
8423 (define_insn "*andqi_2_slp"
8424 [(set (reg 17)
8425 (compare (and:QI
8426 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8427 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8428 (const_int 0)))
8429 (set (strict_low_part (match_dup 0))
8430 (and:QI (match_dup 0) (match_dup 1)))]
8431 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8432 && ix86_match_ccmode (insn, CCNOmode)
8433 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8434 "and{b}\t{%1, %0|%0, %1}"
8435 [(set_attr "type" "alu1")
8436 (set_attr "mode" "QI")])
8437
8438 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8439 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8440 ;; for a QImode operand, which of course failed.
8441
8442 (define_insn "andqi_ext_0"
8443 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444 (const_int 8)
8445 (const_int 8))
8446 (and:SI
8447 (zero_extract:SI
8448 (match_operand 1 "ext_register_operand" "0")
8449 (const_int 8)
8450 (const_int 8))
8451 (match_operand 2 "const_int_operand" "n")))
8452 (clobber (reg:CC 17))]
8453 ""
8454 "and{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "1")
8457 (set_attr "mode" "QI")])
8458
8459 ;; Generated by peephole translating test to and. This shows up
8460 ;; often in fp comparisons.
8461
8462 (define_insn "*andqi_ext_0_cc"
8463 [(set (reg 17)
8464 (compare
8465 (and:SI
8466 (zero_extract:SI
8467 (match_operand 1 "ext_register_operand" "0")
8468 (const_int 8)
8469 (const_int 8))
8470 (match_operand 2 "const_int_operand" "n"))
8471 (const_int 0)))
8472 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8473 (const_int 8)
8474 (const_int 8))
8475 (and:SI
8476 (zero_extract:SI
8477 (match_dup 1)
8478 (const_int 8)
8479 (const_int 8))
8480 (match_dup 2)))]
8481 "ix86_match_ccmode (insn, CCNOmode)"
8482 "and{b}\t{%2, %h0|%h0, %2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "length_immediate" "1")
8485 (set_attr "mode" "QI")])
8486
8487 (define_insn "*andqi_ext_1"
8488 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8489 (const_int 8)
8490 (const_int 8))
8491 (and:SI
8492 (zero_extract:SI
8493 (match_operand 1 "ext_register_operand" "0")
8494 (const_int 8)
8495 (const_int 8))
8496 (zero_extend:SI
8497 (match_operand:QI 2 "general_operand" "Qm"))))
8498 (clobber (reg:CC 17))]
8499 "!TARGET_64BIT"
8500 "and{b}\t{%2, %h0|%h0, %2}"
8501 [(set_attr "type" "alu")
8502 (set_attr "length_immediate" "0")
8503 (set_attr "mode" "QI")])
8504
8505 (define_insn "*andqi_ext_1_rex64"
8506 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8507 (const_int 8)
8508 (const_int 8))
8509 (and:SI
8510 (zero_extract:SI
8511 (match_operand 1 "ext_register_operand" "0")
8512 (const_int 8)
8513 (const_int 8))
8514 (zero_extend:SI
8515 (match_operand 2 "ext_register_operand" "Q"))))
8516 (clobber (reg:CC 17))]
8517 "TARGET_64BIT"
8518 "and{b}\t{%2, %h0|%h0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "length_immediate" "0")
8521 (set_attr "mode" "QI")])
8522
8523 (define_insn "*andqi_ext_2"
8524 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8525 (const_int 8)
8526 (const_int 8))
8527 (and:SI
8528 (zero_extract:SI
8529 (match_operand 1 "ext_register_operand" "%0")
8530 (const_int 8)
8531 (const_int 8))
8532 (zero_extract:SI
8533 (match_operand 2 "ext_register_operand" "Q")
8534 (const_int 8)
8535 (const_int 8))))
8536 (clobber (reg:CC 17))]
8537 ""
8538 "and{b}\t{%h2, %h0|%h0, %h2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "length_immediate" "0")
8541 (set_attr "mode" "QI")])
8542
8543 ;; Convert wide AND instructions with immediate operand to shorter QImode
8544 ;; equivalents when possible.
8545 ;; Don't do the splitting with memory operands, since it introduces risk
8546 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8547 ;; for size, but that can (should?) be handled by generic code instead.
8548 (define_split
8549 [(set (match_operand 0 "register_operand" "")
8550 (and (match_operand 1 "register_operand" "")
8551 (match_operand 2 "const_int_operand" "")))
8552 (clobber (reg:CC 17))]
8553 "reload_completed
8554 && QI_REG_P (operands[0])
8555 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8556 && !(~INTVAL (operands[2]) & ~(255 << 8))
8557 && GET_MODE (operands[0]) != QImode"
8558 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8559 (and:SI (zero_extract:SI (match_dup 1)
8560 (const_int 8) (const_int 8))
8561 (match_dup 2)))
8562 (clobber (reg:CC 17))])]
8563 "operands[0] = gen_lowpart (SImode, operands[0]);
8564 operands[1] = gen_lowpart (SImode, operands[1]);
8565 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8566
8567 ;; Since AND can be encoded with sign extended immediate, this is only
8568 ;; profitable when 7th bit is not set.
8569 (define_split
8570 [(set (match_operand 0 "register_operand" "")
8571 (and (match_operand 1 "general_operand" "")
8572 (match_operand 2 "const_int_operand" "")))
8573 (clobber (reg:CC 17))]
8574 "reload_completed
8575 && ANY_QI_REG_P (operands[0])
8576 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8577 && !(~INTVAL (operands[2]) & ~255)
8578 && !(INTVAL (operands[2]) & 128)
8579 && GET_MODE (operands[0]) != QImode"
8580 [(parallel [(set (strict_low_part (match_dup 0))
8581 (and:QI (match_dup 1)
8582 (match_dup 2)))
8583 (clobber (reg:CC 17))])]
8584 "operands[0] = gen_lowpart (QImode, operands[0]);
8585 operands[1] = gen_lowpart (QImode, operands[1]);
8586 operands[2] = gen_lowpart (QImode, operands[2]);")
8587 \f
8588 ;; Logical inclusive OR instructions
8589
8590 ;; %%% This used to optimize known byte-wide and operations to memory.
8591 ;; If this is considered useful, it should be done with splitters.
8592
8593 (define_expand "iordi3"
8594 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8595 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8596 (match_operand:DI 2 "x86_64_general_operand" "")))
8597 (clobber (reg:CC 17))]
8598 "TARGET_64BIT"
8599 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8600
8601 (define_insn "*iordi_1_rex64"
8602 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8603 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8604 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8605 (clobber (reg:CC 17))]
8606 "TARGET_64BIT
8607 && ix86_binary_operator_ok (IOR, DImode, operands)"
8608 "or{q}\t{%2, %0|%0, %2}"
8609 [(set_attr "type" "alu")
8610 (set_attr "mode" "DI")])
8611
8612 (define_insn "*iordi_2_rex64"
8613 [(set (reg 17)
8614 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8615 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8616 (const_int 0)))
8617 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8618 (ior:DI (match_dup 1) (match_dup 2)))]
8619 "TARGET_64BIT
8620 && ix86_match_ccmode (insn, CCNOmode)
8621 && ix86_binary_operator_ok (IOR, DImode, operands)"
8622 "or{q}\t{%2, %0|%0, %2}"
8623 [(set_attr "type" "alu")
8624 (set_attr "mode" "DI")])
8625
8626 (define_insn "*iordi_3_rex64"
8627 [(set (reg 17)
8628 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8629 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8630 (const_int 0)))
8631 (clobber (match_scratch:DI 0 "=r"))]
8632 "TARGET_64BIT
8633 && ix86_match_ccmode (insn, CCNOmode)
8634 && ix86_binary_operator_ok (IOR, DImode, operands)"
8635 "or{q}\t{%2, %0|%0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "mode" "DI")])
8638
8639
8640 (define_expand "iorsi3"
8641 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8642 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8643 (match_operand:SI 2 "general_operand" "")))
8644 (clobber (reg:CC 17))]
8645 ""
8646 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8647
8648 (define_insn "*iorsi_1"
8649 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8650 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8651 (match_operand:SI 2 "general_operand" "ri,rmi")))
8652 (clobber (reg:CC 17))]
8653 "ix86_binary_operator_ok (IOR, SImode, operands)"
8654 "or{l}\t{%2, %0|%0, %2}"
8655 [(set_attr "type" "alu")
8656 (set_attr "mode" "SI")])
8657
8658 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8659 (define_insn "*iorsi_1_zext"
8660 [(set (match_operand:DI 0 "register_operand" "=rm")
8661 (zero_extend:DI
8662 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8663 (match_operand:SI 2 "general_operand" "rim"))))
8664 (clobber (reg:CC 17))]
8665 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8666 "or{l}\t{%2, %k0|%k0, %2}"
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "SI")])
8669
8670 (define_insn "*iorsi_1_zext_imm"
8671 [(set (match_operand:DI 0 "register_operand" "=rm")
8672 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8673 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8674 (clobber (reg:CC 17))]
8675 "TARGET_64BIT"
8676 "or{l}\t{%2, %k0|%k0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "mode" "SI")])
8679
8680 (define_insn "*iorsi_2"
8681 [(set (reg 17)
8682 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8683 (match_operand:SI 2 "general_operand" "rim,ri"))
8684 (const_int 0)))
8685 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8686 (ior:SI (match_dup 1) (match_dup 2)))]
8687 "ix86_match_ccmode (insn, CCNOmode)
8688 && ix86_binary_operator_ok (IOR, SImode, operands)"
8689 "or{l}\t{%2, %0|%0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "mode" "SI")])
8692
8693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8694 ;; ??? Special case for immediate operand is missing - it is tricky.
8695 (define_insn "*iorsi_2_zext"
8696 [(set (reg 17)
8697 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8698 (match_operand:SI 2 "general_operand" "rim"))
8699 (const_int 0)))
8700 (set (match_operand:DI 0 "register_operand" "=r")
8701 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8702 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8703 && ix86_binary_operator_ok (IOR, SImode, operands)"
8704 "or{l}\t{%2, %k0|%k0, %2}"
8705 [(set_attr "type" "alu")
8706 (set_attr "mode" "SI")])
8707
8708 (define_insn "*iorsi_2_zext_imm"
8709 [(set (reg 17)
8710 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8711 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8712 (const_int 0)))
8713 (set (match_operand:DI 0 "register_operand" "=r")
8714 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8715 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8716 && ix86_binary_operator_ok (IOR, SImode, operands)"
8717 "or{l}\t{%2, %k0|%k0, %2}"
8718 [(set_attr "type" "alu")
8719 (set_attr "mode" "SI")])
8720
8721 (define_insn "*iorsi_3"
8722 [(set (reg 17)
8723 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8724 (match_operand:SI 2 "general_operand" "rim"))
8725 (const_int 0)))
8726 (clobber (match_scratch:SI 0 "=r"))]
8727 "ix86_match_ccmode (insn, CCNOmode)
8728 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8729 "or{l}\t{%2, %0|%0, %2}"
8730 [(set_attr "type" "alu")
8731 (set_attr "mode" "SI")])
8732
8733 (define_expand "iorhi3"
8734 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8735 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8736 (match_operand:HI 2 "general_operand" "")))
8737 (clobber (reg:CC 17))]
8738 "TARGET_HIMODE_MATH"
8739 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8740
8741 (define_insn "*iorhi_1"
8742 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8743 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8744 (match_operand:HI 2 "general_operand" "rmi,ri")))
8745 (clobber (reg:CC 17))]
8746 "ix86_binary_operator_ok (IOR, HImode, operands)"
8747 "or{w}\t{%2, %0|%0, %2}"
8748 [(set_attr "type" "alu")
8749 (set_attr "mode" "HI")])
8750
8751 (define_insn "*iorhi_2"
8752 [(set (reg 17)
8753 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8754 (match_operand:HI 2 "general_operand" "rim,ri"))
8755 (const_int 0)))
8756 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8757 (ior:HI (match_dup 1) (match_dup 2)))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && ix86_binary_operator_ok (IOR, HImode, operands)"
8760 "or{w}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "HI")])
8763
8764 (define_insn "*iorhi_3"
8765 [(set (reg 17)
8766 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8767 (match_operand:HI 2 "general_operand" "rim"))
8768 (const_int 0)))
8769 (clobber (match_scratch:HI 0 "=r"))]
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8772 "or{w}\t{%2, %0|%0, %2}"
8773 [(set_attr "type" "alu")
8774 (set_attr "mode" "HI")])
8775
8776 (define_expand "iorqi3"
8777 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8778 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8779 (match_operand:QI 2 "general_operand" "")))
8780 (clobber (reg:CC 17))]
8781 "TARGET_QIMODE_MATH"
8782 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8783
8784 ;; %%% Potential partial reg stall on alternative 2. What to do?
8785 (define_insn "*iorqi_1"
8786 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8787 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8788 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8789 (clobber (reg:CC 17))]
8790 "ix86_binary_operator_ok (IOR, QImode, operands)"
8791 "@
8792 or{b}\t{%2, %0|%0, %2}
8793 or{b}\t{%2, %0|%0, %2}
8794 or{l}\t{%k2, %k0|%k0, %k2}"
8795 [(set_attr "type" "alu")
8796 (set_attr "mode" "QI,QI,SI")])
8797
8798 (define_insn "*iorqi_1_slp"
8799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8800 (ior:QI (match_dup 0)
8801 (match_operand:QI 1 "general_operand" "qmi,qi")))
8802 (clobber (reg:CC 17))]
8803 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8804 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8805 "or{b}\t{%1, %0|%0, %1}"
8806 [(set_attr "type" "alu1")
8807 (set_attr "mode" "QI")])
8808
8809 (define_insn "*iorqi_2"
8810 [(set (reg 17)
8811 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8812 (match_operand:QI 2 "general_operand" "qim,qi"))
8813 (const_int 0)))
8814 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8815 (ior:QI (match_dup 1) (match_dup 2)))]
8816 "ix86_match_ccmode (insn, CCNOmode)
8817 && ix86_binary_operator_ok (IOR, QImode, operands)"
8818 "or{b}\t{%2, %0|%0, %2}"
8819 [(set_attr "type" "alu")
8820 (set_attr "mode" "QI")])
8821
8822 (define_insn "*iorqi_2_slp"
8823 [(set (reg 17)
8824 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8825 (match_operand:QI 1 "general_operand" "qim,qi"))
8826 (const_int 0)))
8827 (set (strict_low_part (match_dup 0))
8828 (ior:QI (match_dup 0) (match_dup 1)))]
8829 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8830 && ix86_match_ccmode (insn, CCNOmode)
8831 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8832 "or{b}\t{%1, %0|%0, %1}"
8833 [(set_attr "type" "alu1")
8834 (set_attr "mode" "QI")])
8835
8836 (define_insn "*iorqi_3"
8837 [(set (reg 17)
8838 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8839 (match_operand:QI 2 "general_operand" "qim"))
8840 (const_int 0)))
8841 (clobber (match_scratch:QI 0 "=q"))]
8842 "ix86_match_ccmode (insn, CCNOmode)
8843 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8844 "or{b}\t{%2, %0|%0, %2}"
8845 [(set_attr "type" "alu")
8846 (set_attr "mode" "QI")])
8847
8848 (define_insn "iorqi_ext_0"
8849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8850 (const_int 8)
8851 (const_int 8))
8852 (ior:SI
8853 (zero_extract:SI
8854 (match_operand 1 "ext_register_operand" "0")
8855 (const_int 8)
8856 (const_int 8))
8857 (match_operand 2 "const_int_operand" "n")))
8858 (clobber (reg:CC 17))]
8859 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8860 "or{b}\t{%2, %h0|%h0, %2}"
8861 [(set_attr "type" "alu")
8862 (set_attr "length_immediate" "1")
8863 (set_attr "mode" "QI")])
8864
8865 (define_insn "*iorqi_ext_1"
8866 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8867 (const_int 8)
8868 (const_int 8))
8869 (ior:SI
8870 (zero_extract:SI
8871 (match_operand 1 "ext_register_operand" "0")
8872 (const_int 8)
8873 (const_int 8))
8874 (zero_extend:SI
8875 (match_operand:QI 2 "general_operand" "Qm"))))
8876 (clobber (reg:CC 17))]
8877 "!TARGET_64BIT
8878 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8879 "or{b}\t{%2, %h0|%h0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "length_immediate" "0")
8882 (set_attr "mode" "QI")])
8883
8884 (define_insn "*iorqi_ext_1_rex64"
8885 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8886 (const_int 8)
8887 (const_int 8))
8888 (ior:SI
8889 (zero_extract:SI
8890 (match_operand 1 "ext_register_operand" "0")
8891 (const_int 8)
8892 (const_int 8))
8893 (zero_extend:SI
8894 (match_operand 2 "ext_register_operand" "Q"))))
8895 (clobber (reg:CC 17))]
8896 "TARGET_64BIT
8897 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8898 "or{b}\t{%2, %h0|%h0, %2}"
8899 [(set_attr "type" "alu")
8900 (set_attr "length_immediate" "0")
8901 (set_attr "mode" "QI")])
8902
8903 (define_insn "*iorqi_ext_2"
8904 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8905 (const_int 8)
8906 (const_int 8))
8907 (ior:SI
8908 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8909 (const_int 8)
8910 (const_int 8))
8911 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8912 (const_int 8)
8913 (const_int 8))))
8914 (clobber (reg:CC 17))]
8915 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8916 "ior{b}\t{%h2, %h0|%h0, %h2}"
8917 [(set_attr "type" "alu")
8918 (set_attr "length_immediate" "0")
8919 (set_attr "mode" "QI")])
8920
8921 (define_split
8922 [(set (match_operand 0 "register_operand" "")
8923 (ior (match_operand 1 "register_operand" "")
8924 (match_operand 2 "const_int_operand" "")))
8925 (clobber (reg:CC 17))]
8926 "reload_completed
8927 && QI_REG_P (operands[0])
8928 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8929 && !(INTVAL (operands[2]) & ~(255 << 8))
8930 && GET_MODE (operands[0]) != QImode"
8931 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8932 (ior:SI (zero_extract:SI (match_dup 1)
8933 (const_int 8) (const_int 8))
8934 (match_dup 2)))
8935 (clobber (reg:CC 17))])]
8936 "operands[0] = gen_lowpart (SImode, operands[0]);
8937 operands[1] = gen_lowpart (SImode, operands[1]);
8938 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8939
8940 ;; Since OR can be encoded with sign extended immediate, this is only
8941 ;; profitable when 7th bit is set.
8942 (define_split
8943 [(set (match_operand 0 "register_operand" "")
8944 (ior (match_operand 1 "general_operand" "")
8945 (match_operand 2 "const_int_operand" "")))
8946 (clobber (reg:CC 17))]
8947 "reload_completed
8948 && ANY_QI_REG_P (operands[0])
8949 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8950 && !(INTVAL (operands[2]) & ~255)
8951 && (INTVAL (operands[2]) & 128)
8952 && GET_MODE (operands[0]) != QImode"
8953 [(parallel [(set (strict_low_part (match_dup 0))
8954 (ior:QI (match_dup 1)
8955 (match_dup 2)))
8956 (clobber (reg:CC 17))])]
8957 "operands[0] = gen_lowpart (QImode, operands[0]);
8958 operands[1] = gen_lowpart (QImode, operands[1]);
8959 operands[2] = gen_lowpart (QImode, operands[2]);")
8960 \f
8961 ;; Logical XOR instructions
8962
8963 ;; %%% This used to optimize known byte-wide and operations to memory.
8964 ;; If this is considered useful, it should be done with splitters.
8965
8966 (define_expand "xordi3"
8967 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8968 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8969 (match_operand:DI 2 "x86_64_general_operand" "")))
8970 (clobber (reg:CC 17))]
8971 "TARGET_64BIT"
8972 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8973
8974 (define_insn "*xordi_1_rex64"
8975 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8976 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8977 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8978 (clobber (reg:CC 17))]
8979 "TARGET_64BIT
8980 && ix86_binary_operator_ok (XOR, DImode, operands)"
8981 "@
8982 xor{q}\t{%2, %0|%0, %2}
8983 xor{q}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "DI,DI")])
8986
8987 (define_insn "*xordi_2_rex64"
8988 [(set (reg 17)
8989 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8990 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8991 (const_int 0)))
8992 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8993 (xor:DI (match_dup 1) (match_dup 2)))]
8994 "TARGET_64BIT
8995 && ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (XOR, DImode, operands)"
8997 "@
8998 xor{q}\t{%2, %0|%0, %2}
8999 xor{q}\t{%2, %0|%0, %2}"
9000 [(set_attr "type" "alu")
9001 (set_attr "mode" "DI,DI")])
9002
9003 (define_insn "*xordi_3_rex64"
9004 [(set (reg 17)
9005 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9006 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9007 (const_int 0)))
9008 (clobber (match_scratch:DI 0 "=r"))]
9009 "TARGET_64BIT
9010 && ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_binary_operator_ok (XOR, DImode, operands)"
9012 "xor{q}\t{%2, %0|%0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "DI")])
9015
9016 (define_expand "xorsi3"
9017 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9018 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9019 (match_operand:SI 2 "general_operand" "")))
9020 (clobber (reg:CC 17))]
9021 ""
9022 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9023
9024 (define_insn "*xorsi_1"
9025 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9026 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9027 (match_operand:SI 2 "general_operand" "ri,rm")))
9028 (clobber (reg:CC 17))]
9029 "ix86_binary_operator_ok (XOR, SImode, operands)"
9030 "xor{l}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "SI")])
9033
9034 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9035 ;; Add speccase for immediates
9036 (define_insn "*xorsi_1_zext"
9037 [(set (match_operand:DI 0 "register_operand" "=r")
9038 (zero_extend:DI
9039 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9040 (match_operand:SI 2 "general_operand" "rim"))))
9041 (clobber (reg:CC 17))]
9042 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9043 "xor{l}\t{%2, %k0|%k0, %2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "mode" "SI")])
9046
9047 (define_insn "*xorsi_1_zext_imm"
9048 [(set (match_operand:DI 0 "register_operand" "=r")
9049 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9050 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9051 (clobber (reg:CC 17))]
9052 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9053 "xor{l}\t{%2, %k0|%k0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "SI")])
9056
9057 (define_insn "*xorsi_2"
9058 [(set (reg 17)
9059 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9060 (match_operand:SI 2 "general_operand" "rim,ri"))
9061 (const_int 0)))
9062 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9063 (xor:SI (match_dup 1) (match_dup 2)))]
9064 "ix86_match_ccmode (insn, CCNOmode)
9065 && ix86_binary_operator_ok (XOR, SImode, operands)"
9066 "xor{l}\t{%2, %0|%0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9069
9070 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9071 ;; ??? Special case for immediate operand is missing - it is tricky.
9072 (define_insn "*xorsi_2_zext"
9073 [(set (reg 17)
9074 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9075 (match_operand:SI 2 "general_operand" "rim"))
9076 (const_int 0)))
9077 (set (match_operand:DI 0 "register_operand" "=r")
9078 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9079 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9080 && ix86_binary_operator_ok (XOR, SImode, operands)"
9081 "xor{l}\t{%2, %k0|%k0, %2}"
9082 [(set_attr "type" "alu")
9083 (set_attr "mode" "SI")])
9084
9085 (define_insn "*xorsi_2_zext_imm"
9086 [(set (reg 17)
9087 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9088 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9089 (const_int 0)))
9090 (set (match_operand:DI 0 "register_operand" "=r")
9091 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9093 && ix86_binary_operator_ok (XOR, SImode, operands)"
9094 "xor{l}\t{%2, %k0|%k0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "mode" "SI")])
9097
9098 (define_insn "*xorsi_3"
9099 [(set (reg 17)
9100 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9101 (match_operand:SI 2 "general_operand" "rim"))
9102 (const_int 0)))
9103 (clobber (match_scratch:SI 0 "=r"))]
9104 "ix86_match_ccmode (insn, CCNOmode)
9105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9106 "xor{l}\t{%2, %0|%0, %2}"
9107 [(set_attr "type" "alu")
9108 (set_attr "mode" "SI")])
9109
9110 (define_expand "xorhi3"
9111 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9112 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9113 (match_operand:HI 2 "general_operand" "")))
9114 (clobber (reg:CC 17))]
9115 "TARGET_HIMODE_MATH"
9116 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9117
9118 (define_insn "*xorhi_1"
9119 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9120 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9121 (match_operand:HI 2 "general_operand" "rmi,ri")))
9122 (clobber (reg:CC 17))]
9123 "ix86_binary_operator_ok (XOR, HImode, operands)"
9124 "xor{w}\t{%2, %0|%0, %2}"
9125 [(set_attr "type" "alu")
9126 (set_attr "mode" "HI")])
9127
9128 (define_insn "*xorhi_2"
9129 [(set (reg 17)
9130 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9131 (match_operand:HI 2 "general_operand" "rim,ri"))
9132 (const_int 0)))
9133 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9134 (xor:HI (match_dup 1) (match_dup 2)))]
9135 "ix86_match_ccmode (insn, CCNOmode)
9136 && ix86_binary_operator_ok (XOR, HImode, operands)"
9137 "xor{w}\t{%2, %0|%0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "mode" "HI")])
9140
9141 (define_insn "*xorhi_3"
9142 [(set (reg 17)
9143 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9144 (match_operand:HI 2 "general_operand" "rim"))
9145 (const_int 0)))
9146 (clobber (match_scratch:HI 0 "=r"))]
9147 "ix86_match_ccmode (insn, CCNOmode)
9148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9149 "xor{w}\t{%2, %0|%0, %2}"
9150 [(set_attr "type" "alu")
9151 (set_attr "mode" "HI")])
9152
9153 (define_expand "xorqi3"
9154 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9155 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9156 (match_operand:QI 2 "general_operand" "")))
9157 (clobber (reg:CC 17))]
9158 "TARGET_QIMODE_MATH"
9159 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9160
9161 ;; %%% Potential partial reg stall on alternative 2. What to do?
9162 (define_insn "*xorqi_1"
9163 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9164 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9165 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9166 (clobber (reg:CC 17))]
9167 "ix86_binary_operator_ok (XOR, QImode, operands)"
9168 "@
9169 xor{b}\t{%2, %0|%0, %2}
9170 xor{b}\t{%2, %0|%0, %2}
9171 xor{l}\t{%k2, %k0|%k0, %k2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "mode" "QI,QI,SI")])
9174
9175 (define_insn "*xorqi_1_slp"
9176 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9177 (xor:QI (match_dup 0)
9178 (match_operand:QI 1 "general_operand" "qi,qmi")))
9179 (clobber (reg:CC 17))]
9180 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9181 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9182 "xor{b}\t{%1, %0|%0, %1}"
9183 [(set_attr "type" "alu1")
9184 (set_attr "mode" "QI")])
9185
9186 (define_insn "xorqi_ext_0"
9187 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9188 (const_int 8)
9189 (const_int 8))
9190 (xor:SI
9191 (zero_extract:SI
9192 (match_operand 1 "ext_register_operand" "0")
9193 (const_int 8)
9194 (const_int 8))
9195 (match_operand 2 "const_int_operand" "n")))
9196 (clobber (reg:CC 17))]
9197 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9198 "xor{b}\t{%2, %h0|%h0, %2}"
9199 [(set_attr "type" "alu")
9200 (set_attr "length_immediate" "1")
9201 (set_attr "mode" "QI")])
9202
9203 (define_insn "*xorqi_ext_1"
9204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9205 (const_int 8)
9206 (const_int 8))
9207 (xor:SI
9208 (zero_extract:SI
9209 (match_operand 1 "ext_register_operand" "0")
9210 (const_int 8)
9211 (const_int 8))
9212 (zero_extend:SI
9213 (match_operand:QI 2 "general_operand" "Qm"))))
9214 (clobber (reg:CC 17))]
9215 "!TARGET_64BIT
9216 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9217 "xor{b}\t{%2, %h0|%h0, %2}"
9218 [(set_attr "type" "alu")
9219 (set_attr "length_immediate" "0")
9220 (set_attr "mode" "QI")])
9221
9222 (define_insn "*xorqi_ext_1_rex64"
9223 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9224 (const_int 8)
9225 (const_int 8))
9226 (xor:SI
9227 (zero_extract:SI
9228 (match_operand 1 "ext_register_operand" "0")
9229 (const_int 8)
9230 (const_int 8))
9231 (zero_extend:SI
9232 (match_operand 2 "ext_register_operand" "Q"))))
9233 (clobber (reg:CC 17))]
9234 "TARGET_64BIT
9235 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9236 "xor{b}\t{%2, %h0|%h0, %2}"
9237 [(set_attr "type" "alu")
9238 (set_attr "length_immediate" "0")
9239 (set_attr "mode" "QI")])
9240
9241 (define_insn "*xorqi_ext_2"
9242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9243 (const_int 8)
9244 (const_int 8))
9245 (xor:SI
9246 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9247 (const_int 8)
9248 (const_int 8))
9249 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9250 (const_int 8)
9251 (const_int 8))))
9252 (clobber (reg:CC 17))]
9253 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9254 "xor{b}\t{%h2, %h0|%h0, %h2}"
9255 [(set_attr "type" "alu")
9256 (set_attr "length_immediate" "0")
9257 (set_attr "mode" "QI")])
9258
9259 (define_insn "*xorqi_cc_1"
9260 [(set (reg 17)
9261 (compare
9262 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9263 (match_operand:QI 2 "general_operand" "qim,qi"))
9264 (const_int 0)))
9265 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9266 (xor:QI (match_dup 1) (match_dup 2)))]
9267 "ix86_match_ccmode (insn, CCNOmode)
9268 && ix86_binary_operator_ok (XOR, QImode, operands)"
9269 "xor{b}\t{%2, %0|%0, %2}"
9270 [(set_attr "type" "alu")
9271 (set_attr "mode" "QI")])
9272
9273 (define_insn "*xorqi_2_slp"
9274 [(set (reg 17)
9275 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9276 (match_operand:QI 1 "general_operand" "qim,qi"))
9277 (const_int 0)))
9278 (set (strict_low_part (match_dup 0))
9279 (xor:QI (match_dup 0) (match_dup 1)))]
9280 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9281 && ix86_match_ccmode (insn, CCNOmode)
9282 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9283 "xor{b}\t{%1, %0|%0, %1}"
9284 [(set_attr "type" "alu1")
9285 (set_attr "mode" "QI")])
9286
9287 (define_insn "*xorqi_cc_2"
9288 [(set (reg 17)
9289 (compare
9290 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9291 (match_operand:QI 2 "general_operand" "qim"))
9292 (const_int 0)))
9293 (clobber (match_scratch:QI 0 "=q"))]
9294 "ix86_match_ccmode (insn, CCNOmode)
9295 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9296 "xor{b}\t{%2, %0|%0, %2}"
9297 [(set_attr "type" "alu")
9298 (set_attr "mode" "QI")])
9299
9300 (define_insn "*xorqi_cc_ext_1"
9301 [(set (reg 17)
9302 (compare
9303 (xor:SI
9304 (zero_extract:SI
9305 (match_operand 1 "ext_register_operand" "0")
9306 (const_int 8)
9307 (const_int 8))
9308 (match_operand:QI 2 "general_operand" "qmn"))
9309 (const_int 0)))
9310 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9311 (const_int 8)
9312 (const_int 8))
9313 (xor:SI
9314 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9315 (match_dup 2)))]
9316 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9317 "xor{b}\t{%2, %h0|%h0, %2}"
9318 [(set_attr "type" "alu")
9319 (set_attr "mode" "QI")])
9320
9321 (define_insn "*xorqi_cc_ext_1_rex64"
9322 [(set (reg 17)
9323 (compare
9324 (xor:SI
9325 (zero_extract:SI
9326 (match_operand 1 "ext_register_operand" "0")
9327 (const_int 8)
9328 (const_int 8))
9329 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9330 (const_int 0)))
9331 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9332 (const_int 8)
9333 (const_int 8))
9334 (xor:SI
9335 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9336 (match_dup 2)))]
9337 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9338 "xor{b}\t{%2, %h0|%h0, %2}"
9339 [(set_attr "type" "alu")
9340 (set_attr "mode" "QI")])
9341
9342 (define_expand "xorqi_cc_ext_1"
9343 [(parallel [
9344 (set (reg:CCNO 17)
9345 (compare:CCNO
9346 (xor:SI
9347 (zero_extract:SI
9348 (match_operand 1 "ext_register_operand" "")
9349 (const_int 8)
9350 (const_int 8))
9351 (match_operand:QI 2 "general_operand" ""))
9352 (const_int 0)))
9353 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9354 (const_int 8)
9355 (const_int 8))
9356 (xor:SI
9357 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9358 (match_dup 2)))])]
9359 ""
9360 "")
9361
9362 (define_split
9363 [(set (match_operand 0 "register_operand" "")
9364 (xor (match_operand 1 "register_operand" "")
9365 (match_operand 2 "const_int_operand" "")))
9366 (clobber (reg:CC 17))]
9367 "reload_completed
9368 && QI_REG_P (operands[0])
9369 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9370 && !(INTVAL (operands[2]) & ~(255 << 8))
9371 && GET_MODE (operands[0]) != QImode"
9372 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9373 (xor:SI (zero_extract:SI (match_dup 1)
9374 (const_int 8) (const_int 8))
9375 (match_dup 2)))
9376 (clobber (reg:CC 17))])]
9377 "operands[0] = gen_lowpart (SImode, operands[0]);
9378 operands[1] = gen_lowpart (SImode, operands[1]);
9379 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9380
9381 ;; Since XOR can be encoded with sign extended immediate, this is only
9382 ;; profitable when 7th bit is set.
9383 (define_split
9384 [(set (match_operand 0 "register_operand" "")
9385 (xor (match_operand 1 "general_operand" "")
9386 (match_operand 2 "const_int_operand" "")))
9387 (clobber (reg:CC 17))]
9388 "reload_completed
9389 && ANY_QI_REG_P (operands[0])
9390 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9391 && !(INTVAL (operands[2]) & ~255)
9392 && (INTVAL (operands[2]) & 128)
9393 && GET_MODE (operands[0]) != QImode"
9394 [(parallel [(set (strict_low_part (match_dup 0))
9395 (xor:QI (match_dup 1)
9396 (match_dup 2)))
9397 (clobber (reg:CC 17))])]
9398 "operands[0] = gen_lowpart (QImode, operands[0]);
9399 operands[1] = gen_lowpart (QImode, operands[1]);
9400 operands[2] = gen_lowpart (QImode, operands[2]);")
9401 \f
9402 ;; Negation instructions
9403
9404 (define_expand "negdi2"
9405 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9406 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9407 (clobber (reg:CC 17))])]
9408 ""
9409 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9410
9411 (define_insn "*negdi2_1"
9412 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9413 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9414 (clobber (reg:CC 17))]
9415 "!TARGET_64BIT
9416 && ix86_unary_operator_ok (NEG, DImode, operands)"
9417 "#")
9418
9419 (define_split
9420 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9421 (neg:DI (match_operand:DI 1 "general_operand" "")))
9422 (clobber (reg:CC 17))]
9423 "!TARGET_64BIT && reload_completed"
9424 [(parallel
9425 [(set (reg:CCZ 17)
9426 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9427 (set (match_dup 0) (neg:SI (match_dup 2)))])
9428 (parallel
9429 [(set (match_dup 1)
9430 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9431 (match_dup 3))
9432 (const_int 0)))
9433 (clobber (reg:CC 17))])
9434 (parallel
9435 [(set (match_dup 1)
9436 (neg:SI (match_dup 1)))
9437 (clobber (reg:CC 17))])]
9438 "split_di (operands+1, 1, operands+2, operands+3);
9439 split_di (operands+0, 1, operands+0, operands+1);")
9440
9441 (define_insn "*negdi2_1_rex64"
9442 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9443 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9444 (clobber (reg:CC 17))]
9445 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9446 "neg{q}\t%0"
9447 [(set_attr "type" "negnot")
9448 (set_attr "mode" "DI")])
9449
9450 ;; The problem with neg is that it does not perform (compare x 0),
9451 ;; it really performs (compare 0 x), which leaves us with the zero
9452 ;; flag being the only useful item.
9453
9454 (define_insn "*negdi2_cmpz_rex64"
9455 [(set (reg:CCZ 17)
9456 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9457 (const_int 0)))
9458 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9459 (neg:DI (match_dup 1)))]
9460 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9461 "neg{q}\t%0"
9462 [(set_attr "type" "negnot")
9463 (set_attr "mode" "DI")])
9464
9465
9466 (define_expand "negsi2"
9467 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9468 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9469 (clobber (reg:CC 17))])]
9470 ""
9471 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9472
9473 (define_insn "*negsi2_1"
9474 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9475 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9476 (clobber (reg:CC 17))]
9477 "ix86_unary_operator_ok (NEG, SImode, operands)"
9478 "neg{l}\t%0"
9479 [(set_attr "type" "negnot")
9480 (set_attr "mode" "SI")])
9481
9482 ;; Combine is quite creative about this pattern.
9483 (define_insn "*negsi2_1_zext"
9484 [(set (match_operand:DI 0 "register_operand" "=r")
9485 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9486 (const_int 32)))
9487 (const_int 32)))
9488 (clobber (reg:CC 17))]
9489 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9490 "neg{l}\t%k0"
9491 [(set_attr "type" "negnot")
9492 (set_attr "mode" "SI")])
9493
9494 ;; The problem with neg is that it does not perform (compare x 0),
9495 ;; it really performs (compare 0 x), which leaves us with the zero
9496 ;; flag being the only useful item.
9497
9498 (define_insn "*negsi2_cmpz"
9499 [(set (reg:CCZ 17)
9500 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9501 (const_int 0)))
9502 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9503 (neg:SI (match_dup 1)))]
9504 "ix86_unary_operator_ok (NEG, SImode, operands)"
9505 "neg{l}\t%0"
9506 [(set_attr "type" "negnot")
9507 (set_attr "mode" "SI")])
9508
9509 (define_insn "*negsi2_cmpz_zext"
9510 [(set (reg:CCZ 17)
9511 (compare:CCZ (lshiftrt:DI
9512 (neg:DI (ashift:DI
9513 (match_operand:DI 1 "register_operand" "0")
9514 (const_int 32)))
9515 (const_int 32))
9516 (const_int 0)))
9517 (set (match_operand:DI 0 "register_operand" "=r")
9518 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9519 (const_int 32)))
9520 (const_int 32)))]
9521 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9522 "neg{l}\t%k0"
9523 [(set_attr "type" "negnot")
9524 (set_attr "mode" "SI")])
9525
9526 (define_expand "neghi2"
9527 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9528 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9529 (clobber (reg:CC 17))])]
9530 "TARGET_HIMODE_MATH"
9531 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9532
9533 (define_insn "*neghi2_1"
9534 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9535 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9536 (clobber (reg:CC 17))]
9537 "ix86_unary_operator_ok (NEG, HImode, operands)"
9538 "neg{w}\t%0"
9539 [(set_attr "type" "negnot")
9540 (set_attr "mode" "HI")])
9541
9542 (define_insn "*neghi2_cmpz"
9543 [(set (reg:CCZ 17)
9544 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9545 (const_int 0)))
9546 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9547 (neg:HI (match_dup 1)))]
9548 "ix86_unary_operator_ok (NEG, HImode, operands)"
9549 "neg{w}\t%0"
9550 [(set_attr "type" "negnot")
9551 (set_attr "mode" "HI")])
9552
9553 (define_expand "negqi2"
9554 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9555 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9556 (clobber (reg:CC 17))])]
9557 "TARGET_QIMODE_MATH"
9558 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9559
9560 (define_insn "*negqi2_1"
9561 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9562 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9563 (clobber (reg:CC 17))]
9564 "ix86_unary_operator_ok (NEG, QImode, operands)"
9565 "neg{b}\t%0"
9566 [(set_attr "type" "negnot")
9567 (set_attr "mode" "QI")])
9568
9569 (define_insn "*negqi2_cmpz"
9570 [(set (reg:CCZ 17)
9571 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9572 (const_int 0)))
9573 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9574 (neg:QI (match_dup 1)))]
9575 "ix86_unary_operator_ok (NEG, QImode, operands)"
9576 "neg{b}\t%0"
9577 [(set_attr "type" "negnot")
9578 (set_attr "mode" "QI")])
9579
9580 ;; Changing of sign for FP values is doable using integer unit too.
9581
9582 (define_expand "negsf2"
9583 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9584 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9585 (clobber (reg:CC 17))])]
9586 "TARGET_80387"
9587 "if (TARGET_SSE)
9588 {
9589 /* In case operand is in memory, we will not use SSE. */
9590 if (memory_operand (operands[0], VOIDmode)
9591 && rtx_equal_p (operands[0], operands[1]))
9592 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9593 else
9594 {
9595 /* Using SSE is tricky, since we need bitwise negation of -0
9596 in register. */
9597 rtx reg = gen_reg_rtx (SFmode);
9598 rtx dest = operands[0];
9599 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9600
9601 operands[1] = force_reg (SFmode, operands[1]);
9602 operands[0] = force_reg (SFmode, operands[0]);
9603 reg = force_reg (V4SFmode,
9604 gen_rtx_CONST_VECTOR (V4SFmode,
9605 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9606 CONST0_RTX (SFmode),
9607 CONST0_RTX (SFmode))));
9608 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9609 if (dest != operands[0])
9610 emit_move_insn (dest, operands[0]);
9611 }
9612 DONE;
9613 }
9614 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9615
9616 (define_insn "negsf2_memory"
9617 [(set (match_operand:SF 0 "memory_operand" "=m")
9618 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9619 (clobber (reg:CC 17))]
9620 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9621 "#")
9622
9623 (define_insn "negsf2_ifs"
9624 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9625 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9626 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9627 (clobber (reg:CC 17))]
9628 "TARGET_SSE
9629 && (reload_in_progress || reload_completed
9630 || (register_operand (operands[0], VOIDmode)
9631 && register_operand (operands[1], VOIDmode)))"
9632 "#")
9633
9634 (define_split
9635 [(set (match_operand:SF 0 "memory_operand" "")
9636 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9637 (use (match_operand:SF 2 "" ""))
9638 (clobber (reg:CC 17))]
9639 ""
9640 [(parallel [(set (match_dup 0)
9641 (neg:SF (match_dup 1)))
9642 (clobber (reg:CC 17))])])
9643
9644 (define_split
9645 [(set (match_operand:SF 0 "register_operand" "")
9646 (neg:SF (match_operand:SF 1 "register_operand" "")))
9647 (use (match_operand:V4SF 2 "" ""))
9648 (clobber (reg:CC 17))]
9649 "reload_completed && !SSE_REG_P (operands[0])"
9650 [(parallel [(set (match_dup 0)
9651 (neg:SF (match_dup 1)))
9652 (clobber (reg:CC 17))])])
9653
9654 (define_split
9655 [(set (match_operand:SF 0 "register_operand" "")
9656 (neg:SF (match_operand:SF 1 "register_operand" "")))
9657 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9658 (clobber (reg:CC 17))]
9659 "reload_completed && SSE_REG_P (operands[0])"
9660 [(set (match_dup 0)
9661 (xor:V4SF (match_dup 1)
9662 (match_dup 2)))]
9663 {
9664 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9665 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9666 if (operands_match_p (operands[0], operands[2]))
9667 {
9668 rtx tmp;
9669 tmp = operands[1];
9670 operands[1] = operands[2];
9671 operands[2] = tmp;
9672 }
9673 })
9674
9675
9676 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9677 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9678 ;; to itself.
9679 (define_insn "*negsf2_if"
9680 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9681 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9682 (clobber (reg:CC 17))]
9683 "TARGET_80387 && !TARGET_SSE
9684 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9685 "#")
9686
9687 (define_split
9688 [(set (match_operand:SF 0 "fp_register_operand" "")
9689 (neg:SF (match_operand:SF 1 "register_operand" "")))
9690 (clobber (reg:CC 17))]
9691 "TARGET_80387 && reload_completed"
9692 [(set (match_dup 0)
9693 (neg:SF (match_dup 1)))]
9694 "")
9695
9696 (define_split
9697 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9698 (neg:SF (match_operand:SF 1 "register_operand" "")))
9699 (clobber (reg:CC 17))]
9700 "TARGET_80387 && reload_completed"
9701 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9702 (clobber (reg:CC 17))])]
9703 "operands[1] = gen_int_mode (0x80000000, SImode);
9704 operands[0] = gen_lowpart (SImode, operands[0]);")
9705
9706 (define_split
9707 [(set (match_operand 0 "memory_operand" "")
9708 (neg (match_operand 1 "memory_operand" "")))
9709 (clobber (reg:CC 17))]
9710 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9711 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9712 (clobber (reg:CC 17))])]
9713 {
9714 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9715
9716 if (GET_MODE (operands[1]) == XFmode)
9717 size = 10;
9718 operands[0] = adjust_address (operands[0], QImode, size - 1);
9719 operands[1] = gen_int_mode (0x80, QImode);
9720 })
9721
9722 (define_expand "negdf2"
9723 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9724 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9725 (clobber (reg:CC 17))])]
9726 "TARGET_80387"
9727 "if (TARGET_SSE2)
9728 {
9729 /* In case operand is in memory, we will not use SSE. */
9730 if (memory_operand (operands[0], VOIDmode)
9731 && rtx_equal_p (operands[0], operands[1]))
9732 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9733 else
9734 {
9735 /* Using SSE is tricky, since we need bitwise negation of -0
9736 in register. */
9737 rtx reg;
9738 #if HOST_BITS_PER_WIDE_INT >= 64
9739 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9740 #else
9741 rtx imm = immed_double_const (0, 0x80000000, DImode);
9742 #endif
9743 rtx dest = operands[0];
9744
9745 operands[1] = force_reg (DFmode, operands[1]);
9746 operands[0] = force_reg (DFmode, operands[0]);
9747 imm = gen_lowpart (DFmode, imm);
9748 reg = force_reg (V2DFmode,
9749 gen_rtx_CONST_VECTOR (V2DFmode,
9750 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9751 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9752 if (dest != operands[0])
9753 emit_move_insn (dest, operands[0]);
9754 }
9755 DONE;
9756 }
9757 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9758
9759 (define_insn "negdf2_memory"
9760 [(set (match_operand:DF 0 "memory_operand" "=m")
9761 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9762 (clobber (reg:CC 17))]
9763 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9764 "#")
9765
9766 (define_insn "negdf2_ifs"
9767 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9768 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9769 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9770 (clobber (reg:CC 17))]
9771 "!TARGET_64BIT && TARGET_SSE2
9772 && (reload_in_progress || reload_completed
9773 || (register_operand (operands[0], VOIDmode)
9774 && register_operand (operands[1], VOIDmode)))"
9775 "#")
9776
9777 (define_insn "*negdf2_ifs_rex64"
9778 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9779 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9780 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9781 (clobber (reg:CC 17))]
9782 "TARGET_64BIT && TARGET_SSE2
9783 && (reload_in_progress || reload_completed
9784 || (register_operand (operands[0], VOIDmode)
9785 && register_operand (operands[1], VOIDmode)))"
9786 "#")
9787
9788 (define_split
9789 [(set (match_operand:DF 0 "memory_operand" "")
9790 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9791 (use (match_operand:V2DF 2 "" ""))
9792 (clobber (reg:CC 17))]
9793 ""
9794 [(parallel [(set (match_dup 0)
9795 (neg:DF (match_dup 1)))
9796 (clobber (reg:CC 17))])])
9797
9798 (define_split
9799 [(set (match_operand:DF 0 "register_operand" "")
9800 (neg:DF (match_operand:DF 1 "register_operand" "")))
9801 (use (match_operand:V2DF 2 "" ""))
9802 (clobber (reg:CC 17))]
9803 "reload_completed && !SSE_REG_P (operands[0])
9804 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9805 [(parallel [(set (match_dup 0)
9806 (neg:DF (match_dup 1)))
9807 (clobber (reg:CC 17))])])
9808
9809 (define_split
9810 [(set (match_operand:DF 0 "register_operand" "")
9811 (neg:DF (match_operand:DF 1 "register_operand" "")))
9812 (use (match_operand:V2DF 2 "" ""))
9813 (clobber (reg:CC 17))]
9814 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9815 [(parallel [(set (match_dup 0)
9816 (xor:DI (match_dup 1) (match_dup 2)))
9817 (clobber (reg:CC 17))])]
9818 "operands[0] = gen_lowpart (DImode, operands[0]);
9819 operands[1] = gen_lowpart (DImode, operands[1]);
9820 operands[2] = gen_lowpart (DImode, operands[2]);")
9821
9822 (define_split
9823 [(set (match_operand:DF 0 "register_operand" "")
9824 (neg:DF (match_operand:DF 1 "register_operand" "")))
9825 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9826 (clobber (reg:CC 17))]
9827 "reload_completed && SSE_REG_P (operands[0])"
9828 [(set (match_dup 0)
9829 (xor:V2DF (match_dup 1)
9830 (match_dup 2)))]
9831 {
9832 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9833 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9834 /* Avoid possible reformatting on the operands. */
9835 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9836 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9837 if (operands_match_p (operands[0], operands[2]))
9838 {
9839 rtx tmp;
9840 tmp = operands[1];
9841 operands[1] = operands[2];
9842 operands[2] = tmp;
9843 }
9844 })
9845
9846 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9847 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9848 ;; to itself.
9849 (define_insn "*negdf2_if"
9850 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9851 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9852 (clobber (reg:CC 17))]
9853 "!TARGET_64BIT && TARGET_80387
9854 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9855 "#")
9856
9857 ;; FIXME: We should to allow integer registers here. Problem is that
9858 ;; we need another scratch register to get constant from.
9859 ;; Forcing constant to mem if no register available in peep2 should be
9860 ;; safe even for PIC mode, because of RIP relative addressing.
9861 (define_insn "*negdf2_if_rex64"
9862 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9863 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9864 (clobber (reg:CC 17))]
9865 "TARGET_64BIT && TARGET_80387
9866 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9867 "#")
9868
9869 (define_split
9870 [(set (match_operand:DF 0 "fp_register_operand" "")
9871 (neg:DF (match_operand:DF 1 "register_operand" "")))
9872 (clobber (reg:CC 17))]
9873 "TARGET_80387 && reload_completed"
9874 [(set (match_dup 0)
9875 (neg:DF (match_dup 1)))]
9876 "")
9877
9878 (define_split
9879 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9880 (neg:DF (match_operand:DF 1 "register_operand" "")))
9881 (clobber (reg:CC 17))]
9882 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9883 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9884 (clobber (reg:CC 17))])]
9885 "operands[4] = gen_int_mode (0x80000000, SImode);
9886 split_di (operands+0, 1, operands+2, operands+3);")
9887
9888 (define_expand "negxf2"
9889 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9890 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9891 (clobber (reg:CC 17))])]
9892 "TARGET_80387"
9893 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9894
9895 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9896 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9897 ;; to itself.
9898 (define_insn "*negxf2_if"
9899 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9900 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9901 (clobber (reg:CC 17))]
9902 "TARGET_80387
9903 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9904 "#")
9905
9906 (define_split
9907 [(set (match_operand:XF 0 "fp_register_operand" "")
9908 (neg:XF (match_operand:XF 1 "register_operand" "")))
9909 (clobber (reg:CC 17))]
9910 "TARGET_80387 && reload_completed"
9911 [(set (match_dup 0)
9912 (neg:XF (match_dup 1)))]
9913 "")
9914
9915 (define_split
9916 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9917 (neg:XF (match_operand:XF 1 "register_operand" "")))
9918 (clobber (reg:CC 17))]
9919 "TARGET_80387 && reload_completed"
9920 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9921 (clobber (reg:CC 17))])]
9922 "operands[1] = GEN_INT (0x8000);
9923 operands[0] = gen_rtx_REG (SImode,
9924 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9925
9926 ;; Conditionalize these after reload. If they matches before reload, we
9927 ;; lose the clobber and ability to use integer instructions.
9928
9929 (define_insn "*negsf2_1"
9930 [(set (match_operand:SF 0 "register_operand" "=f")
9931 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9932 "TARGET_80387 && reload_completed"
9933 "fchs"
9934 [(set_attr "type" "fsgn")
9935 (set_attr "mode" "SF")
9936 (set_attr "ppro_uops" "few")])
9937
9938 (define_insn "*negdf2_1"
9939 [(set (match_operand:DF 0 "register_operand" "=f")
9940 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9941 "TARGET_80387 && reload_completed"
9942 "fchs"
9943 [(set_attr "type" "fsgn")
9944 (set_attr "mode" "DF")
9945 (set_attr "ppro_uops" "few")])
9946
9947 (define_insn "*negextendsfdf2"
9948 [(set (match_operand:DF 0 "register_operand" "=f")
9949 (neg:DF (float_extend:DF
9950 (match_operand:SF 1 "register_operand" "0"))))]
9951 "TARGET_80387"
9952 "fchs"
9953 [(set_attr "type" "fsgn")
9954 (set_attr "mode" "DF")
9955 (set_attr "ppro_uops" "few")])
9956
9957 (define_insn "*negxf2_1"
9958 [(set (match_operand:XF 0 "register_operand" "=f")
9959 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9960 "TARGET_80387 && reload_completed"
9961 "fchs"
9962 [(set_attr "type" "fsgn")
9963 (set_attr "mode" "XF")
9964 (set_attr "ppro_uops" "few")])
9965
9966 (define_insn "*negextenddfxf2"
9967 [(set (match_operand:XF 0 "register_operand" "=f")
9968 (neg:XF (float_extend:XF
9969 (match_operand:DF 1 "register_operand" "0"))))]
9970 "TARGET_80387"
9971 "fchs"
9972 [(set_attr "type" "fsgn")
9973 (set_attr "mode" "XF")
9974 (set_attr "ppro_uops" "few")])
9975
9976 (define_insn "*negextendsfxf2"
9977 [(set (match_operand:XF 0 "register_operand" "=f")
9978 (neg:XF (float_extend:XF
9979 (match_operand:SF 1 "register_operand" "0"))))]
9980 "TARGET_80387"
9981 "fchs"
9982 [(set_attr "type" "fsgn")
9983 (set_attr "mode" "XF")
9984 (set_attr "ppro_uops" "few")])
9985 \f
9986 ;; Absolute value instructions
9987
9988 (define_expand "abssf2"
9989 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9990 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9991 (clobber (reg:CC 17))])]
9992 "TARGET_80387"
9993 "if (TARGET_SSE)
9994 {
9995 /* In case operand is in memory, we will not use SSE. */
9996 if (memory_operand (operands[0], VOIDmode)
9997 && rtx_equal_p (operands[0], operands[1]))
9998 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
9999 else
10000 {
10001 /* Using SSE is tricky, since we need bitwise negation of -0
10002 in register. */
10003 rtx reg = gen_reg_rtx (V4SFmode);
10004 rtx dest = operands[0];
10005 rtx imm;
10006
10007 operands[1] = force_reg (SFmode, operands[1]);
10008 operands[0] = force_reg (SFmode, operands[0]);
10009 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10010 reg = force_reg (V4SFmode,
10011 gen_rtx_CONST_VECTOR (V4SFmode,
10012 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10013 CONST0_RTX (SFmode),
10014 CONST0_RTX (SFmode))));
10015 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10016 if (dest != operands[0])
10017 emit_move_insn (dest, operands[0]);
10018 }
10019 DONE;
10020 }
10021 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10022
10023 (define_insn "abssf2_memory"
10024 [(set (match_operand:SF 0 "memory_operand" "=m")
10025 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10026 (clobber (reg:CC 17))]
10027 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10028 "#")
10029
10030 (define_insn "abssf2_ifs"
10031 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10032 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10033 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10034 (clobber (reg:CC 17))]
10035 "TARGET_SSE
10036 && (reload_in_progress || reload_completed
10037 || (register_operand (operands[0], VOIDmode)
10038 && register_operand (operands[1], VOIDmode)))"
10039 "#")
10040
10041 (define_split
10042 [(set (match_operand:SF 0 "memory_operand" "")
10043 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10044 (use (match_operand:V4SF 2 "" ""))
10045 (clobber (reg:CC 17))]
10046 ""
10047 [(parallel [(set (match_dup 0)
10048 (abs:SF (match_dup 1)))
10049 (clobber (reg:CC 17))])])
10050
10051 (define_split
10052 [(set (match_operand:SF 0 "register_operand" "")
10053 (abs:SF (match_operand:SF 1 "register_operand" "")))
10054 (use (match_operand:V4SF 2 "" ""))
10055 (clobber (reg:CC 17))]
10056 "reload_completed && !SSE_REG_P (operands[0])"
10057 [(parallel [(set (match_dup 0)
10058 (abs:SF (match_dup 1)))
10059 (clobber (reg:CC 17))])])
10060
10061 (define_split
10062 [(set (match_operand:SF 0 "register_operand" "")
10063 (abs:SF (match_operand:SF 1 "register_operand" "")))
10064 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10065 (clobber (reg:CC 17))]
10066 "reload_completed && SSE_REG_P (operands[0])"
10067 [(set (match_dup 0)
10068 (and:V4SF (match_dup 1)
10069 (match_dup 2)))]
10070 {
10071 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10072 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10073 if (operands_match_p (operands[0], operands[2]))
10074 {
10075 rtx tmp;
10076 tmp = operands[1];
10077 operands[1] = operands[2];
10078 operands[2] = tmp;
10079 }
10080 })
10081
10082 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10083 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10084 ;; to itself.
10085 (define_insn "*abssf2_if"
10086 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10087 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10088 (clobber (reg:CC 17))]
10089 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10090 "#")
10091
10092 (define_split
10093 [(set (match_operand:SF 0 "fp_register_operand" "")
10094 (abs:SF (match_operand:SF 1 "register_operand" "")))
10095 (clobber (reg:CC 17))]
10096 "TARGET_80387 && reload_completed"
10097 [(set (match_dup 0)
10098 (abs:SF (match_dup 1)))]
10099 "")
10100
10101 (define_split
10102 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10103 (abs:SF (match_operand:SF 1 "register_operand" "")))
10104 (clobber (reg:CC 17))]
10105 "TARGET_80387 && reload_completed"
10106 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10107 (clobber (reg:CC 17))])]
10108 "operands[1] = gen_int_mode (~0x80000000, SImode);
10109 operands[0] = gen_lowpart (SImode, operands[0]);")
10110
10111 (define_split
10112 [(set (match_operand 0 "memory_operand" "")
10113 (abs (match_operand 1 "memory_operand" "")))
10114 (clobber (reg:CC 17))]
10115 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10116 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10117 (clobber (reg:CC 17))])]
10118 {
10119 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10120
10121 if (GET_MODE (operands[1]) == XFmode)
10122 size = 10;
10123 operands[0] = adjust_address (operands[0], QImode, size - 1);
10124 operands[1] = gen_int_mode (~0x80, QImode);
10125 })
10126
10127 (define_expand "absdf2"
10128 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10129 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10130 (clobber (reg:CC 17))])]
10131 "TARGET_80387"
10132 "if (TARGET_SSE2)
10133 {
10134 /* In case operand is in memory, we will not use SSE. */
10135 if (memory_operand (operands[0], VOIDmode)
10136 && rtx_equal_p (operands[0], operands[1]))
10137 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10138 else
10139 {
10140 /* Using SSE is tricky, since we need bitwise negation of -0
10141 in register. */
10142 rtx reg = gen_reg_rtx (V2DFmode);
10143 #if HOST_BITS_PER_WIDE_INT >= 64
10144 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10145 #else
10146 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10147 #endif
10148 rtx dest = operands[0];
10149
10150 operands[1] = force_reg (DFmode, operands[1]);
10151 operands[0] = force_reg (DFmode, operands[0]);
10152
10153 /* Produce LONG_DOUBLE with the proper immediate argument. */
10154 imm = gen_lowpart (DFmode, imm);
10155 reg = force_reg (V2DFmode,
10156 gen_rtx_CONST_VECTOR (V2DFmode,
10157 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10158 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10159 if (dest != operands[0])
10160 emit_move_insn (dest, operands[0]);
10161 }
10162 DONE;
10163 }
10164 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10165
10166 (define_insn "absdf2_memory"
10167 [(set (match_operand:DF 0 "memory_operand" "=m")
10168 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10169 (clobber (reg:CC 17))]
10170 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10171 "#")
10172
10173 (define_insn "absdf2_ifs"
10174 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10175 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10176 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10177 (clobber (reg:CC 17))]
10178 "!TARGET_64BIT && TARGET_SSE2
10179 && (reload_in_progress || reload_completed
10180 || (register_operand (operands[0], VOIDmode)
10181 && register_operand (operands[1], VOIDmode)))"
10182 "#")
10183
10184 (define_insn "*absdf2_ifs_rex64"
10185 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10186 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10187 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10188 (clobber (reg:CC 17))]
10189 "TARGET_64BIT && TARGET_SSE2
10190 && (reload_in_progress || reload_completed
10191 || (register_operand (operands[0], VOIDmode)
10192 && register_operand (operands[1], VOIDmode)))"
10193 "#")
10194
10195 (define_split
10196 [(set (match_operand:DF 0 "memory_operand" "")
10197 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10198 (use (match_operand:V2DF 2 "" ""))
10199 (clobber (reg:CC 17))]
10200 ""
10201 [(parallel [(set (match_dup 0)
10202 (abs:DF (match_dup 1)))
10203 (clobber (reg:CC 17))])])
10204
10205 (define_split
10206 [(set (match_operand:DF 0 "register_operand" "")
10207 (abs:DF (match_operand:DF 1 "register_operand" "")))
10208 (use (match_operand:V2DF 2 "" ""))
10209 (clobber (reg:CC 17))]
10210 "reload_completed && !SSE_REG_P (operands[0])"
10211 [(parallel [(set (match_dup 0)
10212 (abs:DF (match_dup 1)))
10213 (clobber (reg:CC 17))])])
10214
10215 (define_split
10216 [(set (match_operand:DF 0 "register_operand" "")
10217 (abs:DF (match_operand:DF 1 "register_operand" "")))
10218 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10219 (clobber (reg:CC 17))]
10220 "reload_completed && SSE_REG_P (operands[0])"
10221 [(set (match_dup 0)
10222 (and:V2DF (match_dup 1)
10223 (match_dup 2)))]
10224 {
10225 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10226 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10227 /* Avoid possible reformatting on the operands. */
10228 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10229 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10230 if (operands_match_p (operands[0], operands[2]))
10231 {
10232 rtx tmp;
10233 tmp = operands[1];
10234 operands[1] = operands[2];
10235 operands[2] = tmp;
10236 }
10237 })
10238
10239
10240 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10241 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10242 ;; to itself.
10243 (define_insn "*absdf2_if"
10244 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10245 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10246 (clobber (reg:CC 17))]
10247 "!TARGET_64BIT && TARGET_80387
10248 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10249 "#")
10250
10251 ;; FIXME: We should to allow integer registers here. Problem is that
10252 ;; we need another scratch register to get constant from.
10253 ;; Forcing constant to mem if no register available in peep2 should be
10254 ;; safe even for PIC mode, because of RIP relative addressing.
10255 (define_insn "*absdf2_if_rex64"
10256 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10257 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10258 (clobber (reg:CC 17))]
10259 "TARGET_64BIT && TARGET_80387
10260 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10261 "#")
10262
10263 (define_split
10264 [(set (match_operand:DF 0 "fp_register_operand" "")
10265 (abs:DF (match_operand:DF 1 "register_operand" "")))
10266 (clobber (reg:CC 17))]
10267 "TARGET_80387 && reload_completed"
10268 [(set (match_dup 0)
10269 (abs:DF (match_dup 1)))]
10270 "")
10271
10272 (define_split
10273 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10274 (abs:DF (match_operand:DF 1 "register_operand" "")))
10275 (clobber (reg:CC 17))]
10276 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10277 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10278 (clobber (reg:CC 17))])]
10279 "operands[4] = gen_int_mode (~0x80000000, SImode);
10280 split_di (operands+0, 1, operands+2, operands+3);")
10281
10282 (define_expand "absxf2"
10283 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10284 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10285 (clobber (reg:CC 17))])]
10286 "TARGET_80387"
10287 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10288
10289 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10290 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10291 ;; to itself.
10292 (define_insn "*absxf2_if"
10293 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10294 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10295 (clobber (reg:CC 17))]
10296 "TARGET_80387
10297 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10298 "#")
10299
10300 (define_split
10301 [(set (match_operand:XF 0 "fp_register_operand" "")
10302 (abs:XF (match_operand:XF 1 "register_operand" "")))
10303 (clobber (reg:CC 17))]
10304 "TARGET_80387 && reload_completed"
10305 [(set (match_dup 0)
10306 (abs:XF (match_dup 1)))]
10307 "")
10308
10309 (define_split
10310 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10311 (abs:XF (match_operand:XF 1 "register_operand" "")))
10312 (clobber (reg:CC 17))]
10313 "TARGET_80387 && reload_completed"
10314 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10315 (clobber (reg:CC 17))])]
10316 "operands[1] = GEN_INT (~0x8000);
10317 operands[0] = gen_rtx_REG (SImode,
10318 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10319
10320 (define_insn "*abssf2_1"
10321 [(set (match_operand:SF 0 "register_operand" "=f")
10322 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10323 "TARGET_80387 && reload_completed"
10324 "fabs"
10325 [(set_attr "type" "fsgn")
10326 (set_attr "mode" "SF")])
10327
10328 (define_insn "*absdf2_1"
10329 [(set (match_operand:DF 0 "register_operand" "=f")
10330 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10331 "TARGET_80387 && reload_completed"
10332 "fabs"
10333 [(set_attr "type" "fsgn")
10334 (set_attr "mode" "DF")])
10335
10336 (define_insn "*absextendsfdf2"
10337 [(set (match_operand:DF 0 "register_operand" "=f")
10338 (abs:DF (float_extend:DF
10339 (match_operand:SF 1 "register_operand" "0"))))]
10340 "TARGET_80387"
10341 "fabs"
10342 [(set_attr "type" "fsgn")
10343 (set_attr "mode" "DF")])
10344
10345 (define_insn "*absxf2_1"
10346 [(set (match_operand:XF 0 "register_operand" "=f")
10347 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10348 "TARGET_80387 && reload_completed"
10349 "fabs"
10350 [(set_attr "type" "fsgn")
10351 (set_attr "mode" "DF")])
10352
10353 (define_insn "*absextenddfxf2"
10354 [(set (match_operand:XF 0 "register_operand" "=f")
10355 (abs:XF (float_extend:XF
10356 (match_operand:DF 1 "register_operand" "0"))))]
10357 "TARGET_80387"
10358 "fabs"
10359 [(set_attr "type" "fsgn")
10360 (set_attr "mode" "XF")])
10361
10362 (define_insn "*absextendsfxf2"
10363 [(set (match_operand:XF 0 "register_operand" "=f")
10364 (abs:XF (float_extend:XF
10365 (match_operand:SF 1 "register_operand" "0"))))]
10366 "TARGET_80387"
10367 "fabs"
10368 [(set_attr "type" "fsgn")
10369 (set_attr "mode" "XF")])
10370 \f
10371 ;; One complement instructions
10372
10373 (define_expand "one_cmpldi2"
10374 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10375 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10376 "TARGET_64BIT"
10377 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10378
10379 (define_insn "*one_cmpldi2_1_rex64"
10380 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10381 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10382 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10383 "not{q}\t%0"
10384 [(set_attr "type" "negnot")
10385 (set_attr "mode" "DI")])
10386
10387 (define_insn "*one_cmpldi2_2_rex64"
10388 [(set (reg 17)
10389 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10390 (const_int 0)))
10391 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10392 (not:DI (match_dup 1)))]
10393 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10394 && ix86_unary_operator_ok (NOT, DImode, operands)"
10395 "#"
10396 [(set_attr "type" "alu1")
10397 (set_attr "mode" "DI")])
10398
10399 (define_split
10400 [(set (reg 17)
10401 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10402 (const_int 0)))
10403 (set (match_operand:DI 0 "nonimmediate_operand" "")
10404 (not:DI (match_dup 1)))]
10405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10406 [(parallel [(set (reg:CCNO 17)
10407 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10408 (const_int 0)))
10409 (set (match_dup 0)
10410 (xor:DI (match_dup 1) (const_int -1)))])]
10411 "")
10412
10413 (define_expand "one_cmplsi2"
10414 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10415 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10416 ""
10417 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10418
10419 (define_insn "*one_cmplsi2_1"
10420 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10421 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10422 "ix86_unary_operator_ok (NOT, SImode, operands)"
10423 "not{l}\t%0"
10424 [(set_attr "type" "negnot")
10425 (set_attr "mode" "SI")])
10426
10427 ;; ??? Currently never generated - xor is used instead.
10428 (define_insn "*one_cmplsi2_1_zext"
10429 [(set (match_operand:DI 0 "register_operand" "=r")
10430 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10431 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10432 "not{l}\t%k0"
10433 [(set_attr "type" "negnot")
10434 (set_attr "mode" "SI")])
10435
10436 (define_insn "*one_cmplsi2_2"
10437 [(set (reg 17)
10438 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10439 (const_int 0)))
10440 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10441 (not:SI (match_dup 1)))]
10442 "ix86_match_ccmode (insn, CCNOmode)
10443 && ix86_unary_operator_ok (NOT, SImode, operands)"
10444 "#"
10445 [(set_attr "type" "alu1")
10446 (set_attr "mode" "SI")])
10447
10448 (define_split
10449 [(set (reg 17)
10450 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10451 (const_int 0)))
10452 (set (match_operand:SI 0 "nonimmediate_operand" "")
10453 (not:SI (match_dup 1)))]
10454 "ix86_match_ccmode (insn, CCNOmode)"
10455 [(parallel [(set (reg:CCNO 17)
10456 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10457 (const_int 0)))
10458 (set (match_dup 0)
10459 (xor:SI (match_dup 1) (const_int -1)))])]
10460 "")
10461
10462 ;; ??? Currently never generated - xor is used instead.
10463 (define_insn "*one_cmplsi2_2_zext"
10464 [(set (reg 17)
10465 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10466 (const_int 0)))
10467 (set (match_operand:DI 0 "register_operand" "=r")
10468 (zero_extend:DI (not:SI (match_dup 1))))]
10469 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10470 && ix86_unary_operator_ok (NOT, SImode, operands)"
10471 "#"
10472 [(set_attr "type" "alu1")
10473 (set_attr "mode" "SI")])
10474
10475 (define_split
10476 [(set (reg 17)
10477 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10478 (const_int 0)))
10479 (set (match_operand:DI 0 "register_operand" "")
10480 (zero_extend:DI (not:SI (match_dup 1))))]
10481 "ix86_match_ccmode (insn, CCNOmode)"
10482 [(parallel [(set (reg:CCNO 17)
10483 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10484 (const_int 0)))
10485 (set (match_dup 0)
10486 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10487 "")
10488
10489 (define_expand "one_cmplhi2"
10490 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10491 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10492 "TARGET_HIMODE_MATH"
10493 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10494
10495 (define_insn "*one_cmplhi2_1"
10496 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10497 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10498 "ix86_unary_operator_ok (NOT, HImode, operands)"
10499 "not{w}\t%0"
10500 [(set_attr "type" "negnot")
10501 (set_attr "mode" "HI")])
10502
10503 (define_insn "*one_cmplhi2_2"
10504 [(set (reg 17)
10505 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10506 (const_int 0)))
10507 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10508 (not:HI (match_dup 1)))]
10509 "ix86_match_ccmode (insn, CCNOmode)
10510 && ix86_unary_operator_ok (NEG, HImode, operands)"
10511 "#"
10512 [(set_attr "type" "alu1")
10513 (set_attr "mode" "HI")])
10514
10515 (define_split
10516 [(set (reg 17)
10517 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10518 (const_int 0)))
10519 (set (match_operand:HI 0 "nonimmediate_operand" "")
10520 (not:HI (match_dup 1)))]
10521 "ix86_match_ccmode (insn, CCNOmode)"
10522 [(parallel [(set (reg:CCNO 17)
10523 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10524 (const_int 0)))
10525 (set (match_dup 0)
10526 (xor:HI (match_dup 1) (const_int -1)))])]
10527 "")
10528
10529 ;; %%% Potential partial reg stall on alternative 1. What to do?
10530 (define_expand "one_cmplqi2"
10531 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10532 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10533 "TARGET_QIMODE_MATH"
10534 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10535
10536 (define_insn "*one_cmplqi2_1"
10537 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10538 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10539 "ix86_unary_operator_ok (NOT, QImode, operands)"
10540 "@
10541 not{b}\t%0
10542 not{l}\t%k0"
10543 [(set_attr "type" "negnot")
10544 (set_attr "mode" "QI,SI")])
10545
10546 (define_insn "*one_cmplqi2_2"
10547 [(set (reg 17)
10548 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10549 (const_int 0)))
10550 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10551 (not:QI (match_dup 1)))]
10552 "ix86_match_ccmode (insn, CCNOmode)
10553 && ix86_unary_operator_ok (NOT, QImode, operands)"
10554 "#"
10555 [(set_attr "type" "alu1")
10556 (set_attr "mode" "QI")])
10557
10558 (define_split
10559 [(set (reg 17)
10560 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10561 (const_int 0)))
10562 (set (match_operand:QI 0 "nonimmediate_operand" "")
10563 (not:QI (match_dup 1)))]
10564 "ix86_match_ccmode (insn, CCNOmode)"
10565 [(parallel [(set (reg:CCNO 17)
10566 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10567 (const_int 0)))
10568 (set (match_dup 0)
10569 (xor:QI (match_dup 1) (const_int -1)))])]
10570 "")
10571 \f
10572 ;; Arithmetic shift instructions
10573
10574 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10575 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10576 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10577 ;; from the assembler input.
10578 ;;
10579 ;; This instruction shifts the target reg/mem as usual, but instead of
10580 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10581 ;; is a left shift double, bits are taken from the high order bits of
10582 ;; reg, else if the insn is a shift right double, bits are taken from the
10583 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10584 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10585 ;;
10586 ;; Since sh[lr]d does not change the `reg' operand, that is done
10587 ;; separately, making all shifts emit pairs of shift double and normal
10588 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10589 ;; support a 63 bit shift, each shift where the count is in a reg expands
10590 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10591 ;;
10592 ;; If the shift count is a constant, we need never emit more than one
10593 ;; shift pair, instead using moves and sign extension for counts greater
10594 ;; than 31.
10595
10596 (define_expand "ashldi3"
10597 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10598 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10599 (match_operand:QI 2 "nonmemory_operand" "")))
10600 (clobber (reg:CC 17))])]
10601 ""
10602 {
10603 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10604 {
10605 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10606 DONE;
10607 }
10608 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10609 DONE;
10610 })
10611
10612 (define_insn "*ashldi3_1_rex64"
10613 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10614 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10615 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10616 (clobber (reg:CC 17))]
10617 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10618 {
10619 switch (get_attr_type (insn))
10620 {
10621 case TYPE_ALU:
10622 if (operands[2] != const1_rtx)
10623 abort ();
10624 if (!rtx_equal_p (operands[0], operands[1]))
10625 abort ();
10626 return "add{q}\t{%0, %0|%0, %0}";
10627
10628 case TYPE_LEA:
10629 if (GET_CODE (operands[2]) != CONST_INT
10630 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10631 abort ();
10632 operands[1] = gen_rtx_MULT (DImode, operands[1],
10633 GEN_INT (1 << INTVAL (operands[2])));
10634 return "lea{q}\t{%a1, %0|%0, %a1}";
10635
10636 default:
10637 if (REG_P (operands[2]))
10638 return "sal{q}\t{%b2, %0|%0, %b2}";
10639 else if (operands[2] == const1_rtx
10640 && (TARGET_SHIFT1 || optimize_size))
10641 return "sal{q}\t%0";
10642 else
10643 return "sal{q}\t{%2, %0|%0, %2}";
10644 }
10645 }
10646 [(set (attr "type")
10647 (cond [(eq_attr "alternative" "1")
10648 (const_string "lea")
10649 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10650 (const_int 0))
10651 (match_operand 0 "register_operand" ""))
10652 (match_operand 2 "const1_operand" ""))
10653 (const_string "alu")
10654 ]
10655 (const_string "ishift")))
10656 (set_attr "mode" "DI")])
10657
10658 ;; Convert lea to the lea pattern to avoid flags dependency.
10659 (define_split
10660 [(set (match_operand:DI 0 "register_operand" "")
10661 (ashift:DI (match_operand:DI 1 "register_operand" "")
10662 (match_operand:QI 2 "immediate_operand" "")))
10663 (clobber (reg:CC 17))]
10664 "TARGET_64BIT && reload_completed
10665 && true_regnum (operands[0]) != true_regnum (operands[1])"
10666 [(set (match_dup 0)
10667 (mult:DI (match_dup 1)
10668 (match_dup 2)))]
10669 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10670
10671 ;; This pattern can't accept a variable shift count, since shifts by
10672 ;; zero don't affect the flags. We assume that shifts by constant
10673 ;; zero are optimized away.
10674 (define_insn "*ashldi3_cmp_rex64"
10675 [(set (reg 17)
10676 (compare
10677 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10678 (match_operand:QI 2 "immediate_operand" "e"))
10679 (const_int 0)))
10680 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10681 (ashift:DI (match_dup 1) (match_dup 2)))]
10682 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10683 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10684 {
10685 switch (get_attr_type (insn))
10686 {
10687 case TYPE_ALU:
10688 if (operands[2] != const1_rtx)
10689 abort ();
10690 return "add{q}\t{%0, %0|%0, %0}";
10691
10692 default:
10693 if (REG_P (operands[2]))
10694 return "sal{q}\t{%b2, %0|%0, %b2}";
10695 else if (operands[2] == const1_rtx
10696 && (TARGET_SHIFT1 || optimize_size))
10697 return "sal{q}\t%0";
10698 else
10699 return "sal{q}\t{%2, %0|%0, %2}";
10700 }
10701 }
10702 [(set (attr "type")
10703 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10704 (const_int 0))
10705 (match_operand 0 "register_operand" ""))
10706 (match_operand 2 "const1_operand" ""))
10707 (const_string "alu")
10708 ]
10709 (const_string "ishift")))
10710 (set_attr "mode" "DI")])
10711
10712 (define_insn "ashldi3_1"
10713 [(set (match_operand:DI 0 "register_operand" "=r")
10714 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10715 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10716 (clobber (match_scratch:SI 3 "=&r"))
10717 (clobber (reg:CC 17))]
10718 "!TARGET_64BIT && TARGET_CMOVE"
10719 "#"
10720 [(set_attr "type" "multi")])
10721
10722 (define_insn "*ashldi3_2"
10723 [(set (match_operand:DI 0 "register_operand" "=r")
10724 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10725 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10726 (clobber (reg:CC 17))]
10727 "!TARGET_64BIT"
10728 "#"
10729 [(set_attr "type" "multi")])
10730
10731 (define_split
10732 [(set (match_operand:DI 0 "register_operand" "")
10733 (ashift:DI (match_operand:DI 1 "register_operand" "")
10734 (match_operand:QI 2 "nonmemory_operand" "")))
10735 (clobber (match_scratch:SI 3 ""))
10736 (clobber (reg:CC 17))]
10737 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10738 [(const_int 0)]
10739 "ix86_split_ashldi (operands, operands[3]); DONE;")
10740
10741 (define_split
10742 [(set (match_operand:DI 0 "register_operand" "")
10743 (ashift:DI (match_operand:DI 1 "register_operand" "")
10744 (match_operand:QI 2 "nonmemory_operand" "")))
10745 (clobber (reg:CC 17))]
10746 "!TARGET_64BIT && reload_completed"
10747 [(const_int 0)]
10748 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10749
10750 (define_insn "x86_shld_1"
10751 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10752 (ior:SI (ashift:SI (match_dup 0)
10753 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10754 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10755 (minus:QI (const_int 32) (match_dup 2)))))
10756 (clobber (reg:CC 17))]
10757 ""
10758 "@
10759 shld{l}\t{%2, %1, %0|%0, %1, %2}
10760 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10761 [(set_attr "type" "ishift")
10762 (set_attr "prefix_0f" "1")
10763 (set_attr "mode" "SI")
10764 (set_attr "pent_pair" "np")
10765 (set_attr "athlon_decode" "vector")
10766 (set_attr "ppro_uops" "few")])
10767
10768 (define_expand "x86_shift_adj_1"
10769 [(set (reg:CCZ 17)
10770 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10771 (const_int 32))
10772 (const_int 0)))
10773 (set (match_operand:SI 0 "register_operand" "")
10774 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10775 (match_operand:SI 1 "register_operand" "")
10776 (match_dup 0)))
10777 (set (match_dup 1)
10778 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10779 (match_operand:SI 3 "register_operand" "r")
10780 (match_dup 1)))]
10781 "TARGET_CMOVE"
10782 "")
10783
10784 (define_expand "x86_shift_adj_2"
10785 [(use (match_operand:SI 0 "register_operand" ""))
10786 (use (match_operand:SI 1 "register_operand" ""))
10787 (use (match_operand:QI 2 "register_operand" ""))]
10788 ""
10789 {
10790 rtx label = gen_label_rtx ();
10791 rtx tmp;
10792
10793 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10794
10795 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10796 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10797 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10798 gen_rtx_LABEL_REF (VOIDmode, label),
10799 pc_rtx);
10800 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10801 JUMP_LABEL (tmp) = label;
10802
10803 emit_move_insn (operands[0], operands[1]);
10804 emit_move_insn (operands[1], const0_rtx);
10805
10806 emit_label (label);
10807 LABEL_NUSES (label) = 1;
10808
10809 DONE;
10810 })
10811
10812 (define_expand "ashlsi3"
10813 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10814 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10815 (match_operand:QI 2 "nonmemory_operand" "")))
10816 (clobber (reg:CC 17))]
10817 ""
10818 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10819
10820 (define_insn "*ashlsi3_1"
10821 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10822 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10823 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10824 (clobber (reg:CC 17))]
10825 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10826 {
10827 switch (get_attr_type (insn))
10828 {
10829 case TYPE_ALU:
10830 if (operands[2] != const1_rtx)
10831 abort ();
10832 if (!rtx_equal_p (operands[0], operands[1]))
10833 abort ();
10834 return "add{l}\t{%0, %0|%0, %0}";
10835
10836 case TYPE_LEA:
10837 return "#";
10838
10839 default:
10840 if (REG_P (operands[2]))
10841 return "sal{l}\t{%b2, %0|%0, %b2}";
10842 else if (operands[2] == const1_rtx
10843 && (TARGET_SHIFT1 || optimize_size))
10844 return "sal{l}\t%0";
10845 else
10846 return "sal{l}\t{%2, %0|%0, %2}";
10847 }
10848 }
10849 [(set (attr "type")
10850 (cond [(eq_attr "alternative" "1")
10851 (const_string "lea")
10852 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10853 (const_int 0))
10854 (match_operand 0 "register_operand" ""))
10855 (match_operand 2 "const1_operand" ""))
10856 (const_string "alu")
10857 ]
10858 (const_string "ishift")))
10859 (set_attr "mode" "SI")])
10860
10861 ;; Convert lea to the lea pattern to avoid flags dependency.
10862 (define_split
10863 [(set (match_operand 0 "register_operand" "")
10864 (ashift (match_operand 1 "index_register_operand" "")
10865 (match_operand:QI 2 "const_int_operand" "")))
10866 (clobber (reg:CC 17))]
10867 "reload_completed
10868 && true_regnum (operands[0]) != true_regnum (operands[1])"
10869 [(const_int 0)]
10870 {
10871 rtx pat;
10872 operands[0] = gen_lowpart (SImode, operands[0]);
10873 operands[1] = gen_lowpart (Pmode, operands[1]);
10874 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10875 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10876 if (Pmode != SImode)
10877 pat = gen_rtx_SUBREG (SImode, pat, 0);
10878 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10879 DONE;
10880 })
10881
10882 ;; Rare case of shifting RSP is handled by generating move and shift
10883 (define_split
10884 [(set (match_operand 0 "register_operand" "")
10885 (ashift (match_operand 1 "register_operand" "")
10886 (match_operand:QI 2 "const_int_operand" "")))
10887 (clobber (reg:CC 17))]
10888 "reload_completed
10889 && true_regnum (operands[0]) != true_regnum (operands[1])"
10890 [(const_int 0)]
10891 {
10892 rtx pat, clob;
10893 emit_move_insn (operands[1], operands[0]);
10894 pat = gen_rtx_SET (VOIDmode, operands[0],
10895 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10896 operands[0], operands[2]));
10897 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10898 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10899 DONE;
10900 })
10901
10902 (define_insn "*ashlsi3_1_zext"
10903 [(set (match_operand:DI 0 "register_operand" "=r,r")
10904 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10905 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10906 (clobber (reg:CC 17))]
10907 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10908 {
10909 switch (get_attr_type (insn))
10910 {
10911 case TYPE_ALU:
10912 if (operands[2] != const1_rtx)
10913 abort ();
10914 return "add{l}\t{%k0, %k0|%k0, %k0}";
10915
10916 case TYPE_LEA:
10917 return "#";
10918
10919 default:
10920 if (REG_P (operands[2]))
10921 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10922 else if (operands[2] == const1_rtx
10923 && (TARGET_SHIFT1 || optimize_size))
10924 return "sal{l}\t%k0";
10925 else
10926 return "sal{l}\t{%2, %k0|%k0, %2}";
10927 }
10928 }
10929 [(set (attr "type")
10930 (cond [(eq_attr "alternative" "1")
10931 (const_string "lea")
10932 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10933 (const_int 0))
10934 (match_operand 2 "const1_operand" ""))
10935 (const_string "alu")
10936 ]
10937 (const_string "ishift")))
10938 (set_attr "mode" "SI")])
10939
10940 ;; Convert lea to the lea pattern to avoid flags dependency.
10941 (define_split
10942 [(set (match_operand:DI 0 "register_operand" "")
10943 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10944 (match_operand:QI 2 "const_int_operand" ""))))
10945 (clobber (reg:CC 17))]
10946 "TARGET_64BIT && reload_completed
10947 && true_regnum (operands[0]) != true_regnum (operands[1])"
10948 [(set (match_dup 0) (zero_extend:DI
10949 (subreg:SI (mult:SI (match_dup 1)
10950 (match_dup 2)) 0)))]
10951 {
10952 operands[1] = gen_lowpart (Pmode, operands[1]);
10953 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10954 })
10955
10956 ;; This pattern can't accept a variable shift count, since shifts by
10957 ;; zero don't affect the flags. We assume that shifts by constant
10958 ;; zero are optimized away.
10959 (define_insn "*ashlsi3_cmp"
10960 [(set (reg 17)
10961 (compare
10962 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10963 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10964 (const_int 0)))
10965 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10966 (ashift:SI (match_dup 1) (match_dup 2)))]
10967 "ix86_match_ccmode (insn, CCGOCmode)
10968 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10969 {
10970 switch (get_attr_type (insn))
10971 {
10972 case TYPE_ALU:
10973 if (operands[2] != const1_rtx)
10974 abort ();
10975 return "add{l}\t{%0, %0|%0, %0}";
10976
10977 default:
10978 if (REG_P (operands[2]))
10979 return "sal{l}\t{%b2, %0|%0, %b2}";
10980 else if (operands[2] == const1_rtx
10981 && (TARGET_SHIFT1 || optimize_size))
10982 return "sal{l}\t%0";
10983 else
10984 return "sal{l}\t{%2, %0|%0, %2}";
10985 }
10986 }
10987 [(set (attr "type")
10988 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10989 (const_int 0))
10990 (match_operand 0 "register_operand" ""))
10991 (match_operand 2 "const1_operand" ""))
10992 (const_string "alu")
10993 ]
10994 (const_string "ishift")))
10995 (set_attr "mode" "SI")])
10996
10997 (define_insn "*ashlsi3_cmp_zext"
10998 [(set (reg 17)
10999 (compare
11000 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11001 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11002 (const_int 0)))
11003 (set (match_operand:DI 0 "register_operand" "=r")
11004 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11005 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11006 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11007 {
11008 switch (get_attr_type (insn))
11009 {
11010 case TYPE_ALU:
11011 if (operands[2] != const1_rtx)
11012 abort ();
11013 return "add{l}\t{%k0, %k0|%k0, %k0}";
11014
11015 default:
11016 if (REG_P (operands[2]))
11017 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11018 else if (operands[2] == const1_rtx
11019 && (TARGET_SHIFT1 || optimize_size))
11020 return "sal{l}\t%k0";
11021 else
11022 return "sal{l}\t{%2, %k0|%k0, %2}";
11023 }
11024 }
11025 [(set (attr "type")
11026 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11027 (const_int 0))
11028 (match_operand 2 "const1_operand" ""))
11029 (const_string "alu")
11030 ]
11031 (const_string "ishift")))
11032 (set_attr "mode" "SI")])
11033
11034 (define_expand "ashlhi3"
11035 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11036 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11037 (match_operand:QI 2 "nonmemory_operand" "")))
11038 (clobber (reg:CC 17))]
11039 "TARGET_HIMODE_MATH"
11040 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11041
11042 (define_insn "*ashlhi3_1_lea"
11043 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11044 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11045 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11046 (clobber (reg:CC 17))]
11047 "!TARGET_PARTIAL_REG_STALL
11048 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11049 {
11050 switch (get_attr_type (insn))
11051 {
11052 case TYPE_LEA:
11053 return "#";
11054 case TYPE_ALU:
11055 if (operands[2] != const1_rtx)
11056 abort ();
11057 return "add{w}\t{%0, %0|%0, %0}";
11058
11059 default:
11060 if (REG_P (operands[2]))
11061 return "sal{w}\t{%b2, %0|%0, %b2}";
11062 else if (operands[2] == const1_rtx
11063 && (TARGET_SHIFT1 || optimize_size))
11064 return "sal{w}\t%0";
11065 else
11066 return "sal{w}\t{%2, %0|%0, %2}";
11067 }
11068 }
11069 [(set (attr "type")
11070 (cond [(eq_attr "alternative" "1")
11071 (const_string "lea")
11072 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11073 (const_int 0))
11074 (match_operand 0 "register_operand" ""))
11075 (match_operand 2 "const1_operand" ""))
11076 (const_string "alu")
11077 ]
11078 (const_string "ishift")))
11079 (set_attr "mode" "HI,SI")])
11080
11081 (define_insn "*ashlhi3_1"
11082 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11083 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11084 (match_operand:QI 2 "nonmemory_operand" "cI")))
11085 (clobber (reg:CC 17))]
11086 "TARGET_PARTIAL_REG_STALL
11087 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11088 {
11089 switch (get_attr_type (insn))
11090 {
11091 case TYPE_ALU:
11092 if (operands[2] != const1_rtx)
11093 abort ();
11094 return "add{w}\t{%0, %0|%0, %0}";
11095
11096 default:
11097 if (REG_P (operands[2]))
11098 return "sal{w}\t{%b2, %0|%0, %b2}";
11099 else if (operands[2] == const1_rtx
11100 && (TARGET_SHIFT1 || optimize_size))
11101 return "sal{w}\t%0";
11102 else
11103 return "sal{w}\t{%2, %0|%0, %2}";
11104 }
11105 }
11106 [(set (attr "type")
11107 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11108 (const_int 0))
11109 (match_operand 0 "register_operand" ""))
11110 (match_operand 2 "const1_operand" ""))
11111 (const_string "alu")
11112 ]
11113 (const_string "ishift")))
11114 (set_attr "mode" "HI")])
11115
11116 ;; This pattern can't accept a variable shift count, since shifts by
11117 ;; zero don't affect the flags. We assume that shifts by constant
11118 ;; zero are optimized away.
11119 (define_insn "*ashlhi3_cmp"
11120 [(set (reg 17)
11121 (compare
11122 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11123 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11124 (const_int 0)))
11125 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11126 (ashift:HI (match_dup 1) (match_dup 2)))]
11127 "ix86_match_ccmode (insn, CCGOCmode)
11128 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11129 {
11130 switch (get_attr_type (insn))
11131 {
11132 case TYPE_ALU:
11133 if (operands[2] != const1_rtx)
11134 abort ();
11135 return "add{w}\t{%0, %0|%0, %0}";
11136
11137 default:
11138 if (REG_P (operands[2]))
11139 return "sal{w}\t{%b2, %0|%0, %b2}";
11140 else if (operands[2] == const1_rtx
11141 && (TARGET_SHIFT1 || optimize_size))
11142 return "sal{w}\t%0";
11143 else
11144 return "sal{w}\t{%2, %0|%0, %2}";
11145 }
11146 }
11147 [(set (attr "type")
11148 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11149 (const_int 0))
11150 (match_operand 0 "register_operand" ""))
11151 (match_operand 2 "const1_operand" ""))
11152 (const_string "alu")
11153 ]
11154 (const_string "ishift")))
11155 (set_attr "mode" "HI")])
11156
11157 (define_expand "ashlqi3"
11158 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11159 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11160 (match_operand:QI 2 "nonmemory_operand" "")))
11161 (clobber (reg:CC 17))]
11162 "TARGET_QIMODE_MATH"
11163 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11164
11165 ;; %%% Potential partial reg stall on alternative 2. What to do?
11166
11167 (define_insn "*ashlqi3_1_lea"
11168 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11169 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11170 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11171 (clobber (reg:CC 17))]
11172 "!TARGET_PARTIAL_REG_STALL
11173 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11174 {
11175 switch (get_attr_type (insn))
11176 {
11177 case TYPE_LEA:
11178 return "#";
11179 case TYPE_ALU:
11180 if (operands[2] != const1_rtx)
11181 abort ();
11182 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11183 return "add{l}\t{%k0, %k0|%k0, %k0}";
11184 else
11185 return "add{b}\t{%0, %0|%0, %0}";
11186
11187 default:
11188 if (REG_P (operands[2]))
11189 {
11190 if (get_attr_mode (insn) == MODE_SI)
11191 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11192 else
11193 return "sal{b}\t{%b2, %0|%0, %b2}";
11194 }
11195 else if (operands[2] == const1_rtx
11196 && (TARGET_SHIFT1 || optimize_size))
11197 {
11198 if (get_attr_mode (insn) == MODE_SI)
11199 return "sal{l}\t%0";
11200 else
11201 return "sal{b}\t%0";
11202 }
11203 else
11204 {
11205 if (get_attr_mode (insn) == MODE_SI)
11206 return "sal{l}\t{%2, %k0|%k0, %2}";
11207 else
11208 return "sal{b}\t{%2, %0|%0, %2}";
11209 }
11210 }
11211 }
11212 [(set (attr "type")
11213 (cond [(eq_attr "alternative" "2")
11214 (const_string "lea")
11215 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11216 (const_int 0))
11217 (match_operand 0 "register_operand" ""))
11218 (match_operand 2 "const1_operand" ""))
11219 (const_string "alu")
11220 ]
11221 (const_string "ishift")))
11222 (set_attr "mode" "QI,SI,SI")])
11223
11224 (define_insn "*ashlqi3_1"
11225 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11226 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11227 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11228 (clobber (reg:CC 17))]
11229 "TARGET_PARTIAL_REG_STALL
11230 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11231 {
11232 switch (get_attr_type (insn))
11233 {
11234 case TYPE_ALU:
11235 if (operands[2] != const1_rtx)
11236 abort ();
11237 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11238 return "add{l}\t{%k0, %k0|%k0, %k0}";
11239 else
11240 return "add{b}\t{%0, %0|%0, %0}";
11241
11242 default:
11243 if (REG_P (operands[2]))
11244 {
11245 if (get_attr_mode (insn) == MODE_SI)
11246 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11247 else
11248 return "sal{b}\t{%b2, %0|%0, %b2}";
11249 }
11250 else if (operands[2] == const1_rtx
11251 && (TARGET_SHIFT1 || optimize_size))
11252 {
11253 if (get_attr_mode (insn) == MODE_SI)
11254 return "sal{l}\t%0";
11255 else
11256 return "sal{b}\t%0";
11257 }
11258 else
11259 {
11260 if (get_attr_mode (insn) == MODE_SI)
11261 return "sal{l}\t{%2, %k0|%k0, %2}";
11262 else
11263 return "sal{b}\t{%2, %0|%0, %2}";
11264 }
11265 }
11266 }
11267 [(set (attr "type")
11268 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11269 (const_int 0))
11270 (match_operand 0 "register_operand" ""))
11271 (match_operand 2 "const1_operand" ""))
11272 (const_string "alu")
11273 ]
11274 (const_string "ishift")))
11275 (set_attr "mode" "QI,SI")])
11276
11277 ;; This pattern can't accept a variable shift count, since shifts by
11278 ;; zero don't affect the flags. We assume that shifts by constant
11279 ;; zero are optimized away.
11280 (define_insn "*ashlqi3_cmp"
11281 [(set (reg 17)
11282 (compare
11283 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11284 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11285 (const_int 0)))
11286 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11287 (ashift:QI (match_dup 1) (match_dup 2)))]
11288 "ix86_match_ccmode (insn, CCGOCmode)
11289 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11290 {
11291 switch (get_attr_type (insn))
11292 {
11293 case TYPE_ALU:
11294 if (operands[2] != const1_rtx)
11295 abort ();
11296 return "add{b}\t{%0, %0|%0, %0}";
11297
11298 default:
11299 if (REG_P (operands[2]))
11300 return "sal{b}\t{%b2, %0|%0, %b2}";
11301 else if (operands[2] == const1_rtx
11302 && (TARGET_SHIFT1 || optimize_size))
11303 return "sal{b}\t%0";
11304 else
11305 return "sal{b}\t{%2, %0|%0, %2}";
11306 }
11307 }
11308 [(set (attr "type")
11309 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11310 (const_int 0))
11311 (match_operand 0 "register_operand" ""))
11312 (match_operand 2 "const1_operand" ""))
11313 (const_string "alu")
11314 ]
11315 (const_string "ishift")))
11316 (set_attr "mode" "QI")])
11317
11318 ;; See comment above `ashldi3' about how this works.
11319
11320 (define_expand "ashrdi3"
11321 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11322 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11323 (match_operand:QI 2 "nonmemory_operand" "")))
11324 (clobber (reg:CC 17))])]
11325 ""
11326 {
11327 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11328 {
11329 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11330 DONE;
11331 }
11332 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11333 DONE;
11334 })
11335
11336 (define_insn "ashrdi3_63_rex64"
11337 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11338 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11339 (match_operand:DI 2 "const_int_operand" "i,i")))
11340 (clobber (reg:CC 17))]
11341 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11342 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11343 "@
11344 {cqto|cqo}
11345 sar{q}\t{%2, %0|%0, %2}"
11346 [(set_attr "type" "imovx,ishift")
11347 (set_attr "prefix_0f" "0,*")
11348 (set_attr "length_immediate" "0,*")
11349 (set_attr "modrm" "0,1")
11350 (set_attr "mode" "DI")])
11351
11352 (define_insn "*ashrdi3_1_one_bit_rex64"
11353 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11354 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11355 (match_operand:QI 2 "const1_operand" "")))
11356 (clobber (reg:CC 17))]
11357 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11358 && (TARGET_SHIFT1 || optimize_size)"
11359 "sar{q}\t%0"
11360 [(set_attr "type" "ishift")
11361 (set (attr "length")
11362 (if_then_else (match_operand:DI 0 "register_operand" "")
11363 (const_string "2")
11364 (const_string "*")))])
11365
11366 (define_insn "*ashrdi3_1_rex64"
11367 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11368 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11369 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11370 (clobber (reg:CC 17))]
11371 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11372 "@
11373 sar{q}\t{%2, %0|%0, %2}
11374 sar{q}\t{%b2, %0|%0, %b2}"
11375 [(set_attr "type" "ishift")
11376 (set_attr "mode" "DI")])
11377
11378 ;; This pattern can't accept a variable shift count, since shifts by
11379 ;; zero don't affect the flags. We assume that shifts by constant
11380 ;; zero are optimized away.
11381 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11382 [(set (reg 17)
11383 (compare
11384 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11385 (match_operand:QI 2 "const1_operand" ""))
11386 (const_int 0)))
11387 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11388 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11389 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11390 && (TARGET_SHIFT1 || optimize_size)
11391 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11392 "sar{q}\t%0"
11393 [(set_attr "type" "ishift")
11394 (set (attr "length")
11395 (if_then_else (match_operand:DI 0 "register_operand" "")
11396 (const_string "2")
11397 (const_string "*")))])
11398
11399 ;; This pattern can't accept a variable shift count, since shifts by
11400 ;; zero don't affect the flags. We assume that shifts by constant
11401 ;; zero are optimized away.
11402 (define_insn "*ashrdi3_cmp_rex64"
11403 [(set (reg 17)
11404 (compare
11405 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11406 (match_operand:QI 2 "const_int_operand" "n"))
11407 (const_int 0)))
11408 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11409 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11410 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11411 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11412 "sar{q}\t{%2, %0|%0, %2}"
11413 [(set_attr "type" "ishift")
11414 (set_attr "mode" "DI")])
11415
11416
11417 (define_insn "ashrdi3_1"
11418 [(set (match_operand:DI 0 "register_operand" "=r")
11419 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11420 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11421 (clobber (match_scratch:SI 3 "=&r"))
11422 (clobber (reg:CC 17))]
11423 "!TARGET_64BIT && TARGET_CMOVE"
11424 "#"
11425 [(set_attr "type" "multi")])
11426
11427 (define_insn "*ashrdi3_2"
11428 [(set (match_operand:DI 0 "register_operand" "=r")
11429 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11430 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11431 (clobber (reg:CC 17))]
11432 "!TARGET_64BIT"
11433 "#"
11434 [(set_attr "type" "multi")])
11435
11436 (define_split
11437 [(set (match_operand:DI 0 "register_operand" "")
11438 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11439 (match_operand:QI 2 "nonmemory_operand" "")))
11440 (clobber (match_scratch:SI 3 ""))
11441 (clobber (reg:CC 17))]
11442 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11443 [(const_int 0)]
11444 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11445
11446 (define_split
11447 [(set (match_operand:DI 0 "register_operand" "")
11448 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11449 (match_operand:QI 2 "nonmemory_operand" "")))
11450 (clobber (reg:CC 17))]
11451 "!TARGET_64BIT && reload_completed"
11452 [(const_int 0)]
11453 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11454
11455 (define_insn "x86_shrd_1"
11456 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11457 (ior:SI (ashiftrt:SI (match_dup 0)
11458 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11459 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11460 (minus:QI (const_int 32) (match_dup 2)))))
11461 (clobber (reg:CC 17))]
11462 ""
11463 "@
11464 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11465 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11466 [(set_attr "type" "ishift")
11467 (set_attr "prefix_0f" "1")
11468 (set_attr "pent_pair" "np")
11469 (set_attr "ppro_uops" "few")
11470 (set_attr "mode" "SI")])
11471
11472 (define_expand "x86_shift_adj_3"
11473 [(use (match_operand:SI 0 "register_operand" ""))
11474 (use (match_operand:SI 1 "register_operand" ""))
11475 (use (match_operand:QI 2 "register_operand" ""))]
11476 ""
11477 {
11478 rtx label = gen_label_rtx ();
11479 rtx tmp;
11480
11481 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11482
11483 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11484 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11485 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11486 gen_rtx_LABEL_REF (VOIDmode, label),
11487 pc_rtx);
11488 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11489 JUMP_LABEL (tmp) = label;
11490
11491 emit_move_insn (operands[0], operands[1]);
11492 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11493
11494 emit_label (label);
11495 LABEL_NUSES (label) = 1;
11496
11497 DONE;
11498 })
11499
11500 (define_insn "ashrsi3_31"
11501 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11502 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11503 (match_operand:SI 2 "const_int_operand" "i,i")))
11504 (clobber (reg:CC 17))]
11505 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11506 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11507 "@
11508 {cltd|cdq}
11509 sar{l}\t{%2, %0|%0, %2}"
11510 [(set_attr "type" "imovx,ishift")
11511 (set_attr "prefix_0f" "0,*")
11512 (set_attr "length_immediate" "0,*")
11513 (set_attr "modrm" "0,1")
11514 (set_attr "mode" "SI")])
11515
11516 (define_insn "*ashrsi3_31_zext"
11517 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11518 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11519 (match_operand:SI 2 "const_int_operand" "i,i"))))
11520 (clobber (reg:CC 17))]
11521 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11522 && INTVAL (operands[2]) == 31
11523 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11524 "@
11525 {cltd|cdq}
11526 sar{l}\t{%2, %k0|%k0, %2}"
11527 [(set_attr "type" "imovx,ishift")
11528 (set_attr "prefix_0f" "0,*")
11529 (set_attr "length_immediate" "0,*")
11530 (set_attr "modrm" "0,1")
11531 (set_attr "mode" "SI")])
11532
11533 (define_expand "ashrsi3"
11534 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11535 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11536 (match_operand:QI 2 "nonmemory_operand" "")))
11537 (clobber (reg:CC 17))]
11538 ""
11539 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11540
11541 (define_insn "*ashrsi3_1_one_bit"
11542 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11543 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11544 (match_operand:QI 2 "const1_operand" "")))
11545 (clobber (reg:CC 17))]
11546 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11547 && (TARGET_SHIFT1 || optimize_size)"
11548 "sar{l}\t%0"
11549 [(set_attr "type" "ishift")
11550 (set (attr "length")
11551 (if_then_else (match_operand:SI 0 "register_operand" "")
11552 (const_string "2")
11553 (const_string "*")))])
11554
11555 (define_insn "*ashrsi3_1_one_bit_zext"
11556 [(set (match_operand:DI 0 "register_operand" "=r")
11557 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11558 (match_operand:QI 2 "const1_operand" ""))))
11559 (clobber (reg:CC 17))]
11560 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11561 && (TARGET_SHIFT1 || optimize_size)"
11562 "sar{l}\t%k0"
11563 [(set_attr "type" "ishift")
11564 (set_attr "length" "2")])
11565
11566 (define_insn "*ashrsi3_1"
11567 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11568 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11569 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11570 (clobber (reg:CC 17))]
11571 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11572 "@
11573 sar{l}\t{%2, %0|%0, %2}
11574 sar{l}\t{%b2, %0|%0, %b2}"
11575 [(set_attr "type" "ishift")
11576 (set_attr "mode" "SI")])
11577
11578 (define_insn "*ashrsi3_1_zext"
11579 [(set (match_operand:DI 0 "register_operand" "=r,r")
11580 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11581 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11582 (clobber (reg:CC 17))]
11583 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11584 "@
11585 sar{l}\t{%2, %k0|%k0, %2}
11586 sar{l}\t{%b2, %k0|%k0, %b2}"
11587 [(set_attr "type" "ishift")
11588 (set_attr "mode" "SI")])
11589
11590 ;; This pattern can't accept a variable shift count, since shifts by
11591 ;; zero don't affect the flags. We assume that shifts by constant
11592 ;; zero are optimized away.
11593 (define_insn "*ashrsi3_one_bit_cmp"
11594 [(set (reg 17)
11595 (compare
11596 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11597 (match_operand:QI 2 "const1_operand" ""))
11598 (const_int 0)))
11599 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11600 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11601 "ix86_match_ccmode (insn, CCGOCmode)
11602 && (TARGET_SHIFT1 || optimize_size)
11603 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11604 "sar{l}\t%0"
11605 [(set_attr "type" "ishift")
11606 (set (attr "length")
11607 (if_then_else (match_operand:SI 0 "register_operand" "")
11608 (const_string "2")
11609 (const_string "*")))])
11610
11611 (define_insn "*ashrsi3_one_bit_cmp_zext"
11612 [(set (reg 17)
11613 (compare
11614 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11615 (match_operand:QI 2 "const1_operand" ""))
11616 (const_int 0)))
11617 (set (match_operand:DI 0 "register_operand" "=r")
11618 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11619 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11620 && (TARGET_SHIFT1 || optimize_size)
11621 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11622 "sar{l}\t%k0"
11623 [(set_attr "type" "ishift")
11624 (set_attr "length" "2")])
11625
11626 ;; This pattern can't accept a variable shift count, since shifts by
11627 ;; zero don't affect the flags. We assume that shifts by constant
11628 ;; zero are optimized away.
11629 (define_insn "*ashrsi3_cmp"
11630 [(set (reg 17)
11631 (compare
11632 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11633 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11634 (const_int 0)))
11635 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11636 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11637 "ix86_match_ccmode (insn, CCGOCmode)
11638 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11639 "sar{l}\t{%2, %0|%0, %2}"
11640 [(set_attr "type" "ishift")
11641 (set_attr "mode" "SI")])
11642
11643 (define_insn "*ashrsi3_cmp_zext"
11644 [(set (reg 17)
11645 (compare
11646 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11647 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11648 (const_int 0)))
11649 (set (match_operand:DI 0 "register_operand" "=r")
11650 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11651 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11652 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653 "sar{l}\t{%2, %k0|%k0, %2}"
11654 [(set_attr "type" "ishift")
11655 (set_attr "mode" "SI")])
11656
11657 (define_expand "ashrhi3"
11658 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11659 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11660 (match_operand:QI 2 "nonmemory_operand" "")))
11661 (clobber (reg:CC 17))]
11662 "TARGET_HIMODE_MATH"
11663 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11664
11665 (define_insn "*ashrhi3_1_one_bit"
11666 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11667 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11668 (match_operand:QI 2 "const1_operand" "")))
11669 (clobber (reg:CC 17))]
11670 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11671 && (TARGET_SHIFT1 || optimize_size)"
11672 "sar{w}\t%0"
11673 [(set_attr "type" "ishift")
11674 (set (attr "length")
11675 (if_then_else (match_operand 0 "register_operand" "")
11676 (const_string "2")
11677 (const_string "*")))])
11678
11679 (define_insn "*ashrhi3_1"
11680 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11681 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11682 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11683 (clobber (reg:CC 17))]
11684 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11685 "@
11686 sar{w}\t{%2, %0|%0, %2}
11687 sar{w}\t{%b2, %0|%0, %b2}"
11688 [(set_attr "type" "ishift")
11689 (set_attr "mode" "HI")])
11690
11691 ;; This pattern can't accept a variable shift count, since shifts by
11692 ;; zero don't affect the flags. We assume that shifts by constant
11693 ;; zero are optimized away.
11694 (define_insn "*ashrhi3_one_bit_cmp"
11695 [(set (reg 17)
11696 (compare
11697 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11698 (match_operand:QI 2 "const1_operand" ""))
11699 (const_int 0)))
11700 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11701 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11702 "ix86_match_ccmode (insn, CCGOCmode)
11703 && (TARGET_SHIFT1 || optimize_size)
11704 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11705 "sar{w}\t%0"
11706 [(set_attr "type" "ishift")
11707 (set (attr "length")
11708 (if_then_else (match_operand 0 "register_operand" "")
11709 (const_string "2")
11710 (const_string "*")))])
11711
11712 ;; This pattern can't accept a variable shift count, since shifts by
11713 ;; zero don't affect the flags. We assume that shifts by constant
11714 ;; zero are optimized away.
11715 (define_insn "*ashrhi3_cmp"
11716 [(set (reg 17)
11717 (compare
11718 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11719 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11720 (const_int 0)))
11721 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11722 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11723 "ix86_match_ccmode (insn, CCGOCmode)
11724 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11725 "sar{w}\t{%2, %0|%0, %2}"
11726 [(set_attr "type" "ishift")
11727 (set_attr "mode" "HI")])
11728
11729 (define_expand "ashrqi3"
11730 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11731 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11732 (match_operand:QI 2 "nonmemory_operand" "")))
11733 (clobber (reg:CC 17))]
11734 "TARGET_QIMODE_MATH"
11735 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11736
11737 (define_insn "*ashrqi3_1_one_bit"
11738 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11739 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11740 (match_operand:QI 2 "const1_operand" "")))
11741 (clobber (reg:CC 17))]
11742 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11743 && (TARGET_SHIFT1 || optimize_size)"
11744 "sar{b}\t%0"
11745 [(set_attr "type" "ishift")
11746 (set (attr "length")
11747 (if_then_else (match_operand 0 "register_operand" "")
11748 (const_string "2")
11749 (const_string "*")))])
11750
11751 (define_insn "*ashrqi3_1_one_bit_slp"
11752 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11753 (ashiftrt:QI (match_dup 0)
11754 (match_operand:QI 1 "const1_operand" "")))
11755 (clobber (reg:CC 17))]
11756 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11757 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11758 && (TARGET_SHIFT1 || optimize_size)"
11759 "sar{b}\t%0"
11760 [(set_attr "type" "ishift1")
11761 (set (attr "length")
11762 (if_then_else (match_operand 0 "register_operand" "")
11763 (const_string "2")
11764 (const_string "*")))])
11765
11766 (define_insn "*ashrqi3_1"
11767 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11768 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11769 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11770 (clobber (reg:CC 17))]
11771 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11772 "@
11773 sar{b}\t{%2, %0|%0, %2}
11774 sar{b}\t{%b2, %0|%0, %b2}"
11775 [(set_attr "type" "ishift")
11776 (set_attr "mode" "QI")])
11777
11778 (define_insn "*ashrqi3_1_slp"
11779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11780 (ashiftrt:QI (match_dup 0)
11781 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11782 (clobber (reg:CC 17))]
11783 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11784 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11785 "@
11786 sar{b}\t{%1, %0|%0, %1}
11787 sar{b}\t{%b1, %0|%0, %b1}"
11788 [(set_attr "type" "ishift1")
11789 (set_attr "mode" "QI")])
11790
11791 ;; This pattern can't accept a variable shift count, since shifts by
11792 ;; zero don't affect the flags. We assume that shifts by constant
11793 ;; zero are optimized away.
11794 (define_insn "*ashrqi3_one_bit_cmp"
11795 [(set (reg 17)
11796 (compare
11797 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11798 (match_operand:QI 2 "const1_operand" "I"))
11799 (const_int 0)))
11800 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11801 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11802 "ix86_match_ccmode (insn, CCGOCmode)
11803 && (TARGET_SHIFT1 || optimize_size)
11804 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11805 "sar{b}\t%0"
11806 [(set_attr "type" "ishift")
11807 (set (attr "length")
11808 (if_then_else (match_operand 0 "register_operand" "")
11809 (const_string "2")
11810 (const_string "*")))])
11811
11812 ;; This pattern can't accept a variable shift count, since shifts by
11813 ;; zero don't affect the flags. We assume that shifts by constant
11814 ;; zero are optimized away.
11815 (define_insn "*ashrqi3_cmp"
11816 [(set (reg 17)
11817 (compare
11818 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11819 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11820 (const_int 0)))
11821 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11822 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11823 "ix86_match_ccmode (insn, CCGOCmode)
11824 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11825 "sar{b}\t{%2, %0|%0, %2}"
11826 [(set_attr "type" "ishift")
11827 (set_attr "mode" "QI")])
11828 \f
11829 ;; Logical shift instructions
11830
11831 ;; See comment above `ashldi3' about how this works.
11832
11833 (define_expand "lshrdi3"
11834 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11835 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11836 (match_operand:QI 2 "nonmemory_operand" "")))
11837 (clobber (reg:CC 17))])]
11838 ""
11839 {
11840 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11841 {
11842 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11843 DONE;
11844 }
11845 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11846 DONE;
11847 })
11848
11849 (define_insn "*lshrdi3_1_one_bit_rex64"
11850 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11851 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11852 (match_operand:QI 2 "const1_operand" "")))
11853 (clobber (reg:CC 17))]
11854 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11855 && (TARGET_SHIFT1 || optimize_size)"
11856 "shr{q}\t%0"
11857 [(set_attr "type" "ishift")
11858 (set (attr "length")
11859 (if_then_else (match_operand:DI 0 "register_operand" "")
11860 (const_string "2")
11861 (const_string "*")))])
11862
11863 (define_insn "*lshrdi3_1_rex64"
11864 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11865 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11866 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11867 (clobber (reg:CC 17))]
11868 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11869 "@
11870 shr{q}\t{%2, %0|%0, %2}
11871 shr{q}\t{%b2, %0|%0, %b2}"
11872 [(set_attr "type" "ishift")
11873 (set_attr "mode" "DI")])
11874
11875 ;; This pattern can't accept a variable shift count, since shifts by
11876 ;; zero don't affect the flags. We assume that shifts by constant
11877 ;; zero are optimized away.
11878 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11879 [(set (reg 17)
11880 (compare
11881 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11882 (match_operand:QI 2 "const1_operand" ""))
11883 (const_int 0)))
11884 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11885 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11886 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11887 && (TARGET_SHIFT1 || optimize_size)
11888 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11889 "shr{q}\t%0"
11890 [(set_attr "type" "ishift")
11891 (set (attr "length")
11892 (if_then_else (match_operand:DI 0 "register_operand" "")
11893 (const_string "2")
11894 (const_string "*")))])
11895
11896 ;; This pattern can't accept a variable shift count, since shifts by
11897 ;; zero don't affect the flags. We assume that shifts by constant
11898 ;; zero are optimized away.
11899 (define_insn "*lshrdi3_cmp_rex64"
11900 [(set (reg 17)
11901 (compare
11902 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11903 (match_operand:QI 2 "const_int_operand" "e"))
11904 (const_int 0)))
11905 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11906 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11907 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11908 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11909 "shr{q}\t{%2, %0|%0, %2}"
11910 [(set_attr "type" "ishift")
11911 (set_attr "mode" "DI")])
11912
11913 (define_insn "lshrdi3_1"
11914 [(set (match_operand:DI 0 "register_operand" "=r")
11915 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11916 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11917 (clobber (match_scratch:SI 3 "=&r"))
11918 (clobber (reg:CC 17))]
11919 "!TARGET_64BIT && TARGET_CMOVE"
11920 "#"
11921 [(set_attr "type" "multi")])
11922
11923 (define_insn "*lshrdi3_2"
11924 [(set (match_operand:DI 0 "register_operand" "=r")
11925 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11926 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11927 (clobber (reg:CC 17))]
11928 "!TARGET_64BIT"
11929 "#"
11930 [(set_attr "type" "multi")])
11931
11932 (define_split
11933 [(set (match_operand:DI 0 "register_operand" "")
11934 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11935 (match_operand:QI 2 "nonmemory_operand" "")))
11936 (clobber (match_scratch:SI 3 ""))
11937 (clobber (reg:CC 17))]
11938 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11939 [(const_int 0)]
11940 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11941
11942 (define_split
11943 [(set (match_operand:DI 0 "register_operand" "")
11944 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11945 (match_operand:QI 2 "nonmemory_operand" "")))
11946 (clobber (reg:CC 17))]
11947 "!TARGET_64BIT && reload_completed"
11948 [(const_int 0)]
11949 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11950
11951 (define_expand "lshrsi3"
11952 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11953 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11954 (match_operand:QI 2 "nonmemory_operand" "")))
11955 (clobber (reg:CC 17))]
11956 ""
11957 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11958
11959 (define_insn "*lshrsi3_1_one_bit"
11960 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11961 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11962 (match_operand:QI 2 "const1_operand" "")))
11963 (clobber (reg:CC 17))]
11964 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11965 && (TARGET_SHIFT1 || optimize_size)"
11966 "shr{l}\t%0"
11967 [(set_attr "type" "ishift")
11968 (set (attr "length")
11969 (if_then_else (match_operand:SI 0 "register_operand" "")
11970 (const_string "2")
11971 (const_string "*")))])
11972
11973 (define_insn "*lshrsi3_1_one_bit_zext"
11974 [(set (match_operand:DI 0 "register_operand" "=r")
11975 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11976 (match_operand:QI 2 "const1_operand" "")))
11977 (clobber (reg:CC 17))]
11978 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11979 && (TARGET_SHIFT1 || optimize_size)"
11980 "shr{l}\t%k0"
11981 [(set_attr "type" "ishift")
11982 (set_attr "length" "2")])
11983
11984 (define_insn "*lshrsi3_1"
11985 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11986 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11987 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11988 (clobber (reg:CC 17))]
11989 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11990 "@
11991 shr{l}\t{%2, %0|%0, %2}
11992 shr{l}\t{%b2, %0|%0, %b2}"
11993 [(set_attr "type" "ishift")
11994 (set_attr "mode" "SI")])
11995
11996 (define_insn "*lshrsi3_1_zext"
11997 [(set (match_operand:DI 0 "register_operand" "=r,r")
11998 (zero_extend:DI
11999 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12000 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12001 (clobber (reg:CC 17))]
12002 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12003 "@
12004 shr{l}\t{%2, %k0|%k0, %2}
12005 shr{l}\t{%b2, %k0|%k0, %b2}"
12006 [(set_attr "type" "ishift")
12007 (set_attr "mode" "SI")])
12008
12009 ;; This pattern can't accept a variable shift count, since shifts by
12010 ;; zero don't affect the flags. We assume that shifts by constant
12011 ;; zero are optimized away.
12012 (define_insn "*lshrsi3_one_bit_cmp"
12013 [(set (reg 17)
12014 (compare
12015 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12016 (match_operand:QI 2 "const1_operand" ""))
12017 (const_int 0)))
12018 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12019 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12020 "ix86_match_ccmode (insn, CCGOCmode)
12021 && (TARGET_SHIFT1 || optimize_size)
12022 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12023 "shr{l}\t%0"
12024 [(set_attr "type" "ishift")
12025 (set (attr "length")
12026 (if_then_else (match_operand:SI 0 "register_operand" "")
12027 (const_string "2")
12028 (const_string "*")))])
12029
12030 (define_insn "*lshrsi3_cmp_one_bit_zext"
12031 [(set (reg 17)
12032 (compare
12033 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12034 (match_operand:QI 2 "const1_operand" ""))
12035 (const_int 0)))
12036 (set (match_operand:DI 0 "register_operand" "=r")
12037 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12038 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12039 && (TARGET_SHIFT1 || optimize_size)
12040 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12041 "shr{l}\t%k0"
12042 [(set_attr "type" "ishift")
12043 (set_attr "length" "2")])
12044
12045 ;; This pattern can't accept a variable shift count, since shifts by
12046 ;; zero don't affect the flags. We assume that shifts by constant
12047 ;; zero are optimized away.
12048 (define_insn "*lshrsi3_cmp"
12049 [(set (reg 17)
12050 (compare
12051 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12052 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12053 (const_int 0)))
12054 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12055 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12056 "ix86_match_ccmode (insn, CCGOCmode)
12057 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12058 "shr{l}\t{%2, %0|%0, %2}"
12059 [(set_attr "type" "ishift")
12060 (set_attr "mode" "SI")])
12061
12062 (define_insn "*lshrsi3_cmp_zext"
12063 [(set (reg 17)
12064 (compare
12065 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12066 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12067 (const_int 0)))
12068 (set (match_operand:DI 0 "register_operand" "=r")
12069 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12070 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12071 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12072 "shr{l}\t{%2, %k0|%k0, %2}"
12073 [(set_attr "type" "ishift")
12074 (set_attr "mode" "SI")])
12075
12076 (define_expand "lshrhi3"
12077 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12078 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12079 (match_operand:QI 2 "nonmemory_operand" "")))
12080 (clobber (reg:CC 17))]
12081 "TARGET_HIMODE_MATH"
12082 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12083
12084 (define_insn "*lshrhi3_1_one_bit"
12085 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12086 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12087 (match_operand:QI 2 "const1_operand" "")))
12088 (clobber (reg:CC 17))]
12089 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12090 && (TARGET_SHIFT1 || optimize_size)"
12091 "shr{w}\t%0"
12092 [(set_attr "type" "ishift")
12093 (set (attr "length")
12094 (if_then_else (match_operand 0 "register_operand" "")
12095 (const_string "2")
12096 (const_string "*")))])
12097
12098 (define_insn "*lshrhi3_1"
12099 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12100 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12101 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12102 (clobber (reg:CC 17))]
12103 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12104 "@
12105 shr{w}\t{%2, %0|%0, %2}
12106 shr{w}\t{%b2, %0|%0, %b2}"
12107 [(set_attr "type" "ishift")
12108 (set_attr "mode" "HI")])
12109
12110 ;; This pattern can't accept a variable shift count, since shifts by
12111 ;; zero don't affect the flags. We assume that shifts by constant
12112 ;; zero are optimized away.
12113 (define_insn "*lshrhi3_one_bit_cmp"
12114 [(set (reg 17)
12115 (compare
12116 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12117 (match_operand:QI 2 "const1_operand" ""))
12118 (const_int 0)))
12119 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12120 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12121 "ix86_match_ccmode (insn, CCGOCmode)
12122 && (TARGET_SHIFT1 || optimize_size)
12123 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12124 "shr{w}\t%0"
12125 [(set_attr "type" "ishift")
12126 (set (attr "length")
12127 (if_then_else (match_operand:SI 0 "register_operand" "")
12128 (const_string "2")
12129 (const_string "*")))])
12130
12131 ;; This pattern can't accept a variable shift count, since shifts by
12132 ;; zero don't affect the flags. We assume that shifts by constant
12133 ;; zero are optimized away.
12134 (define_insn "*lshrhi3_cmp"
12135 [(set (reg 17)
12136 (compare
12137 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12138 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12139 (const_int 0)))
12140 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12141 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12142 "ix86_match_ccmode (insn, CCGOCmode)
12143 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12144 "shr{w}\t{%2, %0|%0, %2}"
12145 [(set_attr "type" "ishift")
12146 (set_attr "mode" "HI")])
12147
12148 (define_expand "lshrqi3"
12149 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12150 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12151 (match_operand:QI 2 "nonmemory_operand" "")))
12152 (clobber (reg:CC 17))]
12153 "TARGET_QIMODE_MATH"
12154 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12155
12156 (define_insn "*lshrqi3_1_one_bit"
12157 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12158 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12159 (match_operand:QI 2 "const1_operand" "")))
12160 (clobber (reg:CC 17))]
12161 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12162 && (TARGET_SHIFT1 || optimize_size)"
12163 "shr{b}\t%0"
12164 [(set_attr "type" "ishift")
12165 (set (attr "length")
12166 (if_then_else (match_operand 0 "register_operand" "")
12167 (const_string "2")
12168 (const_string "*")))])
12169
12170 (define_insn "*lshrqi3_1_one_bit_slp"
12171 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12172 (lshiftrt:QI (match_dup 0)
12173 (match_operand:QI 1 "const1_operand" "")))
12174 (clobber (reg:CC 17))]
12175 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12176 && (TARGET_SHIFT1 || optimize_size)"
12177 "shr{b}\t%0"
12178 [(set_attr "type" "ishift1")
12179 (set (attr "length")
12180 (if_then_else (match_operand 0 "register_operand" "")
12181 (const_string "2")
12182 (const_string "*")))])
12183
12184 (define_insn "*lshrqi3_1"
12185 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12186 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12187 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188 (clobber (reg:CC 17))]
12189 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12190 "@
12191 shr{b}\t{%2, %0|%0, %2}
12192 shr{b}\t{%b2, %0|%0, %b2}"
12193 [(set_attr "type" "ishift")
12194 (set_attr "mode" "QI")])
12195
12196 (define_insn "*lshrqi3_1_slp"
12197 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12198 (lshiftrt:QI (match_dup 0)
12199 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12200 (clobber (reg:CC 17))]
12201 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12202 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12203 "@
12204 shr{b}\t{%1, %0|%0, %1}
12205 shr{b}\t{%b1, %0|%0, %b1}"
12206 [(set_attr "type" "ishift1")
12207 (set_attr "mode" "QI")])
12208
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags. We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*lshrqi2_one_bit_cmp"
12213 [(set (reg 17)
12214 (compare
12215 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12216 (match_operand:QI 2 "const1_operand" ""))
12217 (const_int 0)))
12218 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12219 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12220 "ix86_match_ccmode (insn, CCGOCmode)
12221 && (TARGET_SHIFT1 || optimize_size)
12222 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12223 "shr{b}\t%0"
12224 [(set_attr "type" "ishift")
12225 (set (attr "length")
12226 (if_then_else (match_operand:SI 0 "register_operand" "")
12227 (const_string "2")
12228 (const_string "*")))])
12229
12230 ;; This pattern can't accept a variable shift count, since shifts by
12231 ;; zero don't affect the flags. We assume that shifts by constant
12232 ;; zero are optimized away.
12233 (define_insn "*lshrqi2_cmp"
12234 [(set (reg 17)
12235 (compare
12236 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12237 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12238 (const_int 0)))
12239 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12240 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12241 "ix86_match_ccmode (insn, CCGOCmode)
12242 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12243 "shr{b}\t{%2, %0|%0, %2}"
12244 [(set_attr "type" "ishift")
12245 (set_attr "mode" "QI")])
12246 \f
12247 ;; Rotate instructions
12248
12249 (define_expand "rotldi3"
12250 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12251 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12252 (match_operand:QI 2 "nonmemory_operand" "")))
12253 (clobber (reg:CC 17))]
12254 "TARGET_64BIT"
12255 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12256
12257 (define_insn "*rotlsi3_1_one_bit_rex64"
12258 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12259 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12260 (match_operand:QI 2 "const1_operand" "")))
12261 (clobber (reg:CC 17))]
12262 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12263 && (TARGET_SHIFT1 || optimize_size)"
12264 "rol{q}\t%0"
12265 [(set_attr "type" "rotate")
12266 (set (attr "length")
12267 (if_then_else (match_operand:DI 0 "register_operand" "")
12268 (const_string "2")
12269 (const_string "*")))])
12270
12271 (define_insn "*rotldi3_1_rex64"
12272 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12273 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12274 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12275 (clobber (reg:CC 17))]
12276 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12277 "@
12278 rol{q}\t{%2, %0|%0, %2}
12279 rol{q}\t{%b2, %0|%0, %b2}"
12280 [(set_attr "type" "rotate")
12281 (set_attr "mode" "DI")])
12282
12283 (define_expand "rotlsi3"
12284 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12285 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12286 (match_operand:QI 2 "nonmemory_operand" "")))
12287 (clobber (reg:CC 17))]
12288 ""
12289 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12290
12291 (define_insn "*rotlsi3_1_one_bit"
12292 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12293 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12294 (match_operand:QI 2 "const1_operand" "")))
12295 (clobber (reg:CC 17))]
12296 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12297 && (TARGET_SHIFT1 || optimize_size)"
12298 "rol{l}\t%0"
12299 [(set_attr "type" "rotate")
12300 (set (attr "length")
12301 (if_then_else (match_operand:SI 0 "register_operand" "")
12302 (const_string "2")
12303 (const_string "*")))])
12304
12305 (define_insn "*rotlsi3_1_one_bit_zext"
12306 [(set (match_operand:DI 0 "register_operand" "=r")
12307 (zero_extend:DI
12308 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12309 (match_operand:QI 2 "const1_operand" ""))))
12310 (clobber (reg:CC 17))]
12311 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12312 && (TARGET_SHIFT1 || optimize_size)"
12313 "rol{l}\t%k0"
12314 [(set_attr "type" "rotate")
12315 (set_attr "length" "2")])
12316
12317 (define_insn "*rotlsi3_1"
12318 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12319 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12320 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12321 (clobber (reg:CC 17))]
12322 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12323 "@
12324 rol{l}\t{%2, %0|%0, %2}
12325 rol{l}\t{%b2, %0|%0, %b2}"
12326 [(set_attr "type" "rotate")
12327 (set_attr "mode" "SI")])
12328
12329 (define_insn "*rotlsi3_1_zext"
12330 [(set (match_operand:DI 0 "register_operand" "=r,r")
12331 (zero_extend:DI
12332 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12333 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12334 (clobber (reg:CC 17))]
12335 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12336 "@
12337 rol{l}\t{%2, %k0|%k0, %2}
12338 rol{l}\t{%b2, %k0|%k0, %b2}"
12339 [(set_attr "type" "rotate")
12340 (set_attr "mode" "SI")])
12341
12342 (define_expand "rotlhi3"
12343 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12344 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12345 (match_operand:QI 2 "nonmemory_operand" "")))
12346 (clobber (reg:CC 17))]
12347 "TARGET_HIMODE_MATH"
12348 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12349
12350 (define_insn "*rotlhi3_1_one_bit"
12351 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12352 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const1_operand" "")))
12354 (clobber (reg:CC 17))]
12355 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12356 && (TARGET_SHIFT1 || optimize_size)"
12357 "rol{w}\t%0"
12358 [(set_attr "type" "rotate")
12359 (set (attr "length")
12360 (if_then_else (match_operand 0 "register_operand" "")
12361 (const_string "2")
12362 (const_string "*")))])
12363
12364 (define_insn "*rotlhi3_1"
12365 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12366 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12367 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12368 (clobber (reg:CC 17))]
12369 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12370 "@
12371 rol{w}\t{%2, %0|%0, %2}
12372 rol{w}\t{%b2, %0|%0, %b2}"
12373 [(set_attr "type" "rotate")
12374 (set_attr "mode" "HI")])
12375
12376 (define_expand "rotlqi3"
12377 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12378 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12379 (match_operand:QI 2 "nonmemory_operand" "")))
12380 (clobber (reg:CC 17))]
12381 "TARGET_QIMODE_MATH"
12382 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12383
12384 (define_insn "*rotlqi3_1_one_bit_slp"
12385 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12386 (rotate:QI (match_dup 0)
12387 (match_operand:QI 1 "const1_operand" "")))
12388 (clobber (reg:CC 17))]
12389 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12390 && (TARGET_SHIFT1 || optimize_size)"
12391 "rol{b}\t%0"
12392 [(set_attr "type" "rotate1")
12393 (set (attr "length")
12394 (if_then_else (match_operand 0 "register_operand" "")
12395 (const_string "2")
12396 (const_string "*")))])
12397
12398 (define_insn "*rotlqi3_1_one_bit"
12399 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12400 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const1_operand" "")))
12402 (clobber (reg:CC 17))]
12403 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12404 && (TARGET_SHIFT1 || optimize_size)"
12405 "rol{b}\t%0"
12406 [(set_attr "type" "rotate")
12407 (set (attr "length")
12408 (if_then_else (match_operand 0 "register_operand" "")
12409 (const_string "2")
12410 (const_string "*")))])
12411
12412 (define_insn "*rotlqi3_1_slp"
12413 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12414 (rotate:QI (match_dup 0)
12415 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12416 (clobber (reg:CC 17))]
12417 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12418 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12419 "@
12420 rol{b}\t{%1, %0|%0, %1}
12421 rol{b}\t{%b1, %0|%0, %b1}"
12422 [(set_attr "type" "rotate1")
12423 (set_attr "mode" "QI")])
12424
12425 (define_insn "*rotlqi3_1"
12426 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12427 (rotate: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 (ROTATE, QImode, operands)"
12431 "@
12432 rol{b}\t{%2, %0|%0, %2}
12433 rol{b}\t{%b2, %0|%0, %b2}"
12434 [(set_attr "type" "rotate")
12435 (set_attr "mode" "QI")])
12436
12437 (define_expand "rotrdi3"
12438 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12439 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12440 (match_operand:QI 2 "nonmemory_operand" "")))
12441 (clobber (reg:CC 17))]
12442 "TARGET_64BIT"
12443 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12444
12445 (define_insn "*rotrdi3_1_one_bit_rex64"
12446 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12447 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12448 (match_operand:QI 2 "const1_operand" "")))
12449 (clobber (reg:CC 17))]
12450 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12451 && (TARGET_SHIFT1 || optimize_size)"
12452 "ror{q}\t%0"
12453 [(set_attr "type" "rotate")
12454 (set (attr "length")
12455 (if_then_else (match_operand:DI 0 "register_operand" "")
12456 (const_string "2")
12457 (const_string "*")))])
12458
12459 (define_insn "*rotrdi3_1_rex64"
12460 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12461 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12462 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12463 (clobber (reg:CC 17))]
12464 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12465 "@
12466 ror{q}\t{%2, %0|%0, %2}
12467 ror{q}\t{%b2, %0|%0, %b2}"
12468 [(set_attr "type" "rotate")
12469 (set_attr "mode" "DI")])
12470
12471 (define_expand "rotrsi3"
12472 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12473 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12474 (match_operand:QI 2 "nonmemory_operand" "")))
12475 (clobber (reg:CC 17))]
12476 ""
12477 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12478
12479 (define_insn "*rotrsi3_1_one_bit"
12480 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12481 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12482 (match_operand:QI 2 "const1_operand" "")))
12483 (clobber (reg:CC 17))]
12484 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12485 && (TARGET_SHIFT1 || optimize_size)"
12486 "ror{l}\t%0"
12487 [(set_attr "type" "rotate")
12488 (set (attr "length")
12489 (if_then_else (match_operand:SI 0 "register_operand" "")
12490 (const_string "2")
12491 (const_string "*")))])
12492
12493 (define_insn "*rotrsi3_1_one_bit_zext"
12494 [(set (match_operand:DI 0 "register_operand" "=r")
12495 (zero_extend:DI
12496 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12497 (match_operand:QI 2 "const1_operand" ""))))
12498 (clobber (reg:CC 17))]
12499 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12500 && (TARGET_SHIFT1 || optimize_size)"
12501 "ror{l}\t%k0"
12502 [(set_attr "type" "rotate")
12503 (set (attr "length")
12504 (if_then_else (match_operand:SI 0 "register_operand" "")
12505 (const_string "2")
12506 (const_string "*")))])
12507
12508 (define_insn "*rotrsi3_1"
12509 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12510 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12511 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12512 (clobber (reg:CC 17))]
12513 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12514 "@
12515 ror{l}\t{%2, %0|%0, %2}
12516 ror{l}\t{%b2, %0|%0, %b2}"
12517 [(set_attr "type" "rotate")
12518 (set_attr "mode" "SI")])
12519
12520 (define_insn "*rotrsi3_1_zext"
12521 [(set (match_operand:DI 0 "register_operand" "=r,r")
12522 (zero_extend:DI
12523 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12524 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12525 (clobber (reg:CC 17))]
12526 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12527 "@
12528 ror{l}\t{%2, %k0|%k0, %2}
12529 ror{l}\t{%b2, %k0|%k0, %b2}"
12530 [(set_attr "type" "rotate")
12531 (set_attr "mode" "SI")])
12532
12533 (define_expand "rotrhi3"
12534 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12535 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12536 (match_operand:QI 2 "nonmemory_operand" "")))
12537 (clobber (reg:CC 17))]
12538 "TARGET_HIMODE_MATH"
12539 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12540
12541 (define_insn "*rotrhi3_one_bit"
12542 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12543 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12544 (match_operand:QI 2 "const1_operand" "")))
12545 (clobber (reg:CC 17))]
12546 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12547 && (TARGET_SHIFT1 || optimize_size)"
12548 "ror{w}\t%0"
12549 [(set_attr "type" "rotate")
12550 (set (attr "length")
12551 (if_then_else (match_operand 0 "register_operand" "")
12552 (const_string "2")
12553 (const_string "*")))])
12554
12555 (define_insn "*rotrhi3"
12556 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12557 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12558 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12559 (clobber (reg:CC 17))]
12560 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12561 "@
12562 ror{w}\t{%2, %0|%0, %2}
12563 ror{w}\t{%b2, %0|%0, %b2}"
12564 [(set_attr "type" "rotate")
12565 (set_attr "mode" "HI")])
12566
12567 (define_expand "rotrqi3"
12568 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12569 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12570 (match_operand:QI 2 "nonmemory_operand" "")))
12571 (clobber (reg:CC 17))]
12572 "TARGET_QIMODE_MATH"
12573 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12574
12575 (define_insn "*rotrqi3_1_one_bit"
12576 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12577 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12578 (match_operand:QI 2 "const1_operand" "")))
12579 (clobber (reg:CC 17))]
12580 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12581 && (TARGET_SHIFT1 || optimize_size)"
12582 "ror{b}\t%0"
12583 [(set_attr "type" "rotate")
12584 (set (attr "length")
12585 (if_then_else (match_operand 0 "register_operand" "")
12586 (const_string "2")
12587 (const_string "*")))])
12588
12589 (define_insn "*rotrqi3_1_one_bit_slp"
12590 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12591 (rotatert:QI (match_dup 0)
12592 (match_operand:QI 1 "const1_operand" "")))
12593 (clobber (reg:CC 17))]
12594 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12595 && (TARGET_SHIFT1 || optimize_size)"
12596 "ror{b}\t%0"
12597 [(set_attr "type" "rotate1")
12598 (set (attr "length")
12599 (if_then_else (match_operand 0 "register_operand" "")
12600 (const_string "2")
12601 (const_string "*")))])
12602
12603 (define_insn "*rotrqi3_1"
12604 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12605 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12606 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12607 (clobber (reg:CC 17))]
12608 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12609 "@
12610 ror{b}\t{%2, %0|%0, %2}
12611 ror{b}\t{%b2, %0|%0, %b2}"
12612 [(set_attr "type" "rotate")
12613 (set_attr "mode" "QI")])
12614
12615 (define_insn "*rotrqi3_1_slp"
12616 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12617 (rotatert:QI (match_dup 0)
12618 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12619 (clobber (reg:CC 17))]
12620 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12621 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12622 "@
12623 ror{b}\t{%1, %0|%0, %1}
12624 ror{b}\t{%b1, %0|%0, %b1}"
12625 [(set_attr "type" "rotate1")
12626 (set_attr "mode" "QI")])
12627 \f
12628 ;; Bit set / bit test instructions
12629
12630 (define_expand "extv"
12631 [(set (match_operand:SI 0 "register_operand" "")
12632 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12633 (match_operand:SI 2 "immediate_operand" "")
12634 (match_operand:SI 3 "immediate_operand" "")))]
12635 ""
12636 {
12637 /* Handle extractions from %ah et al. */
12638 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12639 FAIL;
12640
12641 /* From mips.md: extract_bit_field doesn't verify that our source
12642 matches the predicate, so check it again here. */
12643 if (! register_operand (operands[1], VOIDmode))
12644 FAIL;
12645 })
12646
12647 (define_expand "extzv"
12648 [(set (match_operand:SI 0 "register_operand" "")
12649 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12650 (match_operand:SI 2 "immediate_operand" "")
12651 (match_operand:SI 3 "immediate_operand" "")))]
12652 ""
12653 {
12654 /* Handle extractions from %ah et al. */
12655 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12656 FAIL;
12657
12658 /* From mips.md: extract_bit_field doesn't verify that our source
12659 matches the predicate, so check it again here. */
12660 if (! register_operand (operands[1], VOIDmode))
12661 FAIL;
12662 })
12663
12664 (define_expand "insv"
12665 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12666 (match_operand:SI 1 "immediate_operand" "")
12667 (match_operand:SI 2 "immediate_operand" ""))
12668 (match_operand:SI 3 "register_operand" ""))]
12669 ""
12670 {
12671 /* Handle extractions from %ah et al. */
12672 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12673 FAIL;
12674
12675 /* From mips.md: insert_bit_field doesn't verify that our source
12676 matches the predicate, so check it again here. */
12677 if (! register_operand (operands[0], VOIDmode))
12678 FAIL;
12679 })
12680
12681 ;; %%% bts, btr, btc, bt.
12682 \f
12683 ;; Store-flag instructions.
12684
12685 ;; For all sCOND expanders, also expand the compare or test insn that
12686 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12687
12688 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12689 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12690 ;; way, which can later delete the movzx if only QImode is needed.
12691
12692 (define_expand "seq"
12693 [(set (match_operand:QI 0 "register_operand" "")
12694 (eq:QI (reg:CC 17) (const_int 0)))]
12695 ""
12696 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12697
12698 (define_expand "sne"
12699 [(set (match_operand:QI 0 "register_operand" "")
12700 (ne:QI (reg:CC 17) (const_int 0)))]
12701 ""
12702 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12703
12704 (define_expand "sgt"
12705 [(set (match_operand:QI 0 "register_operand" "")
12706 (gt:QI (reg:CC 17) (const_int 0)))]
12707 ""
12708 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12709
12710 (define_expand "sgtu"
12711 [(set (match_operand:QI 0 "register_operand" "")
12712 (gtu:QI (reg:CC 17) (const_int 0)))]
12713 ""
12714 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12715
12716 (define_expand "slt"
12717 [(set (match_operand:QI 0 "register_operand" "")
12718 (lt:QI (reg:CC 17) (const_int 0)))]
12719 ""
12720 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12721
12722 (define_expand "sltu"
12723 [(set (match_operand:QI 0 "register_operand" "")
12724 (ltu:QI (reg:CC 17) (const_int 0)))]
12725 ""
12726 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12727
12728 (define_expand "sge"
12729 [(set (match_operand:QI 0 "register_operand" "")
12730 (ge:QI (reg:CC 17) (const_int 0)))]
12731 ""
12732 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12733
12734 (define_expand "sgeu"
12735 [(set (match_operand:QI 0 "register_operand" "")
12736 (geu:QI (reg:CC 17) (const_int 0)))]
12737 ""
12738 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12739
12740 (define_expand "sle"
12741 [(set (match_operand:QI 0 "register_operand" "")
12742 (le:QI (reg:CC 17) (const_int 0)))]
12743 ""
12744 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12745
12746 (define_expand "sleu"
12747 [(set (match_operand:QI 0 "register_operand" "")
12748 (leu:QI (reg:CC 17) (const_int 0)))]
12749 ""
12750 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12751
12752 (define_expand "sunordered"
12753 [(set (match_operand:QI 0 "register_operand" "")
12754 (unordered:QI (reg:CC 17) (const_int 0)))]
12755 "TARGET_80387 || TARGET_SSE"
12756 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12757
12758 (define_expand "sordered"
12759 [(set (match_operand:QI 0 "register_operand" "")
12760 (ordered:QI (reg:CC 17) (const_int 0)))]
12761 "TARGET_80387"
12762 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12763
12764 (define_expand "suneq"
12765 [(set (match_operand:QI 0 "register_operand" "")
12766 (uneq:QI (reg:CC 17) (const_int 0)))]
12767 "TARGET_80387 || TARGET_SSE"
12768 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12769
12770 (define_expand "sunge"
12771 [(set (match_operand:QI 0 "register_operand" "")
12772 (unge:QI (reg:CC 17) (const_int 0)))]
12773 "TARGET_80387 || TARGET_SSE"
12774 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12775
12776 (define_expand "sungt"
12777 [(set (match_operand:QI 0 "register_operand" "")
12778 (ungt:QI (reg:CC 17) (const_int 0)))]
12779 "TARGET_80387 || TARGET_SSE"
12780 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12781
12782 (define_expand "sunle"
12783 [(set (match_operand:QI 0 "register_operand" "")
12784 (unle:QI (reg:CC 17) (const_int 0)))]
12785 "TARGET_80387 || TARGET_SSE"
12786 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12787
12788 (define_expand "sunlt"
12789 [(set (match_operand:QI 0 "register_operand" "")
12790 (unlt:QI (reg:CC 17) (const_int 0)))]
12791 "TARGET_80387 || TARGET_SSE"
12792 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12793
12794 (define_expand "sltgt"
12795 [(set (match_operand:QI 0 "register_operand" "")
12796 (ltgt:QI (reg:CC 17) (const_int 0)))]
12797 "TARGET_80387 || TARGET_SSE"
12798 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12799
12800 (define_insn "*setcc_1"
12801 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12802 (match_operator:QI 1 "ix86_comparison_operator"
12803 [(reg 17) (const_int 0)]))]
12804 ""
12805 "set%C1\t%0"
12806 [(set_attr "type" "setcc")
12807 (set_attr "mode" "QI")])
12808
12809 (define_insn "setcc_2"
12810 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12811 (match_operator:QI 1 "ix86_comparison_operator"
12812 [(reg 17) (const_int 0)]))]
12813 ""
12814 "set%C1\t%0"
12815 [(set_attr "type" "setcc")
12816 (set_attr "mode" "QI")])
12817
12818 ;; In general it is not safe to assume too much about CCmode registers,
12819 ;; so simplify-rtx stops when it sees a second one. Under certain
12820 ;; conditions this is safe on x86, so help combine not create
12821 ;;
12822 ;; seta %al
12823 ;; testb %al, %al
12824 ;; sete %al
12825
12826 (define_split
12827 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12828 (ne:QI (match_operator 1 "ix86_comparison_operator"
12829 [(reg 17) (const_int 0)])
12830 (const_int 0)))]
12831 ""
12832 [(set (match_dup 0) (match_dup 1))]
12833 {
12834 PUT_MODE (operands[1], QImode);
12835 })
12836
12837 (define_split
12838 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12839 (ne:QI (match_operator 1 "ix86_comparison_operator"
12840 [(reg 17) (const_int 0)])
12841 (const_int 0)))]
12842 ""
12843 [(set (match_dup 0) (match_dup 1))]
12844 {
12845 PUT_MODE (operands[1], QImode);
12846 })
12847
12848 (define_split
12849 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12850 (eq:QI (match_operator 1 "ix86_comparison_operator"
12851 [(reg 17) (const_int 0)])
12852 (const_int 0)))]
12853 ""
12854 [(set (match_dup 0) (match_dup 1))]
12855 {
12856 rtx new_op1 = copy_rtx (operands[1]);
12857 operands[1] = new_op1;
12858 PUT_MODE (new_op1, QImode);
12859 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12860 GET_MODE (XEXP (new_op1, 0))));
12861
12862 /* Make sure that (a) the CCmode we have for the flags is strong
12863 enough for the reversed compare or (b) we have a valid FP compare. */
12864 if (! ix86_comparison_operator (new_op1, VOIDmode))
12865 FAIL;
12866 })
12867
12868 (define_split
12869 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12870 (eq:QI (match_operator 1 "ix86_comparison_operator"
12871 [(reg 17) (const_int 0)])
12872 (const_int 0)))]
12873 ""
12874 [(set (match_dup 0) (match_dup 1))]
12875 {
12876 rtx new_op1 = copy_rtx (operands[1]);
12877 operands[1] = new_op1;
12878 PUT_MODE (new_op1, QImode);
12879 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12880 GET_MODE (XEXP (new_op1, 0))));
12881
12882 /* Make sure that (a) the CCmode we have for the flags is strong
12883 enough for the reversed compare or (b) we have a valid FP compare. */
12884 if (! ix86_comparison_operator (new_op1, VOIDmode))
12885 FAIL;
12886 })
12887
12888 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12889 ;; subsequent logical operations are used to imitate conditional moves.
12890 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12891 ;; it directly. Further holding this value in pseudo register might bring
12892 ;; problem in implicit normalization in spill code.
12893 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12894 ;; instructions after reload by splitting the conditional move patterns.
12895
12896 (define_insn "*sse_setccsf"
12897 [(set (match_operand:SF 0 "register_operand" "=x")
12898 (match_operator:SF 1 "sse_comparison_operator"
12899 [(match_operand:SF 2 "register_operand" "0")
12900 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12901 "TARGET_SSE && reload_completed"
12902 "cmp%D1ss\t{%3, %0|%0, %3}"
12903 [(set_attr "type" "ssecmp")
12904 (set_attr "mode" "SF")])
12905
12906 (define_insn "*sse_setccdf"
12907 [(set (match_operand:DF 0 "register_operand" "=Y")
12908 (match_operator:DF 1 "sse_comparison_operator"
12909 [(match_operand:DF 2 "register_operand" "0")
12910 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12911 "TARGET_SSE2 && reload_completed"
12912 "cmp%D1sd\t{%3, %0|%0, %3}"
12913 [(set_attr "type" "ssecmp")
12914 (set_attr "mode" "DF")])
12915 \f
12916 ;; Basic conditional jump instructions.
12917 ;; We ignore the overflow flag for signed branch instructions.
12918
12919 ;; For all bCOND expanders, also expand the compare or test insn that
12920 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12921
12922 (define_expand "beq"
12923 [(set (pc)
12924 (if_then_else (match_dup 1)
12925 (label_ref (match_operand 0 "" ""))
12926 (pc)))]
12927 ""
12928 "ix86_expand_branch (EQ, operands[0]); DONE;")
12929
12930 (define_expand "bne"
12931 [(set (pc)
12932 (if_then_else (match_dup 1)
12933 (label_ref (match_operand 0 "" ""))
12934 (pc)))]
12935 ""
12936 "ix86_expand_branch (NE, operands[0]); DONE;")
12937
12938 (define_expand "bgt"
12939 [(set (pc)
12940 (if_then_else (match_dup 1)
12941 (label_ref (match_operand 0 "" ""))
12942 (pc)))]
12943 ""
12944 "ix86_expand_branch (GT, operands[0]); DONE;")
12945
12946 (define_expand "bgtu"
12947 [(set (pc)
12948 (if_then_else (match_dup 1)
12949 (label_ref (match_operand 0 "" ""))
12950 (pc)))]
12951 ""
12952 "ix86_expand_branch (GTU, operands[0]); DONE;")
12953
12954 (define_expand "blt"
12955 [(set (pc)
12956 (if_then_else (match_dup 1)
12957 (label_ref (match_operand 0 "" ""))
12958 (pc)))]
12959 ""
12960 "ix86_expand_branch (LT, operands[0]); DONE;")
12961
12962 (define_expand "bltu"
12963 [(set (pc)
12964 (if_then_else (match_dup 1)
12965 (label_ref (match_operand 0 "" ""))
12966 (pc)))]
12967 ""
12968 "ix86_expand_branch (LTU, operands[0]); DONE;")
12969
12970 (define_expand "bge"
12971 [(set (pc)
12972 (if_then_else (match_dup 1)
12973 (label_ref (match_operand 0 "" ""))
12974 (pc)))]
12975 ""
12976 "ix86_expand_branch (GE, operands[0]); DONE;")
12977
12978 (define_expand "bgeu"
12979 [(set (pc)
12980 (if_then_else (match_dup 1)
12981 (label_ref (match_operand 0 "" ""))
12982 (pc)))]
12983 ""
12984 "ix86_expand_branch (GEU, operands[0]); DONE;")
12985
12986 (define_expand "ble"
12987 [(set (pc)
12988 (if_then_else (match_dup 1)
12989 (label_ref (match_operand 0 "" ""))
12990 (pc)))]
12991 ""
12992 "ix86_expand_branch (LE, operands[0]); DONE;")
12993
12994 (define_expand "bleu"
12995 [(set (pc)
12996 (if_then_else (match_dup 1)
12997 (label_ref (match_operand 0 "" ""))
12998 (pc)))]
12999 ""
13000 "ix86_expand_branch (LEU, operands[0]); DONE;")
13001
13002 (define_expand "bunordered"
13003 [(set (pc)
13004 (if_then_else (match_dup 1)
13005 (label_ref (match_operand 0 "" ""))
13006 (pc)))]
13007 "TARGET_80387 || TARGET_SSE"
13008 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13009
13010 (define_expand "bordered"
13011 [(set (pc)
13012 (if_then_else (match_dup 1)
13013 (label_ref (match_operand 0 "" ""))
13014 (pc)))]
13015 "TARGET_80387 || TARGET_SSE"
13016 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13017
13018 (define_expand "buneq"
13019 [(set (pc)
13020 (if_then_else (match_dup 1)
13021 (label_ref (match_operand 0 "" ""))
13022 (pc)))]
13023 "TARGET_80387 || TARGET_SSE"
13024 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13025
13026 (define_expand "bunge"
13027 [(set (pc)
13028 (if_then_else (match_dup 1)
13029 (label_ref (match_operand 0 "" ""))
13030 (pc)))]
13031 "TARGET_80387 || TARGET_SSE"
13032 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13033
13034 (define_expand "bungt"
13035 [(set (pc)
13036 (if_then_else (match_dup 1)
13037 (label_ref (match_operand 0 "" ""))
13038 (pc)))]
13039 "TARGET_80387 || TARGET_SSE"
13040 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13041
13042 (define_expand "bunle"
13043 [(set (pc)
13044 (if_then_else (match_dup 1)
13045 (label_ref (match_operand 0 "" ""))
13046 (pc)))]
13047 "TARGET_80387 || TARGET_SSE"
13048 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13049
13050 (define_expand "bunlt"
13051 [(set (pc)
13052 (if_then_else (match_dup 1)
13053 (label_ref (match_operand 0 "" ""))
13054 (pc)))]
13055 "TARGET_80387 || TARGET_SSE"
13056 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13057
13058 (define_expand "bltgt"
13059 [(set (pc)
13060 (if_then_else (match_dup 1)
13061 (label_ref (match_operand 0 "" ""))
13062 (pc)))]
13063 "TARGET_80387 || TARGET_SSE"
13064 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13065
13066 (define_insn "*jcc_1"
13067 [(set (pc)
13068 (if_then_else (match_operator 1 "ix86_comparison_operator"
13069 [(reg 17) (const_int 0)])
13070 (label_ref (match_operand 0 "" ""))
13071 (pc)))]
13072 ""
13073 "%+j%C1\t%l0"
13074 [(set_attr "type" "ibr")
13075 (set_attr "modrm" "0")
13076 (set (attr "length")
13077 (if_then_else (and (ge (minus (match_dup 0) (pc))
13078 (const_int -126))
13079 (lt (minus (match_dup 0) (pc))
13080 (const_int 128)))
13081 (const_int 2)
13082 (const_int 6)))])
13083
13084 (define_insn "*jcc_2"
13085 [(set (pc)
13086 (if_then_else (match_operator 1 "ix86_comparison_operator"
13087 [(reg 17) (const_int 0)])
13088 (pc)
13089 (label_ref (match_operand 0 "" ""))))]
13090 ""
13091 "%+j%c1\t%l0"
13092 [(set_attr "type" "ibr")
13093 (set_attr "modrm" "0")
13094 (set (attr "length")
13095 (if_then_else (and (ge (minus (match_dup 0) (pc))
13096 (const_int -126))
13097 (lt (minus (match_dup 0) (pc))
13098 (const_int 128)))
13099 (const_int 2)
13100 (const_int 6)))])
13101
13102 ;; In general it is not safe to assume too much about CCmode registers,
13103 ;; so simplify-rtx stops when it sees a second one. Under certain
13104 ;; conditions this is safe on x86, so help combine not create
13105 ;;
13106 ;; seta %al
13107 ;; testb %al, %al
13108 ;; je Lfoo
13109
13110 (define_split
13111 [(set (pc)
13112 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13113 [(reg 17) (const_int 0)])
13114 (const_int 0))
13115 (label_ref (match_operand 1 "" ""))
13116 (pc)))]
13117 ""
13118 [(set (pc)
13119 (if_then_else (match_dup 0)
13120 (label_ref (match_dup 1))
13121 (pc)))]
13122 {
13123 PUT_MODE (operands[0], VOIDmode);
13124 })
13125
13126 (define_split
13127 [(set (pc)
13128 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13129 [(reg 17) (const_int 0)])
13130 (const_int 0))
13131 (label_ref (match_operand 1 "" ""))
13132 (pc)))]
13133 ""
13134 [(set (pc)
13135 (if_then_else (match_dup 0)
13136 (label_ref (match_dup 1))
13137 (pc)))]
13138 {
13139 rtx new_op0 = copy_rtx (operands[0]);
13140 operands[0] = new_op0;
13141 PUT_MODE (new_op0, VOIDmode);
13142 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13143 GET_MODE (XEXP (new_op0, 0))));
13144
13145 /* Make sure that (a) the CCmode we have for the flags is strong
13146 enough for the reversed compare or (b) we have a valid FP compare. */
13147 if (! ix86_comparison_operator (new_op0, VOIDmode))
13148 FAIL;
13149 })
13150
13151 ;; Define combination compare-and-branch fp compare instructions to use
13152 ;; during early optimization. Splitting the operation apart early makes
13153 ;; for bad code when we want to reverse the operation.
13154
13155 (define_insn "*fp_jcc_1"
13156 [(set (pc)
13157 (if_then_else (match_operator 0 "comparison_operator"
13158 [(match_operand 1 "register_operand" "f")
13159 (match_operand 2 "register_operand" "f")])
13160 (label_ref (match_operand 3 "" ""))
13161 (pc)))
13162 (clobber (reg:CCFP 18))
13163 (clobber (reg:CCFP 17))]
13164 "TARGET_CMOVE && TARGET_80387
13165 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13166 && FLOAT_MODE_P (GET_MODE (operands[1]))
13167 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13168 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13169 "#")
13170
13171 (define_insn "*fp_jcc_1_sse"
13172 [(set (pc)
13173 (if_then_else (match_operator 0 "comparison_operator"
13174 [(match_operand 1 "register_operand" "f#x,x#f")
13175 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13176 (label_ref (match_operand 3 "" ""))
13177 (pc)))
13178 (clobber (reg:CCFP 18))
13179 (clobber (reg:CCFP 17))]
13180 "TARGET_80387
13181 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13182 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13183 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13184 "#")
13185
13186 (define_insn "*fp_jcc_1_sse_only"
13187 [(set (pc)
13188 (if_then_else (match_operator 0 "comparison_operator"
13189 [(match_operand 1 "register_operand" "x")
13190 (match_operand 2 "nonimmediate_operand" "xm")])
13191 (label_ref (match_operand 3 "" ""))
13192 (pc)))
13193 (clobber (reg:CCFP 18))
13194 (clobber (reg:CCFP 17))]
13195 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198 "#")
13199
13200 (define_insn "*fp_jcc_2"
13201 [(set (pc)
13202 (if_then_else (match_operator 0 "comparison_operator"
13203 [(match_operand 1 "register_operand" "f")
13204 (match_operand 2 "register_operand" "f")])
13205 (pc)
13206 (label_ref (match_operand 3 "" ""))))
13207 (clobber (reg:CCFP 18))
13208 (clobber (reg:CCFP 17))]
13209 "TARGET_CMOVE && TARGET_80387
13210 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13211 && FLOAT_MODE_P (GET_MODE (operands[1]))
13212 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13213 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214 "#")
13215
13216 (define_insn "*fp_jcc_2_sse"
13217 [(set (pc)
13218 (if_then_else (match_operator 0 "comparison_operator"
13219 [(match_operand 1 "register_operand" "f#x,x#f")
13220 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13221 (pc)
13222 (label_ref (match_operand 3 "" ""))))
13223 (clobber (reg:CCFP 18))
13224 (clobber (reg:CCFP 17))]
13225 "TARGET_80387
13226 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13227 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13228 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13229 "#")
13230
13231 (define_insn "*fp_jcc_2_sse_only"
13232 [(set (pc)
13233 (if_then_else (match_operator 0 "comparison_operator"
13234 [(match_operand 1 "register_operand" "x")
13235 (match_operand 2 "nonimmediate_operand" "xm")])
13236 (pc)
13237 (label_ref (match_operand 3 "" ""))))
13238 (clobber (reg:CCFP 18))
13239 (clobber (reg:CCFP 17))]
13240 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13241 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243 "#")
13244
13245 (define_insn "*fp_jcc_3"
13246 [(set (pc)
13247 (if_then_else (match_operator 0 "comparison_operator"
13248 [(match_operand 1 "register_operand" "f")
13249 (match_operand 2 "nonimmediate_operand" "fm")])
13250 (label_ref (match_operand 3 "" ""))
13251 (pc)))
13252 (clobber (reg:CCFP 18))
13253 (clobber (reg:CCFP 17))
13254 (clobber (match_scratch:HI 4 "=a"))]
13255 "TARGET_80387
13256 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13257 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13258 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13259 && SELECT_CC_MODE (GET_CODE (operands[0]),
13260 operands[1], operands[2]) == CCFPmode
13261 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13262 "#")
13263
13264 (define_insn "*fp_jcc_4"
13265 [(set (pc)
13266 (if_then_else (match_operator 0 "comparison_operator"
13267 [(match_operand 1 "register_operand" "f")
13268 (match_operand 2 "nonimmediate_operand" "fm")])
13269 (pc)
13270 (label_ref (match_operand 3 "" ""))))
13271 (clobber (reg:CCFP 18))
13272 (clobber (reg:CCFP 17))
13273 (clobber (match_scratch:HI 4 "=a"))]
13274 "TARGET_80387
13275 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13276 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13277 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13278 && SELECT_CC_MODE (GET_CODE (operands[0]),
13279 operands[1], operands[2]) == CCFPmode
13280 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13281 "#")
13282
13283 (define_insn "*fp_jcc_5"
13284 [(set (pc)
13285 (if_then_else (match_operator 0 "comparison_operator"
13286 [(match_operand 1 "register_operand" "f")
13287 (match_operand 2 "register_operand" "f")])
13288 (label_ref (match_operand 3 "" ""))
13289 (pc)))
13290 (clobber (reg:CCFP 18))
13291 (clobber (reg:CCFP 17))
13292 (clobber (match_scratch:HI 4 "=a"))]
13293 "TARGET_80387
13294 && FLOAT_MODE_P (GET_MODE (operands[1]))
13295 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13296 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13297 "#")
13298
13299 (define_insn "*fp_jcc_6"
13300 [(set (pc)
13301 (if_then_else (match_operator 0 "comparison_operator"
13302 [(match_operand 1 "register_operand" "f")
13303 (match_operand 2 "register_operand" "f")])
13304 (pc)
13305 (label_ref (match_operand 3 "" ""))))
13306 (clobber (reg:CCFP 18))
13307 (clobber (reg:CCFP 17))
13308 (clobber (match_scratch:HI 4 "=a"))]
13309 "TARGET_80387
13310 && FLOAT_MODE_P (GET_MODE (operands[1]))
13311 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13312 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13313 "#")
13314
13315 (define_split
13316 [(set (pc)
13317 (if_then_else (match_operator 0 "comparison_operator"
13318 [(match_operand 1 "register_operand" "")
13319 (match_operand 2 "nonimmediate_operand" "")])
13320 (match_operand 3 "" "")
13321 (match_operand 4 "" "")))
13322 (clobber (reg:CCFP 18))
13323 (clobber (reg:CCFP 17))]
13324 "reload_completed"
13325 [(const_int 0)]
13326 {
13327 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13328 operands[3], operands[4], NULL_RTX);
13329 DONE;
13330 })
13331
13332 (define_split
13333 [(set (pc)
13334 (if_then_else (match_operator 0 "comparison_operator"
13335 [(match_operand 1 "register_operand" "")
13336 (match_operand 2 "nonimmediate_operand" "")])
13337 (match_operand 3 "" "")
13338 (match_operand 4 "" "")))
13339 (clobber (reg:CCFP 18))
13340 (clobber (reg:CCFP 17))
13341 (clobber (match_scratch:HI 5 "=a"))]
13342 "reload_completed"
13343 [(set (pc)
13344 (if_then_else (match_dup 6)
13345 (match_dup 3)
13346 (match_dup 4)))]
13347 {
13348 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13349 operands[3], operands[4], operands[5]);
13350 DONE;
13351 })
13352 \f
13353 ;; Unconditional and other jump instructions
13354
13355 (define_insn "jump"
13356 [(set (pc)
13357 (label_ref (match_operand 0 "" "")))]
13358 ""
13359 "jmp\t%l0"
13360 [(set_attr "type" "ibr")
13361 (set (attr "length")
13362 (if_then_else (and (ge (minus (match_dup 0) (pc))
13363 (const_int -126))
13364 (lt (minus (match_dup 0) (pc))
13365 (const_int 128)))
13366 (const_int 2)
13367 (const_int 5)))
13368 (set_attr "modrm" "0")])
13369
13370 (define_expand "indirect_jump"
13371 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13372 ""
13373 "")
13374
13375 (define_insn "*indirect_jump"
13376 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13377 "!TARGET_64BIT"
13378 "jmp\t%A0"
13379 [(set_attr "type" "ibr")
13380 (set_attr "length_immediate" "0")])
13381
13382 (define_insn "*indirect_jump_rtx64"
13383 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13384 "TARGET_64BIT"
13385 "jmp\t%A0"
13386 [(set_attr "type" "ibr")
13387 (set_attr "length_immediate" "0")])
13388
13389 (define_expand "tablejump"
13390 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13391 (use (label_ref (match_operand 1 "" "")))])]
13392 ""
13393 {
13394 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13395 relative. Convert the relative address to an absolute address. */
13396 if (flag_pic)
13397 {
13398 rtx op0, op1;
13399 enum rtx_code code;
13400
13401 if (TARGET_64BIT)
13402 {
13403 code = PLUS;
13404 op0 = operands[0];
13405 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13406 }
13407 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13408 {
13409 code = PLUS;
13410 op0 = operands[0];
13411 op1 = pic_offset_table_rtx;
13412 }
13413 else
13414 {
13415 code = MINUS;
13416 op0 = pic_offset_table_rtx;
13417 op1 = operands[0];
13418 }
13419
13420 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13421 OPTAB_DIRECT);
13422 }
13423 })
13424
13425 (define_insn "*tablejump_1"
13426 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13427 (use (label_ref (match_operand 1 "" "")))]
13428 "!TARGET_64BIT"
13429 "jmp\t%A0"
13430 [(set_attr "type" "ibr")
13431 (set_attr "length_immediate" "0")])
13432
13433 (define_insn "*tablejump_1_rtx64"
13434 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13435 (use (label_ref (match_operand 1 "" "")))]
13436 "TARGET_64BIT"
13437 "jmp\t%A0"
13438 [(set_attr "type" "ibr")
13439 (set_attr "length_immediate" "0")])
13440 \f
13441 ;; Loop instruction
13442 ;;
13443 ;; This is all complicated by the fact that since this is a jump insn
13444 ;; we must handle our own reloads.
13445
13446 (define_expand "doloop_end"
13447 [(use (match_operand 0 "" "")) ; loop pseudo
13448 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13449 (use (match_operand 2 "" "")) ; max iterations
13450 (use (match_operand 3 "" "")) ; loop level
13451 (use (match_operand 4 "" ""))] ; label
13452 "!TARGET_64BIT && TARGET_USE_LOOP"
13453 "
13454 {
13455 /* Only use cloop on innermost loops. */
13456 if (INTVAL (operands[3]) > 1)
13457 FAIL;
13458 if (GET_MODE (operands[0]) != SImode)
13459 FAIL;
13460 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13461 operands[0]));
13462 DONE;
13463 }")
13464
13465 (define_insn "doloop_end_internal"
13466 [(set (pc)
13467 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13468 (const_int 1))
13469 (label_ref (match_operand 0 "" ""))
13470 (pc)))
13471 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13472 (plus:SI (match_dup 1)
13473 (const_int -1)))
13474 (clobber (match_scratch:SI 3 "=X,X,r"))
13475 (clobber (reg:CC 17))]
13476 "!TARGET_64BIT && TARGET_USE_LOOP
13477 && (reload_in_progress || reload_completed
13478 || register_operand (operands[2], VOIDmode))"
13479 {
13480 if (which_alternative != 0)
13481 return "#";
13482 if (get_attr_length (insn) == 2)
13483 return "%+loop\t%l0";
13484 else
13485 return "dec{l}\t%1\;%+jne\t%l0";
13486 }
13487 [(set_attr "ppro_uops" "many")
13488 (set (attr "length")
13489 (if_then_else (and (eq_attr "alternative" "0")
13490 (and (ge (minus (match_dup 0) (pc))
13491 (const_int -126))
13492 (lt (minus (match_dup 0) (pc))
13493 (const_int 128))))
13494 (const_int 2)
13495 (const_int 16)))
13496 ;; We don't know the type before shorten branches. Optimistically expect
13497 ;; the loop instruction to match.
13498 (set (attr "type") (const_string "ibr"))])
13499
13500 (define_split
13501 [(set (pc)
13502 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13503 (const_int 1))
13504 (match_operand 0 "" "")
13505 (pc)))
13506 (set (match_dup 1)
13507 (plus:SI (match_dup 1)
13508 (const_int -1)))
13509 (clobber (match_scratch:SI 2 ""))
13510 (clobber (reg:CC 17))]
13511 "!TARGET_64BIT && TARGET_USE_LOOP
13512 && reload_completed
13513 && REGNO (operands[1]) != 2"
13514 [(parallel [(set (reg:CCZ 17)
13515 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13516 (const_int 0)))
13517 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13518 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13519 (match_dup 0)
13520 (pc)))]
13521 "")
13522
13523 (define_split
13524 [(set (pc)
13525 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13526 (const_int 1))
13527 (match_operand 0 "" "")
13528 (pc)))
13529 (set (match_operand:SI 2 "nonimmediate_operand" "")
13530 (plus:SI (match_dup 1)
13531 (const_int -1)))
13532 (clobber (match_scratch:SI 3 ""))
13533 (clobber (reg:CC 17))]
13534 "!TARGET_64BIT && TARGET_USE_LOOP
13535 && reload_completed
13536 && (! REG_P (operands[2])
13537 || ! rtx_equal_p (operands[1], operands[2]))"
13538 [(set (match_dup 3) (match_dup 1))
13539 (parallel [(set (reg:CCZ 17)
13540 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13541 (const_int 0)))
13542 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13543 (set (match_dup 2) (match_dup 3))
13544 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13545 (match_dup 0)
13546 (pc)))]
13547 "")
13548
13549 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13550
13551 (define_peephole2
13552 [(set (reg 17) (match_operand 0 "" ""))
13553 (set (match_operand:QI 1 "register_operand" "")
13554 (match_operator:QI 2 "ix86_comparison_operator"
13555 [(reg 17) (const_int 0)]))
13556 (set (match_operand 3 "q_regs_operand" "")
13557 (zero_extend (match_dup 1)))]
13558 "(peep2_reg_dead_p (3, operands[1])
13559 || operands_match_p (operands[1], operands[3]))
13560 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13561 [(set (match_dup 4) (match_dup 0))
13562 (set (strict_low_part (match_dup 5))
13563 (match_dup 2))]
13564 {
13565 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13566 operands[5] = gen_lowpart (QImode, operands[3]);
13567 ix86_expand_clear (operands[3]);
13568 })
13569
13570 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13571
13572 (define_peephole2
13573 [(set (reg 17) (match_operand 0 "" ""))
13574 (set (match_operand:QI 1 "register_operand" "")
13575 (match_operator:QI 2 "ix86_comparison_operator"
13576 [(reg 17) (const_int 0)]))
13577 (parallel [(set (match_operand 3 "q_regs_operand" "")
13578 (zero_extend (match_dup 1)))
13579 (clobber (reg:CC 17))])]
13580 "(peep2_reg_dead_p (3, operands[1])
13581 || operands_match_p (operands[1], operands[3]))
13582 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13583 [(set (match_dup 4) (match_dup 0))
13584 (set (strict_low_part (match_dup 5))
13585 (match_dup 2))]
13586 {
13587 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13588 operands[5] = gen_lowpart (QImode, operands[3]);
13589 ix86_expand_clear (operands[3]);
13590 })
13591 \f
13592 ;; Call instructions.
13593
13594 ;; The predicates normally associated with named expanders are not properly
13595 ;; checked for calls. This is a bug in the generic code, but it isn't that
13596 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13597
13598 ;; Call subroutine returning no value.
13599
13600 (define_expand "call_pop"
13601 [(parallel [(call (match_operand:QI 0 "" "")
13602 (match_operand:SI 1 "" ""))
13603 (set (reg:SI 7)
13604 (plus:SI (reg:SI 7)
13605 (match_operand:SI 3 "" "")))])]
13606 "!TARGET_64BIT"
13607 {
13608 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13609 DONE;
13610 })
13611
13612 (define_insn "*call_pop_0"
13613 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13614 (match_operand:SI 1 "" ""))
13615 (set (reg:SI 7) (plus:SI (reg:SI 7)
13616 (match_operand:SI 2 "immediate_operand" "")))]
13617 "!TARGET_64BIT"
13618 {
13619 if (SIBLING_CALL_P (insn))
13620 return "jmp\t%P0";
13621 else
13622 return "call\t%P0";
13623 }
13624 [(set_attr "type" "call")])
13625
13626 (define_insn "*call_pop_1"
13627 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13628 (match_operand:SI 1 "" ""))
13629 (set (reg:SI 7) (plus:SI (reg:SI 7)
13630 (match_operand:SI 2 "immediate_operand" "i")))]
13631 "!TARGET_64BIT"
13632 {
13633 if (constant_call_address_operand (operands[0], Pmode))
13634 {
13635 if (SIBLING_CALL_P (insn))
13636 return "jmp\t%P0";
13637 else
13638 return "call\t%P0";
13639 }
13640 if (SIBLING_CALL_P (insn))
13641 return "jmp\t%A0";
13642 else
13643 return "call\t%A0";
13644 }
13645 [(set_attr "type" "call")])
13646
13647 (define_expand "call"
13648 [(call (match_operand:QI 0 "" "")
13649 (match_operand 1 "" ""))
13650 (use (match_operand 2 "" ""))]
13651 ""
13652 {
13653 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13654 DONE;
13655 })
13656
13657 (define_expand "sibcall"
13658 [(call (match_operand:QI 0 "" "")
13659 (match_operand 1 "" ""))
13660 (use (match_operand 2 "" ""))]
13661 ""
13662 {
13663 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13664 DONE;
13665 })
13666
13667 (define_insn "*call_0"
13668 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13669 (match_operand 1 "" ""))]
13670 ""
13671 {
13672 if (SIBLING_CALL_P (insn))
13673 return "jmp\t%P0";
13674 else
13675 return "call\t%P0";
13676 }
13677 [(set_attr "type" "call")])
13678
13679 (define_insn "*call_1"
13680 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13681 (match_operand 1 "" ""))]
13682 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13683 {
13684 if (constant_call_address_operand (operands[0], QImode))
13685 return "call\t%P0";
13686 return "call\t%A0";
13687 }
13688 [(set_attr "type" "call")])
13689
13690 (define_insn "*sibcall_1"
13691 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13692 (match_operand 1 "" ""))]
13693 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13694 {
13695 if (constant_call_address_operand (operands[0], QImode))
13696 return "jmp\t%P0";
13697 return "jmp\t%A0";
13698 }
13699 [(set_attr "type" "call")])
13700
13701 (define_insn "*call_1_rex64"
13702 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13703 (match_operand 1 "" ""))]
13704 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13705 {
13706 if (constant_call_address_operand (operands[0], QImode))
13707 return "call\t%P0";
13708 return "call\t%A0";
13709 }
13710 [(set_attr "type" "call")])
13711
13712 (define_insn "*sibcall_1_rex64"
13713 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13714 (match_operand 1 "" ""))]
13715 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13716 "jmp\t%P0"
13717 [(set_attr "type" "call")])
13718
13719 (define_insn "*sibcall_1_rex64_v"
13720 [(call (mem:QI (reg:DI 40))
13721 (match_operand 0 "" ""))]
13722 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13723 "jmp\t*%%r11"
13724 [(set_attr "type" "call")])
13725
13726
13727 ;; Call subroutine, returning value in operand 0
13728
13729 (define_expand "call_value_pop"
13730 [(parallel [(set (match_operand 0 "" "")
13731 (call (match_operand:QI 1 "" "")
13732 (match_operand:SI 2 "" "")))
13733 (set (reg:SI 7)
13734 (plus:SI (reg:SI 7)
13735 (match_operand:SI 4 "" "")))])]
13736 "!TARGET_64BIT"
13737 {
13738 ix86_expand_call (operands[0], operands[1], operands[2],
13739 operands[3], operands[4], 0);
13740 DONE;
13741 })
13742
13743 (define_expand "call_value"
13744 [(set (match_operand 0 "" "")
13745 (call (match_operand:QI 1 "" "")
13746 (match_operand:SI 2 "" "")))
13747 (use (match_operand:SI 3 "" ""))]
13748 ;; Operand 2 not used on the i386.
13749 ""
13750 {
13751 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13752 DONE;
13753 })
13754
13755 (define_expand "sibcall_value"
13756 [(set (match_operand 0 "" "")
13757 (call (match_operand:QI 1 "" "")
13758 (match_operand:SI 2 "" "")))
13759 (use (match_operand:SI 3 "" ""))]
13760 ;; Operand 2 not used on the i386.
13761 ""
13762 {
13763 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13764 DONE;
13765 })
13766
13767 ;; Call subroutine returning any type.
13768
13769 (define_expand "untyped_call"
13770 [(parallel [(call (match_operand 0 "" "")
13771 (const_int 0))
13772 (match_operand 1 "" "")
13773 (match_operand 2 "" "")])]
13774 ""
13775 {
13776 int i;
13777
13778 /* In order to give reg-stack an easier job in validating two
13779 coprocessor registers as containing a possible return value,
13780 simply pretend the untyped call returns a complex long double
13781 value. */
13782
13783 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13784 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13785 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13786 NULL, 0);
13787
13788 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13789 {
13790 rtx set = XVECEXP (operands[2], 0, i);
13791 emit_move_insn (SET_DEST (set), SET_SRC (set));
13792 }
13793
13794 /* The optimizer does not know that the call sets the function value
13795 registers we stored in the result block. We avoid problems by
13796 claiming that all hard registers are used and clobbered at this
13797 point. */
13798 emit_insn (gen_blockage (const0_rtx));
13799
13800 DONE;
13801 })
13802 \f
13803 ;; Prologue and epilogue instructions
13804
13805 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13806 ;; all of memory. This blocks insns from being moved across this point.
13807
13808 (define_insn "blockage"
13809 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13810 ""
13811 ""
13812 [(set_attr "length" "0")])
13813
13814 ;; Insn emitted into the body of a function to return from a function.
13815 ;; This is only done if the function's epilogue is known to be simple.
13816 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13817
13818 (define_expand "return"
13819 [(return)]
13820 "ix86_can_use_return_insn_p ()"
13821 {
13822 if (current_function_pops_args)
13823 {
13824 rtx popc = GEN_INT (current_function_pops_args);
13825 emit_jump_insn (gen_return_pop_internal (popc));
13826 DONE;
13827 }
13828 })
13829
13830 (define_insn "return_internal"
13831 [(return)]
13832 "reload_completed"
13833 "ret"
13834 [(set_attr "length" "1")
13835 (set_attr "length_immediate" "0")
13836 (set_attr "modrm" "0")])
13837
13838 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13839 ;; instruction Athlon and K8 have.
13840
13841 (define_insn "return_internal_long"
13842 [(return)
13843 (unspec [(const_int 0)] UNSPEC_REP)]
13844 "reload_completed"
13845 "rep {;} ret"
13846 [(set_attr "length" "1")
13847 (set_attr "length_immediate" "0")
13848 (set_attr "prefix_rep" "1")
13849 (set_attr "modrm" "0")])
13850
13851 (define_insn "return_pop_internal"
13852 [(return)
13853 (use (match_operand:SI 0 "const_int_operand" ""))]
13854 "reload_completed"
13855 "ret\t%0"
13856 [(set_attr "length" "3")
13857 (set_attr "length_immediate" "2")
13858 (set_attr "modrm" "0")])
13859
13860 (define_insn "return_indirect_internal"
13861 [(return)
13862 (use (match_operand:SI 0 "register_operand" "r"))]
13863 "reload_completed"
13864 "jmp\t%A0"
13865 [(set_attr "type" "ibr")
13866 (set_attr "length_immediate" "0")])
13867
13868 (define_insn "nop"
13869 [(const_int 0)]
13870 ""
13871 "nop"
13872 [(set_attr "length" "1")
13873 (set_attr "length_immediate" "0")
13874 (set_attr "modrm" "0")
13875 (set_attr "ppro_uops" "one")])
13876
13877 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13878 ;; branch prediction penalty for the third jump in a 16-byte
13879 ;; block on K8.
13880
13881 (define_insn "align"
13882 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13883 ""
13884 {
13885 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13886 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13887 #else
13888 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13889 The align insn is used to avoid 3 jump instructions in the row to improve
13890 branch prediction and the benefits hardly outweight the cost of extra 8
13891 nops on the average inserted by full alignment pseudo operation. */
13892 #endif
13893 return "";
13894 }
13895 [(set_attr "length" "16")])
13896
13897 (define_expand "prologue"
13898 [(const_int 1)]
13899 ""
13900 "ix86_expand_prologue (); DONE;")
13901
13902 (define_insn "set_got"
13903 [(set (match_operand:SI 0 "register_operand" "=r")
13904 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13905 (clobber (reg:CC 17))]
13906 "!TARGET_64BIT"
13907 { return output_set_got (operands[0]); }
13908 [(set_attr "type" "multi")
13909 (set_attr "length" "12")])
13910
13911 (define_expand "epilogue"
13912 [(const_int 1)]
13913 ""
13914 "ix86_expand_epilogue (1); DONE;")
13915
13916 (define_expand "sibcall_epilogue"
13917 [(const_int 1)]
13918 ""
13919 "ix86_expand_epilogue (0); DONE;")
13920
13921 (define_expand "eh_return"
13922 [(use (match_operand 0 "register_operand" ""))]
13923 ""
13924 {
13925 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13926
13927 /* Tricky bit: we write the address of the handler to which we will
13928 be returning into someone else's stack frame, one word below the
13929 stack address we wish to restore. */
13930 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13931 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13932 tmp = gen_rtx_MEM (Pmode, tmp);
13933 emit_move_insn (tmp, ra);
13934
13935 if (Pmode == SImode)
13936 emit_insn (gen_eh_return_si (sa));
13937 else
13938 emit_insn (gen_eh_return_di (sa));
13939 emit_barrier ();
13940 DONE;
13941 })
13942
13943 (define_insn_and_split "eh_return_si"
13944 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
13945 UNSPECV_EH_RETURN)]
13946 "!TARGET_64BIT"
13947 "#"
13948 "reload_completed"
13949 [(const_int 1)]
13950 "ix86_expand_epilogue (2); DONE;")
13951
13952 (define_insn_and_split "eh_return_di"
13953 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
13954 UNSPECV_EH_RETURN)]
13955 "TARGET_64BIT"
13956 "#"
13957 "reload_completed"
13958 [(const_int 1)]
13959 "ix86_expand_epilogue (2); DONE;")
13960
13961 (define_insn "leave"
13962 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
13963 (set (reg:SI 6) (mem:SI (reg:SI 6)))
13964 (clobber (mem:BLK (scratch)))]
13965 "!TARGET_64BIT"
13966 "leave"
13967 [(set_attr "type" "leave")])
13968
13969 (define_insn "leave_rex64"
13970 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
13971 (set (reg:DI 6) (mem:DI (reg:DI 6)))
13972 (clobber (mem:BLK (scratch)))]
13973 "TARGET_64BIT"
13974 "leave"
13975 [(set_attr "type" "leave")])
13976 \f
13977 (define_expand "ffssi2"
13978 [(parallel
13979 [(set (match_operand:SI 0 "register_operand" "")
13980 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13981 (clobber (match_scratch:SI 2 ""))
13982 (clobber (reg:CC 17))])]
13983 ""
13984 "")
13985
13986 (define_insn_and_split "*ffs_cmove"
13987 [(set (match_operand:SI 0 "register_operand" "=r")
13988 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989 (clobber (match_scratch:SI 2 "=&r"))
13990 (clobber (reg:CC 17))]
13991 "TARGET_CMOVE"
13992 "#"
13993 "&& reload_completed"
13994 [(set (match_dup 2) (const_int -1))
13995 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
13996 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13997 (set (match_dup 0) (if_then_else:SI
13998 (eq (reg:CCZ 17) (const_int 0))
13999 (match_dup 2)
14000 (match_dup 0)))
14001 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14002 (clobber (reg:CC 17))])]
14003 "")
14004
14005 (define_insn_and_split "*ffs_no_cmove"
14006 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14007 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14008 (clobber (match_scratch:SI 2 "=&q"))
14009 (clobber (reg:CC 17))]
14010 ""
14011 "#"
14012 "reload_completed"
14013 [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14014 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14015 (set (strict_low_part (match_dup 3))
14016 (eq:QI (reg:CCZ 17) (const_int 0)))
14017 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14018 (clobber (reg:CC 17))])
14019 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14020 (clobber (reg:CC 17))])
14021 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14022 (clobber (reg:CC 17))])]
14023 {
14024 operands[3] = gen_lowpart (QImode, operands[2]);
14025 ix86_expand_clear (operands[2]);
14026 })
14027
14028 (define_insn "*ffssi_1"
14029 [(set (reg:CCZ 17)
14030 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14031 (const_int 0)))
14032 (set (match_operand:SI 0 "register_operand" "=r")
14033 (ctz:SI (match_dup 1)))]
14034 ""
14035 "bsf{l}\t{%1, %0|%0, %1}"
14036 [(set_attr "prefix_0f" "1")
14037 (set_attr "ppro_uops" "few")])
14038
14039 (define_insn "ctzsi2"
14040 [(set (match_operand:SI 0 "register_operand" "=r")
14041 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14042 (clobber (reg:CC 17))]
14043 ""
14044 "bsf{l}\t{%1, %0|%0, %1}"
14045 [(set_attr "prefix_0f" "1")
14046 (set_attr "ppro_uops" "few")])
14047
14048 (define_expand "clzsi2"
14049 [(parallel
14050 [(set (match_operand:SI 0 "register_operand" "")
14051 (minus:SI (const_int 31)
14052 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14053 (clobber (reg:CC 17))])
14054 (parallel
14055 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14056 (clobber (reg:CC 17))])]
14057 ""
14058 "")
14059
14060 (define_insn "*bsr"
14061 [(set (match_operand:SI 0 "register_operand" "=r")
14062 (minus:SI (const_int 31)
14063 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14064 (clobber (reg:CC 17))]
14065 ""
14066 "bsr{l}\t{%1, %0|%0, %1}"
14067 [(set_attr "prefix_0f" "1")
14068 (set_attr "ppro_uops" "few")])
14069 \f
14070 ;; Thread-local storage patterns for ELF.
14071 ;;
14072 ;; Note that these code sequences must appear exactly as shown
14073 ;; in order to allow linker relaxation.
14074
14075 (define_insn "*tls_global_dynamic_32_gnu"
14076 [(set (match_operand:SI 0 "register_operand" "=a")
14077 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14078 (match_operand:SI 2 "tls_symbolic_operand" "")
14079 (match_operand:SI 3 "call_insn_operand" "")]
14080 UNSPEC_TLS_GD))
14081 (clobber (match_scratch:SI 4 "=d"))
14082 (clobber (match_scratch:SI 5 "=c"))
14083 (clobber (reg:CC 17))]
14084 "!TARGET_64BIT && TARGET_GNU_TLS"
14085 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14086 [(set_attr "type" "multi")
14087 (set_attr "length" "12")])
14088
14089 (define_insn "*tls_global_dynamic_32_sun"
14090 [(set (match_operand:SI 0 "register_operand" "=a")
14091 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14092 (match_operand:SI 2 "tls_symbolic_operand" "")
14093 (match_operand:SI 3 "call_insn_operand" "")]
14094 UNSPEC_TLS_GD))
14095 (clobber (match_scratch:SI 4 "=d"))
14096 (clobber (match_scratch:SI 5 "=c"))
14097 (clobber (reg:CC 17))]
14098 "!TARGET_64BIT && TARGET_SUN_TLS"
14099 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14100 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14101 [(set_attr "type" "multi")
14102 (set_attr "length" "14")])
14103
14104 (define_expand "tls_global_dynamic_32"
14105 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14106 (unspec:SI
14107 [(match_dup 2)
14108 (match_operand:SI 1 "tls_symbolic_operand" "")
14109 (match_dup 3)]
14110 UNSPEC_TLS_GD))
14111 (clobber (match_scratch:SI 4 ""))
14112 (clobber (match_scratch:SI 5 ""))
14113 (clobber (reg:CC 17))])]
14114 ""
14115 {
14116 if (flag_pic)
14117 operands[2] = pic_offset_table_rtx;
14118 else
14119 {
14120 operands[2] = gen_reg_rtx (Pmode);
14121 emit_insn (gen_set_got (operands[2]));
14122 }
14123 operands[3] = ix86_tls_get_addr ();
14124 })
14125
14126 (define_insn "*tls_global_dynamic_64"
14127 [(set (match_operand:DI 0 "register_operand" "=a")
14128 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14129 (match_operand:DI 3 "" "")))
14130 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14131 UNSPEC_TLS_GD)]
14132 "TARGET_64BIT"
14133 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14134 [(set_attr "type" "multi")
14135 (set_attr "length" "16")])
14136
14137 (define_expand "tls_global_dynamic_64"
14138 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14139 (call (mem:QI (match_dup 2)) (const_int 0)))
14140 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14141 UNSPEC_TLS_GD)])]
14142 ""
14143 {
14144 operands[2] = ix86_tls_get_addr ();
14145 })
14146
14147 (define_insn "*tls_local_dynamic_base_32_gnu"
14148 [(set (match_operand:SI 0 "register_operand" "=a")
14149 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14150 (match_operand:SI 2 "call_insn_operand" "")]
14151 UNSPEC_TLS_LD_BASE))
14152 (clobber (match_scratch:SI 3 "=d"))
14153 (clobber (match_scratch:SI 4 "=c"))
14154 (clobber (reg:CC 17))]
14155 "!TARGET_64BIT && TARGET_GNU_TLS"
14156 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14157 [(set_attr "type" "multi")
14158 (set_attr "length" "11")])
14159
14160 (define_insn "*tls_local_dynamic_base_32_sun"
14161 [(set (match_operand:SI 0 "register_operand" "=a")
14162 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14163 (match_operand:SI 2 "call_insn_operand" "")]
14164 UNSPEC_TLS_LD_BASE))
14165 (clobber (match_scratch:SI 3 "=d"))
14166 (clobber (match_scratch:SI 4 "=c"))
14167 (clobber (reg:CC 17))]
14168 "!TARGET_64BIT && TARGET_SUN_TLS"
14169 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14170 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14171 [(set_attr "type" "multi")
14172 (set_attr "length" "13")])
14173
14174 (define_expand "tls_local_dynamic_base_32"
14175 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14176 (unspec:SI [(match_dup 1) (match_dup 2)]
14177 UNSPEC_TLS_LD_BASE))
14178 (clobber (match_scratch:SI 3 ""))
14179 (clobber (match_scratch:SI 4 ""))
14180 (clobber (reg:CC 17))])]
14181 ""
14182 {
14183 if (flag_pic)
14184 operands[1] = pic_offset_table_rtx;
14185 else
14186 {
14187 operands[1] = gen_reg_rtx (Pmode);
14188 emit_insn (gen_set_got (operands[1]));
14189 }
14190 operands[2] = ix86_tls_get_addr ();
14191 })
14192
14193 (define_insn "*tls_local_dynamic_base_64"
14194 [(set (match_operand:DI 0 "register_operand" "=a")
14195 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14196 (match_operand:DI 2 "" "")))
14197 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14198 "TARGET_64BIT"
14199 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14200 [(set_attr "type" "multi")
14201 (set_attr "length" "12")])
14202
14203 (define_expand "tls_local_dynamic_base_64"
14204 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14205 (call (mem:QI (match_dup 1)) (const_int 0)))
14206 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14207 ""
14208 {
14209 operands[1] = ix86_tls_get_addr ();
14210 })
14211
14212 ;; Local dynamic of a single variable is a lose. Show combine how
14213 ;; to convert that back to global dynamic.
14214
14215 (define_insn_and_split "*tls_local_dynamic_32_once"
14216 [(set (match_operand:SI 0 "register_operand" "=a")
14217 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14218 (match_operand:SI 2 "call_insn_operand" "")]
14219 UNSPEC_TLS_LD_BASE)
14220 (const:SI (unspec:SI
14221 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14222 UNSPEC_DTPOFF))))
14223 (clobber (match_scratch:SI 4 "=d"))
14224 (clobber (match_scratch:SI 5 "=c"))
14225 (clobber (reg:CC 17))]
14226 ""
14227 "#"
14228 ""
14229 [(parallel [(set (match_dup 0)
14230 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14231 UNSPEC_TLS_GD))
14232 (clobber (match_dup 4))
14233 (clobber (match_dup 5))
14234 (clobber (reg:CC 17))])]
14235 "")
14236
14237 ;; Load and add the thread base pointer from %gs:0.
14238
14239 (define_insn "*load_tp_si"
14240 [(set (match_operand:SI 0 "register_operand" "=r")
14241 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14242 "!TARGET_64BIT"
14243 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14244 [(set_attr "type" "imov")
14245 (set_attr "modrm" "0")
14246 (set_attr "length" "7")
14247 (set_attr "memory" "load")
14248 (set_attr "imm_disp" "false")])
14249
14250 (define_insn "*add_tp_si"
14251 [(set (match_operand:SI 0 "register_operand" "=r")
14252 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14253 (match_operand:SI 1 "register_operand" "0")))
14254 (clobber (reg:CC 17))]
14255 "!TARGET_64BIT"
14256 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14257 [(set_attr "type" "alu")
14258 (set_attr "modrm" "0")
14259 (set_attr "length" "7")
14260 (set_attr "memory" "load")
14261 (set_attr "imm_disp" "false")])
14262
14263 (define_insn "*load_tp_di"
14264 [(set (match_operand:DI 0 "register_operand" "=r")
14265 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14266 "TARGET_64BIT"
14267 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14268 [(set_attr "type" "imov")
14269 (set_attr "modrm" "0")
14270 (set_attr "length" "7")
14271 (set_attr "memory" "load")
14272 (set_attr "imm_disp" "false")])
14273
14274 (define_insn "*add_tp_di"
14275 [(set (match_operand:DI 0 "register_operand" "=r")
14276 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14277 (match_operand:DI 1 "register_operand" "0")))
14278 (clobber (reg:CC 17))]
14279 "TARGET_64BIT"
14280 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14281 [(set_attr "type" "alu")
14282 (set_attr "modrm" "0")
14283 (set_attr "length" "7")
14284 (set_attr "memory" "load")
14285 (set_attr "imm_disp" "false")])
14286 \f
14287 ;; These patterns match the binary 387 instructions for addM3, subM3,
14288 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14289 ;; SFmode. The first is the normal insn, the second the same insn but
14290 ;; with one operand a conversion, and the third the same insn but with
14291 ;; the other operand a conversion. The conversion may be SFmode or
14292 ;; SImode if the target mode DFmode, but only SImode if the target mode
14293 ;; is SFmode.
14294
14295 ;; Gcc is slightly more smart about handling normal two address instructions
14296 ;; so use special patterns for add and mull.
14297 (define_insn "*fop_sf_comm_nosse"
14298 [(set (match_operand:SF 0 "register_operand" "=f")
14299 (match_operator:SF 3 "binary_fp_operator"
14300 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14301 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14302 "TARGET_80387 && !TARGET_SSE_MATH
14303 && COMMUTATIVE_ARITH_P (operands[3])
14304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14305 "* return output_387_binary_op (insn, operands);"
14306 [(set (attr "type")
14307 (if_then_else (match_operand:SF 3 "mult_operator" "")
14308 (const_string "fmul")
14309 (const_string "fop")))
14310 (set_attr "mode" "SF")])
14311
14312 (define_insn "*fop_sf_comm"
14313 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14314 (match_operator:SF 3 "binary_fp_operator"
14315 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14316 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14317 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14318 && COMMUTATIVE_ARITH_P (operands[3])
14319 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14320 "* return output_387_binary_op (insn, operands);"
14321 [(set (attr "type")
14322 (if_then_else (eq_attr "alternative" "1")
14323 (if_then_else (match_operand:SF 3 "mult_operator" "")
14324 (const_string "ssemul")
14325 (const_string "sseadd"))
14326 (if_then_else (match_operand:SF 3 "mult_operator" "")
14327 (const_string "fmul")
14328 (const_string "fop"))))
14329 (set_attr "mode" "SF")])
14330
14331 (define_insn "*fop_sf_comm_sse"
14332 [(set (match_operand:SF 0 "register_operand" "=x")
14333 (match_operator:SF 3 "binary_fp_operator"
14334 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14335 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14336 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14337 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14338 "* return output_387_binary_op (insn, operands);"
14339 [(set (attr "type")
14340 (if_then_else (match_operand:SF 3 "mult_operator" "")
14341 (const_string "ssemul")
14342 (const_string "sseadd")))
14343 (set_attr "mode" "SF")])
14344
14345 (define_insn "*fop_df_comm_nosse"
14346 [(set (match_operand:DF 0 "register_operand" "=f")
14347 (match_operator:DF 3 "binary_fp_operator"
14348 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14349 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14350 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14351 && COMMUTATIVE_ARITH_P (operands[3])
14352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14353 "* return output_387_binary_op (insn, operands);"
14354 [(set (attr "type")
14355 (if_then_else (match_operand:SF 3 "mult_operator" "")
14356 (const_string "fmul")
14357 (const_string "fop")))
14358 (set_attr "mode" "DF")])
14359
14360 (define_insn "*fop_df_comm"
14361 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14362 (match_operator:DF 3 "binary_fp_operator"
14363 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14364 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14365 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14366 && COMMUTATIVE_ARITH_P (operands[3])
14367 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14368 "* return output_387_binary_op (insn, operands);"
14369 [(set (attr "type")
14370 (if_then_else (eq_attr "alternative" "1")
14371 (if_then_else (match_operand:SF 3 "mult_operator" "")
14372 (const_string "ssemul")
14373 (const_string "sseadd"))
14374 (if_then_else (match_operand:SF 3 "mult_operator" "")
14375 (const_string "fmul")
14376 (const_string "fop"))))
14377 (set_attr "mode" "DF")])
14378
14379 (define_insn "*fop_df_comm_sse"
14380 [(set (match_operand:DF 0 "register_operand" "=Y")
14381 (match_operator:DF 3 "binary_fp_operator"
14382 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14383 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14384 "TARGET_SSE2 && TARGET_SSE_MATH
14385 && COMMUTATIVE_ARITH_P (operands[3])
14386 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14387 "* return output_387_binary_op (insn, operands);"
14388 [(set (attr "type")
14389 (if_then_else (match_operand:SF 3 "mult_operator" "")
14390 (const_string "ssemul")
14391 (const_string "sseadd")))
14392 (set_attr "mode" "DF")])
14393
14394 (define_insn "*fop_xf_comm"
14395 [(set (match_operand:XF 0 "register_operand" "=f")
14396 (match_operator:XF 3 "binary_fp_operator"
14397 [(match_operand:XF 1 "register_operand" "%0")
14398 (match_operand:XF 2 "register_operand" "f")]))]
14399 "TARGET_80387
14400 && COMMUTATIVE_ARITH_P (operands[3])"
14401 "* return output_387_binary_op (insn, operands);"
14402 [(set (attr "type")
14403 (if_then_else (match_operand:XF 3 "mult_operator" "")
14404 (const_string "fmul")
14405 (const_string "fop")))
14406 (set_attr "mode" "XF")])
14407
14408 (define_insn "*fop_sf_1_nosse"
14409 [(set (match_operand:SF 0 "register_operand" "=f,f")
14410 (match_operator:SF 3 "binary_fp_operator"
14411 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14412 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14413 "TARGET_80387 && !TARGET_SSE_MATH
14414 && !COMMUTATIVE_ARITH_P (operands[3])
14415 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14416 "* return output_387_binary_op (insn, operands);"
14417 [(set (attr "type")
14418 (cond [(match_operand:SF 3 "mult_operator" "")
14419 (const_string "fmul")
14420 (match_operand:SF 3 "div_operator" "")
14421 (const_string "fdiv")
14422 ]
14423 (const_string "fop")))
14424 (set_attr "mode" "SF")])
14425
14426 (define_insn "*fop_sf_1"
14427 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14428 (match_operator:SF 3 "binary_fp_operator"
14429 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14430 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14431 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14432 && !COMMUTATIVE_ARITH_P (operands[3])
14433 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14434 "* return output_387_binary_op (insn, operands);"
14435 [(set (attr "type")
14436 (cond [(and (eq_attr "alternative" "2")
14437 (match_operand:SF 3 "mult_operator" ""))
14438 (const_string "ssemul")
14439 (and (eq_attr "alternative" "2")
14440 (match_operand:SF 3 "div_operator" ""))
14441 (const_string "ssediv")
14442 (eq_attr "alternative" "2")
14443 (const_string "sseadd")
14444 (match_operand:SF 3 "mult_operator" "")
14445 (const_string "fmul")
14446 (match_operand:SF 3 "div_operator" "")
14447 (const_string "fdiv")
14448 ]
14449 (const_string "fop")))
14450 (set_attr "mode" "SF")])
14451
14452 (define_insn "*fop_sf_1_sse"
14453 [(set (match_operand:SF 0 "register_operand" "=x")
14454 (match_operator:SF 3 "binary_fp_operator"
14455 [(match_operand:SF 1 "register_operand" "0")
14456 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14457 "TARGET_SSE_MATH
14458 && !COMMUTATIVE_ARITH_P (operands[3])"
14459 "* return output_387_binary_op (insn, operands);"
14460 [(set (attr "type")
14461 (cond [(match_operand:SF 3 "mult_operator" "")
14462 (const_string "ssemul")
14463 (match_operand:SF 3 "div_operator" "")
14464 (const_string "ssediv")
14465 ]
14466 (const_string "sseadd")))
14467 (set_attr "mode" "SF")])
14468
14469 ;; ??? Add SSE splitters for these!
14470 (define_insn "*fop_sf_2"
14471 [(set (match_operand:SF 0 "register_operand" "=f,f")
14472 (match_operator:SF 3 "binary_fp_operator"
14473 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14474 (match_operand:SF 2 "register_operand" "0,0")]))]
14475 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14476 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14477 [(set (attr "type")
14478 (cond [(match_operand:SF 3 "mult_operator" "")
14479 (const_string "fmul")
14480 (match_operand:SF 3 "div_operator" "")
14481 (const_string "fdiv")
14482 ]
14483 (const_string "fop")))
14484 (set_attr "fp_int_src" "true")
14485 (set_attr "ppro_uops" "many")
14486 (set_attr "mode" "SI")])
14487
14488 (define_insn "*fop_sf_3"
14489 [(set (match_operand:SF 0 "register_operand" "=f,f")
14490 (match_operator:SF 3 "binary_fp_operator"
14491 [(match_operand:SF 1 "register_operand" "0,0")
14492 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14493 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14494 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14495 [(set (attr "type")
14496 (cond [(match_operand:SF 3 "mult_operator" "")
14497 (const_string "fmul")
14498 (match_operand:SF 3 "div_operator" "")
14499 (const_string "fdiv")
14500 ]
14501 (const_string "fop")))
14502 (set_attr "fp_int_src" "true")
14503 (set_attr "ppro_uops" "many")
14504 (set_attr "mode" "SI")])
14505
14506 (define_insn "*fop_df_1_nosse"
14507 [(set (match_operand:DF 0 "register_operand" "=f,f")
14508 (match_operator:DF 3 "binary_fp_operator"
14509 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14510 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14511 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14512 && !COMMUTATIVE_ARITH_P (operands[3])
14513 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14514 "* return output_387_binary_op (insn, operands);"
14515 [(set (attr "type")
14516 (cond [(match_operand:DF 3 "mult_operator" "")
14517 (const_string "fmul")
14518 (match_operand:DF 3 "div_operator" "")
14519 (const_string "fdiv")
14520 ]
14521 (const_string "fop")))
14522 (set_attr "mode" "DF")])
14523
14524
14525 (define_insn "*fop_df_1"
14526 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14527 (match_operator:DF 3 "binary_fp_operator"
14528 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14529 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14530 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14531 && !COMMUTATIVE_ARITH_P (operands[3])
14532 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14533 "* return output_387_binary_op (insn, operands);"
14534 [(set (attr "type")
14535 (cond [(and (eq_attr "alternative" "2")
14536 (match_operand:SF 3 "mult_operator" ""))
14537 (const_string "ssemul")
14538 (and (eq_attr "alternative" "2")
14539 (match_operand:SF 3 "div_operator" ""))
14540 (const_string "ssediv")
14541 (eq_attr "alternative" "2")
14542 (const_string "sseadd")
14543 (match_operand:DF 3 "mult_operator" "")
14544 (const_string "fmul")
14545 (match_operand:DF 3 "div_operator" "")
14546 (const_string "fdiv")
14547 ]
14548 (const_string "fop")))
14549 (set_attr "mode" "DF")])
14550
14551 (define_insn "*fop_df_1_sse"
14552 [(set (match_operand:DF 0 "register_operand" "=Y")
14553 (match_operator:DF 3 "binary_fp_operator"
14554 [(match_operand:DF 1 "register_operand" "0")
14555 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14556 "TARGET_SSE2 && TARGET_SSE_MATH
14557 && !COMMUTATIVE_ARITH_P (operands[3])"
14558 "* return output_387_binary_op (insn, operands);"
14559 [(set_attr "mode" "DF")
14560 (set (attr "type")
14561 (cond [(match_operand:SF 3 "mult_operator" "")
14562 (const_string "ssemul")
14563 (match_operand:SF 3 "div_operator" "")
14564 (const_string "ssediv")
14565 ]
14566 (const_string "sseadd")))])
14567
14568 ;; ??? Add SSE splitters for these!
14569 (define_insn "*fop_df_2"
14570 [(set (match_operand:DF 0 "register_operand" "=f,f")
14571 (match_operator:DF 3 "binary_fp_operator"
14572 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14573 (match_operand:DF 2 "register_operand" "0,0")]))]
14574 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14575 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14576 [(set (attr "type")
14577 (cond [(match_operand:DF 3 "mult_operator" "")
14578 (const_string "fmul")
14579 (match_operand:DF 3 "div_operator" "")
14580 (const_string "fdiv")
14581 ]
14582 (const_string "fop")))
14583 (set_attr "fp_int_src" "true")
14584 (set_attr "ppro_uops" "many")
14585 (set_attr "mode" "SI")])
14586
14587 (define_insn "*fop_df_3"
14588 [(set (match_operand:DF 0 "register_operand" "=f,f")
14589 (match_operator:DF 3 "binary_fp_operator"
14590 [(match_operand:DF 1 "register_operand" "0,0")
14591 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14592 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14593 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14594 [(set (attr "type")
14595 (cond [(match_operand:DF 3 "mult_operator" "")
14596 (const_string "fmul")
14597 (match_operand:DF 3 "div_operator" "")
14598 (const_string "fdiv")
14599 ]
14600 (const_string "fop")))
14601 (set_attr "fp_int_src" "true")
14602 (set_attr "ppro_uops" "many")
14603 (set_attr "mode" "SI")])
14604
14605 (define_insn "*fop_df_4"
14606 [(set (match_operand:DF 0 "register_operand" "=f,f")
14607 (match_operator:DF 3 "binary_fp_operator"
14608 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14609 (match_operand:DF 2 "register_operand" "0,f")]))]
14610 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14611 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14612 "* return output_387_binary_op (insn, operands);"
14613 [(set (attr "type")
14614 (cond [(match_operand:DF 3 "mult_operator" "")
14615 (const_string "fmul")
14616 (match_operand:DF 3 "div_operator" "")
14617 (const_string "fdiv")
14618 ]
14619 (const_string "fop")))
14620 (set_attr "mode" "SF")])
14621
14622 (define_insn "*fop_df_5"
14623 [(set (match_operand:DF 0 "register_operand" "=f,f")
14624 (match_operator:DF 3 "binary_fp_operator"
14625 [(match_operand:DF 1 "register_operand" "0,f")
14626 (float_extend:DF
14627 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14628 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14629 "* return output_387_binary_op (insn, operands);"
14630 [(set (attr "type")
14631 (cond [(match_operand:DF 3 "mult_operator" "")
14632 (const_string "fmul")
14633 (match_operand:DF 3 "div_operator" "")
14634 (const_string "fdiv")
14635 ]
14636 (const_string "fop")))
14637 (set_attr "mode" "SF")])
14638
14639 (define_insn "*fop_df_6"
14640 [(set (match_operand:DF 0 "register_operand" "=f,f")
14641 (match_operator:DF 3 "binary_fp_operator"
14642 [(float_extend:DF
14643 (match_operand:SF 1 "register_operand" "0,f"))
14644 (float_extend:DF
14645 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14646 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14647 "* return output_387_binary_op (insn, operands);"
14648 [(set (attr "type")
14649 (cond [(match_operand:DF 3 "mult_operator" "")
14650 (const_string "fmul")
14651 (match_operand:DF 3 "div_operator" "")
14652 (const_string "fdiv")
14653 ]
14654 (const_string "fop")))
14655 (set_attr "mode" "SF")])
14656
14657 (define_insn "*fop_xf_1"
14658 [(set (match_operand:XF 0 "register_operand" "=f,f")
14659 (match_operator:XF 3 "binary_fp_operator"
14660 [(match_operand:XF 1 "register_operand" "0,f")
14661 (match_operand:XF 2 "register_operand" "f,0")]))]
14662 "TARGET_80387
14663 && !COMMUTATIVE_ARITH_P (operands[3])"
14664 "* return output_387_binary_op (insn, operands);"
14665 [(set (attr "type")
14666 (cond [(match_operand:XF 3 "mult_operator" "")
14667 (const_string "fmul")
14668 (match_operand:XF 3 "div_operator" "")
14669 (const_string "fdiv")
14670 ]
14671 (const_string "fop")))
14672 (set_attr "mode" "XF")])
14673
14674 (define_insn "*fop_xf_2"
14675 [(set (match_operand:XF 0 "register_operand" "=f,f")
14676 (match_operator:XF 3 "binary_fp_operator"
14677 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14678 (match_operand:XF 2 "register_operand" "0,0")]))]
14679 "TARGET_80387 && TARGET_USE_FIOP"
14680 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14681 [(set (attr "type")
14682 (cond [(match_operand:XF 3 "mult_operator" "")
14683 (const_string "fmul")
14684 (match_operand:XF 3 "div_operator" "")
14685 (const_string "fdiv")
14686 ]
14687 (const_string "fop")))
14688 (set_attr "fp_int_src" "true")
14689 (set_attr "mode" "SI")
14690 (set_attr "ppro_uops" "many")])
14691
14692 (define_insn "*fop_xf_3"
14693 [(set (match_operand:XF 0 "register_operand" "=f,f")
14694 (match_operator:XF 3 "binary_fp_operator"
14695 [(match_operand:XF 1 "register_operand" "0,0")
14696 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14697 "TARGET_80387 && TARGET_USE_FIOP"
14698 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14699 [(set (attr "type")
14700 (cond [(match_operand:XF 3 "mult_operator" "")
14701 (const_string "fmul")
14702 (match_operand:XF 3 "div_operator" "")
14703 (const_string "fdiv")
14704 ]
14705 (const_string "fop")))
14706 (set_attr "fp_int_src" "true")
14707 (set_attr "mode" "SI")
14708 (set_attr "ppro_uops" "many")])
14709
14710 (define_insn "*fop_xf_4"
14711 [(set (match_operand:XF 0 "register_operand" "=f,f")
14712 (match_operator:XF 3 "binary_fp_operator"
14713 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14714 (match_operand:XF 2 "register_operand" "0,f")]))]
14715 "TARGET_80387"
14716 "* return output_387_binary_op (insn, operands);"
14717 [(set (attr "type")
14718 (cond [(match_operand:XF 3 "mult_operator" "")
14719 (const_string "fmul")
14720 (match_operand:XF 3 "div_operator" "")
14721 (const_string "fdiv")
14722 ]
14723 (const_string "fop")))
14724 (set_attr "mode" "SF")])
14725
14726 (define_insn "*fop_xf_5"
14727 [(set (match_operand:XF 0 "register_operand" "=f,f")
14728 (match_operator:XF 3 "binary_fp_operator"
14729 [(match_operand:XF 1 "register_operand" "0,f")
14730 (float_extend:XF
14731 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14732 "TARGET_80387"
14733 "* return output_387_binary_op (insn, operands);"
14734 [(set (attr "type")
14735 (cond [(match_operand:XF 3 "mult_operator" "")
14736 (const_string "fmul")
14737 (match_operand:XF 3 "div_operator" "")
14738 (const_string "fdiv")
14739 ]
14740 (const_string "fop")))
14741 (set_attr "mode" "SF")])
14742
14743 (define_insn "*fop_xf_6"
14744 [(set (match_operand:XF 0 "register_operand" "=f,f")
14745 (match_operator:XF 3 "binary_fp_operator"
14746 [(float_extend:XF
14747 (match_operand 1 "register_operand" "0,f"))
14748 (float_extend:XF
14749 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14750 "TARGET_80387"
14751 "* return output_387_binary_op (insn, operands);"
14752 [(set (attr "type")
14753 (cond [(match_operand:XF 3 "mult_operator" "")
14754 (const_string "fmul")
14755 (match_operand:XF 3 "div_operator" "")
14756 (const_string "fdiv")
14757 ]
14758 (const_string "fop")))
14759 (set_attr "mode" "SF")])
14760
14761 (define_split
14762 [(set (match_operand 0 "register_operand" "")
14763 (match_operator 3 "binary_fp_operator"
14764 [(float (match_operand:SI 1 "register_operand" ""))
14765 (match_operand 2 "register_operand" "")]))]
14766 "TARGET_80387 && reload_completed
14767 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14768 [(const_int 0)]
14769 {
14770 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14771 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14772 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14773 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14774 GET_MODE (operands[3]),
14775 operands[4],
14776 operands[2])));
14777 ix86_free_from_memory (GET_MODE (operands[1]));
14778 DONE;
14779 })
14780
14781 (define_split
14782 [(set (match_operand 0 "register_operand" "")
14783 (match_operator 3 "binary_fp_operator"
14784 [(match_operand 1 "register_operand" "")
14785 (float (match_operand:SI 2 "register_operand" ""))]))]
14786 "TARGET_80387 && reload_completed
14787 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14788 [(const_int 0)]
14789 {
14790 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14791 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14792 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14793 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14794 GET_MODE (operands[3]),
14795 operands[1],
14796 operands[4])));
14797 ix86_free_from_memory (GET_MODE (operands[2]));
14798 DONE;
14799 })
14800 \f
14801 ;; FPU special functions.
14802
14803 (define_expand "sqrtsf2"
14804 [(set (match_operand:SF 0 "register_operand" "")
14805 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14806 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14807 {
14808 if (!TARGET_SSE_MATH)
14809 operands[1] = force_reg (SFmode, operands[1]);
14810 })
14811
14812 (define_insn "sqrtsf2_1"
14813 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14814 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14815 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14816 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14817 "@
14818 fsqrt
14819 sqrtss\t{%1, %0|%0, %1}"
14820 [(set_attr "type" "fpspc,sse")
14821 (set_attr "mode" "SF,SF")
14822 (set_attr "athlon_decode" "direct,*")])
14823
14824 (define_insn "sqrtsf2_1_sse_only"
14825 [(set (match_operand:SF 0 "register_operand" "=x")
14826 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14827 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14828 "sqrtss\t{%1, %0|%0, %1}"
14829 [(set_attr "type" "sse")
14830 (set_attr "mode" "SF")
14831 (set_attr "athlon_decode" "*")])
14832
14833 (define_insn "sqrtsf2_i387"
14834 [(set (match_operand:SF 0 "register_operand" "=f")
14835 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14836 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14837 && !TARGET_SSE_MATH"
14838 "fsqrt"
14839 [(set_attr "type" "fpspc")
14840 (set_attr "mode" "SF")
14841 (set_attr "athlon_decode" "direct")])
14842
14843 (define_expand "sqrtdf2"
14844 [(set (match_operand:DF 0 "register_operand" "")
14845 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14846 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14847 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14848 {
14849 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14850 operands[1] = force_reg (DFmode, operands[1]);
14851 })
14852
14853 (define_insn "sqrtdf2_1"
14854 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14855 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14856 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14857 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14858 "@
14859 fsqrt
14860 sqrtsd\t{%1, %0|%0, %1}"
14861 [(set_attr "type" "fpspc,sse")
14862 (set_attr "mode" "DF,DF")
14863 (set_attr "athlon_decode" "direct,*")])
14864
14865 (define_insn "sqrtdf2_1_sse_only"
14866 [(set (match_operand:DF 0 "register_operand" "=Y")
14867 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14868 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14869 "sqrtsd\t{%1, %0|%0, %1}"
14870 [(set_attr "type" "sse")
14871 (set_attr "mode" "DF")
14872 (set_attr "athlon_decode" "*")])
14873
14874 (define_insn "sqrtdf2_i387"
14875 [(set (match_operand:DF 0 "register_operand" "=f")
14876 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14877 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14878 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14879 "fsqrt"
14880 [(set_attr "type" "fpspc")
14881 (set_attr "mode" "DF")
14882 (set_attr "athlon_decode" "direct")])
14883
14884 (define_insn "*sqrtextendsfdf2"
14885 [(set (match_operand:DF 0 "register_operand" "=f")
14886 (sqrt:DF (float_extend:DF
14887 (match_operand:SF 1 "register_operand" "0"))))]
14888 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14889 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14890 "fsqrt"
14891 [(set_attr "type" "fpspc")
14892 (set_attr "mode" "DF")
14893 (set_attr "athlon_decode" "direct")])
14894
14895 (define_insn "sqrtxf2"
14896 [(set (match_operand:XF 0 "register_operand" "=f")
14897 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14898 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14899 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14900 "fsqrt"
14901 [(set_attr "type" "fpspc")
14902 (set_attr "mode" "XF")
14903 (set_attr "athlon_decode" "direct")])
14904
14905 (define_insn "*sqrtextenddfxf2"
14906 [(set (match_operand:XF 0 "register_operand" "=f")
14907 (sqrt:XF (float_extend:XF
14908 (match_operand:DF 1 "register_operand" "0"))))]
14909 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14910 "fsqrt"
14911 [(set_attr "type" "fpspc")
14912 (set_attr "mode" "XF")
14913 (set_attr "athlon_decode" "direct")])
14914
14915 (define_insn "*sqrtextendsfxf2"
14916 [(set (match_operand:XF 0 "register_operand" "=f")
14917 (sqrt:XF (float_extend:XF
14918 (match_operand:SF 1 "register_operand" "0"))))]
14919 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14920 "fsqrt"
14921 [(set_attr "type" "fpspc")
14922 (set_attr "mode" "XF")
14923 (set_attr "athlon_decode" "direct")])
14924
14925 (define_insn "sindf2"
14926 [(set (match_operand:DF 0 "register_operand" "=f")
14927 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14928 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14929 && flag_unsafe_math_optimizations"
14930 "fsin"
14931 [(set_attr "type" "fpspc")
14932 (set_attr "mode" "DF")])
14933
14934 (define_insn "sinsf2"
14935 [(set (match_operand:SF 0 "register_operand" "=f")
14936 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14937 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14938 && flag_unsafe_math_optimizations"
14939 "fsin"
14940 [(set_attr "type" "fpspc")
14941 (set_attr "mode" "SF")])
14942
14943 (define_insn "*sinextendsfdf2"
14944 [(set (match_operand:DF 0 "register_operand" "=f")
14945 (unspec:DF [(float_extend:DF
14946 (match_operand:SF 1 "register_operand" "0"))]
14947 UNSPEC_SIN))]
14948 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14949 && flag_unsafe_math_optimizations"
14950 "fsin"
14951 [(set_attr "type" "fpspc")
14952 (set_attr "mode" "DF")])
14953
14954 (define_insn "sinxf2"
14955 [(set (match_operand:XF 0 "register_operand" "=f")
14956 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14957 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14958 && flag_unsafe_math_optimizations"
14959 "fsin"
14960 [(set_attr "type" "fpspc")
14961 (set_attr "mode" "XF")])
14962
14963 (define_insn "cosdf2"
14964 [(set (match_operand:DF 0 "register_operand" "=f")
14965 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14966 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14967 && flag_unsafe_math_optimizations"
14968 "fcos"
14969 [(set_attr "type" "fpspc")
14970 (set_attr "mode" "DF")])
14971
14972 (define_insn "cossf2"
14973 [(set (match_operand:SF 0 "register_operand" "=f")
14974 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14975 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14976 && flag_unsafe_math_optimizations"
14977 "fcos"
14978 [(set_attr "type" "fpspc")
14979 (set_attr "mode" "SF")])
14980
14981 (define_insn "*cosextendsfdf2"
14982 [(set (match_operand:DF 0 "register_operand" "=f")
14983 (unspec:DF [(float_extend:DF
14984 (match_operand:SF 1 "register_operand" "0"))]
14985 UNSPEC_COS))]
14986 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14987 && flag_unsafe_math_optimizations"
14988 "fcos"
14989 [(set_attr "type" "fpspc")
14990 (set_attr "mode" "DF")])
14991
14992 (define_insn "cosxf2"
14993 [(set (match_operand:XF 0 "register_operand" "=f")
14994 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14995 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14996 && flag_unsafe_math_optimizations"
14997 "fcos"
14998 [(set_attr "type" "fpspc")
14999 (set_attr "mode" "XF")])
15000
15001 (define_insn "atan2df3_1"
15002 [(set (match_operand:DF 0 "register_operand" "=f")
15003 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15004 (match_operand:DF 1 "register_operand" "u")]
15005 UNSPEC_FPATAN))
15006 (clobber (match_scratch:DF 3 "=1"))]
15007 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15008 && flag_unsafe_math_optimizations"
15009 "fpatan"
15010 [(set_attr "type" "fpspc")
15011 (set_attr "mode" "DF")])
15012
15013 (define_expand "atan2df3"
15014 [(use (match_operand:DF 0 "register_operand" "=f"))
15015 (use (match_operand:DF 2 "register_operand" "0"))
15016 (use (match_operand:DF 1 "register_operand" "u"))]
15017 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15018 && flag_unsafe_math_optimizations"
15019 {
15020 rtx copy = gen_reg_rtx (DFmode);
15021 emit_move_insn (copy, operands[1]);
15022 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15023 DONE;
15024 })
15025
15026 (define_insn "atan2sf3_1"
15027 [(set (match_operand:SF 0 "register_operand" "=f")
15028 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15029 (match_operand:SF 1 "register_operand" "u")]
15030 UNSPEC_FPATAN))
15031 (clobber (match_scratch:SF 3 "=1"))]
15032 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033 && flag_unsafe_math_optimizations"
15034 "fpatan"
15035 [(set_attr "type" "fpspc")
15036 (set_attr "mode" "SF")])
15037
15038 (define_expand "atan2sf3"
15039 [(use (match_operand:SF 0 "register_operand" "=f"))
15040 (use (match_operand:SF 2 "register_operand" "0"))
15041 (use (match_operand:SF 1 "register_operand" "u"))]
15042 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15043 && flag_unsafe_math_optimizations"
15044 {
15045 rtx copy = gen_reg_rtx (SFmode);
15046 emit_move_insn (copy, operands[1]);
15047 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15048 DONE;
15049 })
15050
15051 (define_insn "atan2xf3_1"
15052 [(set (match_operand:XF 0 "register_operand" "=f")
15053 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15054 (match_operand:XF 1 "register_operand" "u")]
15055 UNSPEC_FPATAN))
15056 (clobber (match_scratch:XF 3 "=1"))]
15057 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15058 && flag_unsafe_math_optimizations"
15059 "fpatan"
15060 [(set_attr "type" "fpspc")
15061 (set_attr "mode" "XF")])
15062
15063 (define_expand "atan2xf3"
15064 [(use (match_operand:XF 0 "register_operand" "=f"))
15065 (use (match_operand:XF 2 "register_operand" "0"))
15066 (use (match_operand:XF 1 "register_operand" "u"))]
15067 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15068 && flag_unsafe_math_optimizations"
15069 {
15070 rtx copy = gen_reg_rtx (XFmode);
15071 emit_move_insn (copy, operands[1]);
15072 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15073 DONE;
15074 })
15075
15076 (define_insn "*fyl2x_sfxf3"
15077 [(set (match_operand:SF 0 "register_operand" "=f")
15078 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15079 (match_operand:XF 1 "register_operand" "u")]
15080 UNSPEC_FYL2X))
15081 (clobber (match_scratch:SF 3 "=1"))]
15082 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15083 && flag_unsafe_math_optimizations"
15084 "fyl2x"
15085 [(set_attr "type" "fpspc")
15086 (set_attr "mode" "SF")])
15087
15088 (define_insn "*fyl2x_dfxf3"
15089 [(set (match_operand:DF 0 "register_operand" "=f")
15090 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15091 (match_operand:XF 1 "register_operand" "u")]
15092 UNSPEC_FYL2X))
15093 (clobber (match_scratch:DF 3 "=1"))]
15094 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15095 && flag_unsafe_math_optimizations"
15096 "fyl2x"
15097 [(set_attr "type" "fpspc")
15098 (set_attr "mode" "DF")])
15099
15100 (define_insn "*fyl2x_xf3"
15101 [(set (match_operand:XF 0 "register_operand" "=f")
15102 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15103 (match_operand:XF 1 "register_operand" "u")]
15104 UNSPEC_FYL2X))
15105 (clobber (match_scratch:XF 3 "=1"))]
15106 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15107 && flag_unsafe_math_optimizations"
15108 "fyl2x"
15109 [(set_attr "type" "fpspc")
15110 (set_attr "mode" "XF")])
15111
15112 (define_expand "logsf2"
15113 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15114 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15115 (match_dup 2)] UNSPEC_FYL2X))
15116 (clobber (match_scratch:SF 3 ""))])]
15117 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15118 && flag_unsafe_math_optimizations"
15119 {
15120 rtx temp;
15121
15122 operands[2] = gen_reg_rtx (XFmode);
15123 temp = standard_80387_constant_rtx (4); /* fldln2 */
15124 emit_move_insn (operands[2], temp);
15125 })
15126
15127 (define_expand "logdf2"
15128 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15129 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15130 (match_dup 2)] UNSPEC_FYL2X))
15131 (clobber (match_scratch:DF 3 ""))])]
15132 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15133 && flag_unsafe_math_optimizations"
15134 {
15135 rtx temp;
15136
15137 operands[2] = gen_reg_rtx (XFmode);
15138 temp = standard_80387_constant_rtx (4); /* fldln2 */
15139 emit_move_insn (operands[2], temp);
15140 })
15141
15142 (define_expand "logxf2"
15143 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15144 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15145 (match_dup 2)] UNSPEC_FYL2X))
15146 (clobber (match_scratch:XF 3 ""))])]
15147 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15148 && flag_unsafe_math_optimizations"
15149 {
15150 rtx temp;
15151
15152 operands[2] = gen_reg_rtx (XFmode);
15153 temp = standard_80387_constant_rtx (4); /* fldln2 */
15154 emit_move_insn (operands[2], temp);
15155 })
15156
15157 (define_expand "log10sf2"
15158 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15159 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15160 (match_dup 2)] UNSPEC_FYL2X))
15161 (clobber (match_scratch:SF 3 ""))])]
15162 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15163 && flag_unsafe_math_optimizations"
15164 {
15165 rtx temp;
15166
15167 operands[2] = gen_reg_rtx (XFmode);
15168 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15169 emit_move_insn (operands[2], temp);
15170 })
15171
15172 (define_expand "log10df2"
15173 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15174 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15175 (match_dup 2)] UNSPEC_FYL2X))
15176 (clobber (match_scratch:DF 3 ""))])]
15177 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15178 && flag_unsafe_math_optimizations"
15179 {
15180 rtx temp;
15181
15182 operands[2] = gen_reg_rtx (XFmode);
15183 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15184 emit_move_insn (operands[2], temp);
15185 })
15186
15187 (define_expand "log10xf2"
15188 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15189 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15190 (match_dup 2)] UNSPEC_FYL2X))
15191 (clobber (match_scratch:XF 3 ""))])]
15192 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15193 && flag_unsafe_math_optimizations"
15194 {
15195 rtx temp;
15196
15197 operands[2] = gen_reg_rtx (XFmode);
15198 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15199 emit_move_insn (operands[2], temp);
15200 })
15201
15202 (define_expand "log2sf2"
15203 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15204 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15205 (match_dup 2)] UNSPEC_FYL2X))
15206 (clobber (match_scratch:SF 3 ""))])]
15207 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15208 && flag_unsafe_math_optimizations"
15209 {
15210 operands[2] = gen_reg_rtx (XFmode);
15211 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15212
15213 })
15214
15215 (define_expand "log2df2"
15216 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15217 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15218 (match_dup 2)] UNSPEC_FYL2X))
15219 (clobber (match_scratch:DF 3 ""))])]
15220 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15221 && flag_unsafe_math_optimizations"
15222 {
15223 operands[2] = gen_reg_rtx (XFmode);
15224 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15225 })
15226
15227 (define_expand "log2xf2"
15228 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15229 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15230 (match_dup 2)] UNSPEC_FYL2X))
15231 (clobber (match_scratch:XF 3 ""))])]
15232 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15233 && flag_unsafe_math_optimizations"
15234 {
15235 operands[2] = gen_reg_rtx (XFmode);
15236 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15237 })
15238
15239 (define_insn "*fscale_sfxf3"
15240 [(set (match_operand:SF 0 "register_operand" "=f")
15241 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15242 (match_operand:XF 1 "register_operand" "u")]
15243 UNSPEC_FSCALE))
15244 (clobber (match_scratch:SF 3 "=1"))]
15245 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15246 && flag_unsafe_math_optimizations"
15247 "fscale\;fstp\t%y1"
15248 [(set_attr "type" "fpspc")
15249 (set_attr "mode" "SF")])
15250
15251 (define_insn "*fscale_dfxf3"
15252 [(set (match_operand:DF 0 "register_operand" "=f")
15253 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15254 (match_operand:XF 1 "register_operand" "u")]
15255 UNSPEC_FSCALE))
15256 (clobber (match_scratch:DF 3 "=1"))]
15257 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15258 && flag_unsafe_math_optimizations"
15259 "fscale\;fstp\t%y1"
15260 [(set_attr "type" "fpspc")
15261 (set_attr "mode" "DF")])
15262
15263 (define_insn "*fscale_xf3"
15264 [(set (match_operand:XF 0 "register_operand" "=f")
15265 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15266 (match_operand:XF 1 "register_operand" "u")]
15267 UNSPEC_FSCALE))
15268 (clobber (match_scratch:XF 3 "=1"))]
15269 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15270 && flag_unsafe_math_optimizations"
15271 "fscale\;fstp\t%y1"
15272 [(set_attr "type" "fpspc")
15273 (set_attr "mode" "XF")])
15274
15275 (define_insn "*frndintxf2"
15276 [(set (match_operand:XF 0 "register_operand" "=f")
15277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15278 UNSPEC_FRNDINT))]
15279 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15280 && flag_unsafe_math_optimizations"
15281 "frndint"
15282 [(set_attr "type" "fpspc")
15283 (set_attr "mode" "XF")])
15284
15285 (define_insn "*f2xm1xf2"
15286 [(set (match_operand:XF 0 "register_operand" "=f")
15287 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15288 UNSPEC_F2XM1))]
15289 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15290 && flag_unsafe_math_optimizations"
15291 "f2xm1"
15292 [(set_attr "type" "fpspc")
15293 (set_attr "mode" "XF")])
15294
15295 (define_expand "expsf2"
15296 [(set (match_dup 2)
15297 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15298 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15299 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15300 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15301 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15302 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15303 (parallel [(set (match_operand:SF 0 "register_operand" "")
15304 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15305 (clobber (match_scratch:SF 5 ""))])]
15306 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15307 && flag_unsafe_math_optimizations"
15308 {
15309 rtx temp;
15310 int i;
15311
15312 for (i=2; i<10; i++)
15313 operands[i] = gen_reg_rtx (XFmode);
15314 temp = standard_80387_constant_rtx (5); /* fldl2e */
15315 emit_move_insn (operands[3], temp);
15316 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15317 })
15318
15319 (define_expand "expdf2"
15320 [(set (match_dup 2)
15321 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15322 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15323 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15324 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15325 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15326 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15327 (parallel [(set (match_operand:DF 0 "register_operand" "")
15328 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15329 (clobber (match_scratch:DF 5 ""))])]
15330 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15331 && flag_unsafe_math_optimizations"
15332 {
15333 rtx temp;
15334 int i;
15335
15336 for (i=2; i<10; i++)
15337 operands[i] = gen_reg_rtx (XFmode);
15338 temp = standard_80387_constant_rtx (5); /* fldl2e */
15339 emit_move_insn (operands[3], temp);
15340 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15341 })
15342
15343 (define_expand "expxf2"
15344 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15345 (match_dup 2)))
15346 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15347 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15348 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15349 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15350 (parallel [(set (match_operand:XF 0 "register_operand" "")
15351 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15352 (clobber (match_scratch:XF 5 ""))])]
15353 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15354 && flag_unsafe_math_optimizations"
15355 {
15356 rtx temp;
15357 int i;
15358
15359 for (i=2; i<9; i++)
15360 operands[i] = gen_reg_rtx (XFmode);
15361 temp = standard_80387_constant_rtx (5); /* fldl2e */
15362 emit_move_insn (operands[2], temp);
15363 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15364 })
15365
15366 (define_expand "atansf2"
15367 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15368 (unspec:SF [(match_dup 2)
15369 (match_operand:SF 1 "register_operand" "")]
15370 UNSPEC_FPATAN))
15371 (clobber (match_scratch:SF 3 ""))])]
15372 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15373 && flag_unsafe_math_optimizations"
15374 {
15375 operands[2] = gen_reg_rtx (SFmode);
15376 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15377 })
15378
15379 (define_expand "atandf2"
15380 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15381 (unspec:DF [(match_dup 2)
15382 (match_operand:DF 1 "register_operand" "")]
15383 UNSPEC_FPATAN))
15384 (clobber (match_scratch:DF 3 ""))])]
15385 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15386 && flag_unsafe_math_optimizations"
15387 {
15388 operands[2] = gen_reg_rtx (DFmode);
15389 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15390 })
15391
15392 (define_expand "atanxf2"
15393 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15394 (unspec:XF [(match_dup 2)
15395 (match_operand:XF 1 "register_operand" "")]
15396 UNSPEC_FPATAN))
15397 (clobber (match_scratch:XF 3 ""))])]
15398 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15399 && flag_unsafe_math_optimizations"
15400 {
15401 operands[2] = gen_reg_rtx (XFmode);
15402 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15403 })
15404 \f
15405 ;; Block operation instructions
15406
15407 (define_insn "cld"
15408 [(set (reg:SI 19) (const_int 0))]
15409 ""
15410 "cld"
15411 [(set_attr "type" "cld")])
15412
15413 (define_expand "movstrsi"
15414 [(use (match_operand:BLK 0 "memory_operand" ""))
15415 (use (match_operand:BLK 1 "memory_operand" ""))
15416 (use (match_operand:SI 2 "nonmemory_operand" ""))
15417 (use (match_operand:SI 3 "const_int_operand" ""))]
15418 "! optimize_size"
15419 {
15420 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15421 DONE;
15422 else
15423 FAIL;
15424 })
15425
15426 (define_expand "movstrdi"
15427 [(use (match_operand:BLK 0 "memory_operand" ""))
15428 (use (match_operand:BLK 1 "memory_operand" ""))
15429 (use (match_operand:DI 2 "nonmemory_operand" ""))
15430 (use (match_operand:DI 3 "const_int_operand" ""))]
15431 "TARGET_64BIT"
15432 {
15433 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15434 DONE;
15435 else
15436 FAIL;
15437 })
15438
15439 ;; Most CPUs don't like single string operations
15440 ;; Handle this case here to simplify previous expander.
15441
15442 (define_expand "strmov"
15443 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15444 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15445 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15446 (clobber (reg:CC 17))])
15447 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15448 (clobber (reg:CC 17))])]
15449 ""
15450 {
15451 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15452
15453 /* If .md ever supports :P for Pmode, these can be directly
15454 in the pattern above. */
15455 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15456 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15457
15458 if (TARGET_SINGLE_STRINGOP || optimize_size)
15459 {
15460 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15461 operands[2], operands[3],
15462 operands[5], operands[6]));
15463 DONE;
15464 }
15465
15466 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15467 })
15468
15469 (define_expand "strmov_singleop"
15470 [(parallel [(set (match_operand 1 "memory_operand" "")
15471 (match_operand 3 "memory_operand" ""))
15472 (set (match_operand 0 "register_operand" "")
15473 (match_operand 4 "" ""))
15474 (set (match_operand 2 "register_operand" "")
15475 (match_operand 5 "" ""))
15476 (use (reg:SI 19))])]
15477 "TARGET_SINGLE_STRINGOP || optimize_size"
15478 "")
15479
15480 (define_insn "*strmovdi_rex_1"
15481 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15482 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15483 (set (match_operand:DI 0 "register_operand" "=D")
15484 (plus:DI (match_dup 2)
15485 (const_int 8)))
15486 (set (match_operand:DI 1 "register_operand" "=S")
15487 (plus:DI (match_dup 3)
15488 (const_int 8)))
15489 (use (reg:SI 19))]
15490 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15491 "movsq"
15492 [(set_attr "type" "str")
15493 (set_attr "mode" "DI")
15494 (set_attr "memory" "both")])
15495
15496 (define_insn "*strmovsi_1"
15497 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15498 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15499 (set (match_operand:SI 0 "register_operand" "=D")
15500 (plus:SI (match_dup 2)
15501 (const_int 4)))
15502 (set (match_operand:SI 1 "register_operand" "=S")
15503 (plus:SI (match_dup 3)
15504 (const_int 4)))
15505 (use (reg:SI 19))]
15506 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15507 "{movsl|movsd}"
15508 [(set_attr "type" "str")
15509 (set_attr "mode" "SI")
15510 (set_attr "memory" "both")])
15511
15512 (define_insn "*strmovsi_rex_1"
15513 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15514 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15515 (set (match_operand:DI 0 "register_operand" "=D")
15516 (plus:DI (match_dup 2)
15517 (const_int 4)))
15518 (set (match_operand:DI 1 "register_operand" "=S")
15519 (plus:DI (match_dup 3)
15520 (const_int 4)))
15521 (use (reg:SI 19))]
15522 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15523 "{movsl|movsd}"
15524 [(set_attr "type" "str")
15525 (set_attr "mode" "SI")
15526 (set_attr "memory" "both")])
15527
15528 (define_insn "*strmovhi_1"
15529 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15530 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15531 (set (match_operand:SI 0 "register_operand" "=D")
15532 (plus:SI (match_dup 2)
15533 (const_int 2)))
15534 (set (match_operand:SI 1 "register_operand" "=S")
15535 (plus:SI (match_dup 3)
15536 (const_int 2)))
15537 (use (reg:SI 19))]
15538 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15539 "movsw"
15540 [(set_attr "type" "str")
15541 (set_attr "memory" "both")
15542 (set_attr "mode" "HI")])
15543
15544 (define_insn "*strmovhi_rex_1"
15545 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15546 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15547 (set (match_operand:DI 0 "register_operand" "=D")
15548 (plus:DI (match_dup 2)
15549 (const_int 2)))
15550 (set (match_operand:DI 1 "register_operand" "=S")
15551 (plus:DI (match_dup 3)
15552 (const_int 2)))
15553 (use (reg:SI 19))]
15554 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15555 "movsw"
15556 [(set_attr "type" "str")
15557 (set_attr "memory" "both")
15558 (set_attr "mode" "HI")])
15559
15560 (define_insn "*strmovqi_1"
15561 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15562 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15563 (set (match_operand:SI 0 "register_operand" "=D")
15564 (plus:SI (match_dup 2)
15565 (const_int 1)))
15566 (set (match_operand:SI 1 "register_operand" "=S")
15567 (plus:SI (match_dup 3)
15568 (const_int 1)))
15569 (use (reg:SI 19))]
15570 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15571 "movsb"
15572 [(set_attr "type" "str")
15573 (set_attr "memory" "both")
15574 (set_attr "mode" "QI")])
15575
15576 (define_insn "*strmovqi_rex_1"
15577 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15578 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15579 (set (match_operand:DI 0 "register_operand" "=D")
15580 (plus:DI (match_dup 2)
15581 (const_int 1)))
15582 (set (match_operand:DI 1 "register_operand" "=S")
15583 (plus:DI (match_dup 3)
15584 (const_int 1)))
15585 (use (reg:SI 19))]
15586 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15587 "movsb"
15588 [(set_attr "type" "str")
15589 (set_attr "memory" "both")
15590 (set_attr "mode" "QI")])
15591
15592 (define_expand "rep_mov"
15593 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15594 (set (match_operand 0 "register_operand" "")
15595 (match_operand 5 "" ""))
15596 (set (match_operand 2 "register_operand" "")
15597 (match_operand 6 "" ""))
15598 (set (match_operand 1 "memory_operand" "")
15599 (match_operand 3 "memory_operand" ""))
15600 (use (match_dup 4))
15601 (use (reg:SI 19))])]
15602 ""
15603 "")
15604
15605 (define_insn "*rep_movdi_rex64"
15606 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15607 (set (match_operand:DI 0 "register_operand" "=D")
15608 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15609 (const_int 3))
15610 (match_operand:DI 3 "register_operand" "0")))
15611 (set (match_operand:DI 1 "register_operand" "=S")
15612 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15613 (match_operand:DI 4 "register_operand" "1")))
15614 (set (mem:BLK (match_dup 3))
15615 (mem:BLK (match_dup 4)))
15616 (use (match_dup 5))
15617 (use (reg:SI 19))]
15618 "TARGET_64BIT"
15619 "{rep\;movsq|rep movsq}"
15620 [(set_attr "type" "str")
15621 (set_attr "prefix_rep" "1")
15622 (set_attr "memory" "both")
15623 (set_attr "mode" "DI")])
15624
15625 (define_insn "*rep_movsi"
15626 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15627 (set (match_operand:SI 0 "register_operand" "=D")
15628 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15629 (const_int 2))
15630 (match_operand:SI 3 "register_operand" "0")))
15631 (set (match_operand:SI 1 "register_operand" "=S")
15632 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15633 (match_operand:SI 4 "register_operand" "1")))
15634 (set (mem:BLK (match_dup 3))
15635 (mem:BLK (match_dup 4)))
15636 (use (match_dup 5))
15637 (use (reg:SI 19))]
15638 "!TARGET_64BIT"
15639 "{rep\;movsl|rep movsd}"
15640 [(set_attr "type" "str")
15641 (set_attr "prefix_rep" "1")
15642 (set_attr "memory" "both")
15643 (set_attr "mode" "SI")])
15644
15645 (define_insn "*rep_movsi_rex64"
15646 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15647 (set (match_operand:DI 0 "register_operand" "=D")
15648 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15649 (const_int 2))
15650 (match_operand:DI 3 "register_operand" "0")))
15651 (set (match_operand:DI 1 "register_operand" "=S")
15652 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15653 (match_operand:DI 4 "register_operand" "1")))
15654 (set (mem:BLK (match_dup 3))
15655 (mem:BLK (match_dup 4)))
15656 (use (match_dup 5))
15657 (use (reg:SI 19))]
15658 "TARGET_64BIT"
15659 "{rep\;movsl|rep movsd}"
15660 [(set_attr "type" "str")
15661 (set_attr "prefix_rep" "1")
15662 (set_attr "memory" "both")
15663 (set_attr "mode" "SI")])
15664
15665 (define_insn "*rep_movqi"
15666 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15667 (set (match_operand:SI 0 "register_operand" "=D")
15668 (plus:SI (match_operand:SI 3 "register_operand" "0")
15669 (match_operand:SI 5 "register_operand" "2")))
15670 (set (match_operand:SI 1 "register_operand" "=S")
15671 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15672 (set (mem:BLK (match_dup 3))
15673 (mem:BLK (match_dup 4)))
15674 (use (match_dup 5))
15675 (use (reg:SI 19))]
15676 "!TARGET_64BIT"
15677 "{rep\;movsb|rep movsb}"
15678 [(set_attr "type" "str")
15679 (set_attr "prefix_rep" "1")
15680 (set_attr "memory" "both")
15681 (set_attr "mode" "SI")])
15682
15683 (define_insn "*rep_movqi_rex64"
15684 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15685 (set (match_operand:DI 0 "register_operand" "=D")
15686 (plus:DI (match_operand:DI 3 "register_operand" "0")
15687 (match_operand:DI 5 "register_operand" "2")))
15688 (set (match_operand:DI 1 "register_operand" "=S")
15689 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15690 (set (mem:BLK (match_dup 3))
15691 (mem:BLK (match_dup 4)))
15692 (use (match_dup 5))
15693 (use (reg:SI 19))]
15694 "TARGET_64BIT"
15695 "{rep\;movsb|rep movsb}"
15696 [(set_attr "type" "str")
15697 (set_attr "prefix_rep" "1")
15698 (set_attr "memory" "both")
15699 (set_attr "mode" "SI")])
15700
15701 (define_expand "clrstrsi"
15702 [(use (match_operand:BLK 0 "memory_operand" ""))
15703 (use (match_operand:SI 1 "nonmemory_operand" ""))
15704 (use (match_operand 2 "const_int_operand" ""))]
15705 ""
15706 {
15707 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15708 DONE;
15709 else
15710 FAIL;
15711 })
15712
15713 (define_expand "clrstrdi"
15714 [(use (match_operand:BLK 0 "memory_operand" ""))
15715 (use (match_operand:DI 1 "nonmemory_operand" ""))
15716 (use (match_operand 2 "const_int_operand" ""))]
15717 "TARGET_64BIT"
15718 {
15719 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15720 DONE;
15721 else
15722 FAIL;
15723 })
15724
15725 ;; Most CPUs don't like single string operations
15726 ;; Handle this case here to simplify previous expander.
15727
15728 (define_expand "strset"
15729 [(set (match_operand 1 "memory_operand" "")
15730 (match_operand 2 "register_operand" ""))
15731 (parallel [(set (match_operand 0 "register_operand" "")
15732 (match_dup 3))
15733 (clobber (reg:CC 17))])]
15734 ""
15735 {
15736 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15737 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15738
15739 /* If .md ever supports :P for Pmode, this can be directly
15740 in the pattern above. */
15741 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15742 GEN_INT (GET_MODE_SIZE (GET_MODE
15743 (operands[2]))));
15744 if (TARGET_SINGLE_STRINGOP || optimize_size)
15745 {
15746 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15747 operands[3]));
15748 DONE;
15749 }
15750 })
15751
15752 (define_expand "strset_singleop"
15753 [(parallel [(set (match_operand 1 "memory_operand" "")
15754 (match_operand 2 "register_operand" ""))
15755 (set (match_operand 0 "register_operand" "")
15756 (match_operand 3 "" ""))
15757 (use (reg:SI 19))])]
15758 "TARGET_SINGLE_STRINGOP || optimize_size"
15759 "")
15760
15761 (define_insn "*strsetdi_rex_1"
15762 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15763 (match_operand:SI 2 "register_operand" "a"))
15764 (set (match_operand:DI 0 "register_operand" "=D")
15765 (plus:DI (match_dup 1)
15766 (const_int 8)))
15767 (use (reg:SI 19))]
15768 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15769 "stosq"
15770 [(set_attr "type" "str")
15771 (set_attr "memory" "store")
15772 (set_attr "mode" "DI")])
15773
15774 (define_insn "*strsetsi_1"
15775 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15776 (match_operand:SI 2 "register_operand" "a"))
15777 (set (match_operand:SI 0 "register_operand" "=D")
15778 (plus:SI (match_dup 1)
15779 (const_int 4)))
15780 (use (reg:SI 19))]
15781 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15782 "{stosl|stosd}"
15783 [(set_attr "type" "str")
15784 (set_attr "memory" "store")
15785 (set_attr "mode" "SI")])
15786
15787 (define_insn "*strsetsi_rex_1"
15788 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15789 (match_operand:SI 2 "register_operand" "a"))
15790 (set (match_operand:DI 0 "register_operand" "=D")
15791 (plus:DI (match_dup 1)
15792 (const_int 4)))
15793 (use (reg:SI 19))]
15794 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15795 "{stosl|stosd}"
15796 [(set_attr "type" "str")
15797 (set_attr "memory" "store")
15798 (set_attr "mode" "SI")])
15799
15800 (define_insn "*strsethi_1"
15801 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15802 (match_operand:HI 2 "register_operand" "a"))
15803 (set (match_operand:SI 0 "register_operand" "=D")
15804 (plus:SI (match_dup 1)
15805 (const_int 2)))
15806 (use (reg:SI 19))]
15807 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15808 "stosw"
15809 [(set_attr "type" "str")
15810 (set_attr "memory" "store")
15811 (set_attr "mode" "HI")])
15812
15813 (define_insn "*strsethi_rex_1"
15814 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15815 (match_operand:HI 2 "register_operand" "a"))
15816 (set (match_operand:DI 0 "register_operand" "=D")
15817 (plus:DI (match_dup 1)
15818 (const_int 2)))
15819 (use (reg:SI 19))]
15820 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15821 "stosw"
15822 [(set_attr "type" "str")
15823 (set_attr "memory" "store")
15824 (set_attr "mode" "HI")])
15825
15826 (define_insn "*strsetqi_1"
15827 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15828 (match_operand:QI 2 "register_operand" "a"))
15829 (set (match_operand:SI 0 "register_operand" "=D")
15830 (plus:SI (match_dup 1)
15831 (const_int 1)))
15832 (use (reg:SI 19))]
15833 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15834 "stosb"
15835 [(set_attr "type" "str")
15836 (set_attr "memory" "store")
15837 (set_attr "mode" "QI")])
15838
15839 (define_insn "*strsetqi_rex_1"
15840 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15841 (match_operand:QI 2 "register_operand" "a"))
15842 (set (match_operand:DI 0 "register_operand" "=D")
15843 (plus:DI (match_dup 1)
15844 (const_int 1)))
15845 (use (reg:SI 19))]
15846 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15847 "stosb"
15848 [(set_attr "type" "str")
15849 (set_attr "memory" "store")
15850 (set_attr "mode" "QI")])
15851
15852 (define_expand "rep_stos"
15853 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15854 (set (match_operand 0 "register_operand" "")
15855 (match_operand 4 "" ""))
15856 (set (match_operand 2 "memory_operand" "") (const_int 0))
15857 (use (match_operand 3 "register_operand" ""))
15858 (use (match_dup 1))
15859 (use (reg:SI 19))])]
15860 ""
15861 "")
15862
15863 (define_insn "*rep_stosdi_rex64"
15864 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15865 (set (match_operand:DI 0 "register_operand" "=D")
15866 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15867 (const_int 3))
15868 (match_operand:DI 3 "register_operand" "0")))
15869 (set (mem:BLK (match_dup 3))
15870 (const_int 0))
15871 (use (match_operand:DI 2 "register_operand" "a"))
15872 (use (match_dup 4))
15873 (use (reg:SI 19))]
15874 "TARGET_64BIT"
15875 "{rep\;stosq|rep stosq}"
15876 [(set_attr "type" "str")
15877 (set_attr "prefix_rep" "1")
15878 (set_attr "memory" "store")
15879 (set_attr "mode" "DI")])
15880
15881 (define_insn "*rep_stossi"
15882 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15883 (set (match_operand:SI 0 "register_operand" "=D")
15884 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15885 (const_int 2))
15886 (match_operand:SI 3 "register_operand" "0")))
15887 (set (mem:BLK (match_dup 3))
15888 (const_int 0))
15889 (use (match_operand:SI 2 "register_operand" "a"))
15890 (use (match_dup 4))
15891 (use (reg:SI 19))]
15892 "!TARGET_64BIT"
15893 "{rep\;stosl|rep stosd}"
15894 [(set_attr "type" "str")
15895 (set_attr "prefix_rep" "1")
15896 (set_attr "memory" "store")
15897 (set_attr "mode" "SI")])
15898
15899 (define_insn "*rep_stossi_rex64"
15900 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15901 (set (match_operand:DI 0 "register_operand" "=D")
15902 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15903 (const_int 2))
15904 (match_operand:DI 3 "register_operand" "0")))
15905 (set (mem:BLK (match_dup 3))
15906 (const_int 0))
15907 (use (match_operand:SI 2 "register_operand" "a"))
15908 (use (match_dup 4))
15909 (use (reg:SI 19))]
15910 "TARGET_64BIT"
15911 "{rep\;stosl|rep stosd}"
15912 [(set_attr "type" "str")
15913 (set_attr "prefix_rep" "1")
15914 (set_attr "memory" "store")
15915 (set_attr "mode" "SI")])
15916
15917 (define_insn "*rep_stosqi"
15918 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15919 (set (match_operand:SI 0 "register_operand" "=D")
15920 (plus:SI (match_operand:SI 3 "register_operand" "0")
15921 (match_operand:SI 4 "register_operand" "1")))
15922 (set (mem:BLK (match_dup 3))
15923 (const_int 0))
15924 (use (match_operand:QI 2 "register_operand" "a"))
15925 (use (match_dup 4))
15926 (use (reg:SI 19))]
15927 "!TARGET_64BIT"
15928 "{rep\;stosb|rep stosb}"
15929 [(set_attr "type" "str")
15930 (set_attr "prefix_rep" "1")
15931 (set_attr "memory" "store")
15932 (set_attr "mode" "QI")])
15933
15934 (define_insn "*rep_stosqi_rex64"
15935 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15936 (set (match_operand:DI 0 "register_operand" "=D")
15937 (plus:DI (match_operand:DI 3 "register_operand" "0")
15938 (match_operand:DI 4 "register_operand" "1")))
15939 (set (mem:BLK (match_dup 3))
15940 (const_int 0))
15941 (use (match_operand:QI 2 "register_operand" "a"))
15942 (use (match_dup 4))
15943 (use (reg:SI 19))]
15944 "TARGET_64BIT"
15945 "{rep\;stosb|rep stosb}"
15946 [(set_attr "type" "str")
15947 (set_attr "prefix_rep" "1")
15948 (set_attr "memory" "store")
15949 (set_attr "mode" "QI")])
15950
15951 (define_expand "cmpstrsi"
15952 [(set (match_operand:SI 0 "register_operand" "")
15953 (compare:SI (match_operand:BLK 1 "general_operand" "")
15954 (match_operand:BLK 2 "general_operand" "")))
15955 (use (match_operand 3 "general_operand" ""))
15956 (use (match_operand 4 "immediate_operand" ""))]
15957 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15958 {
15959 rtx addr1, addr2, out, outlow, count, countreg, align;
15960
15961 /* Can't use this if the user has appropriated esi or edi. */
15962 if (global_regs[4] || global_regs[5])
15963 FAIL;
15964
15965 out = operands[0];
15966 if (GET_CODE (out) != REG)
15967 out = gen_reg_rtx (SImode);
15968
15969 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15970 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15971 if (addr1 != XEXP (operands[1], 0))
15972 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15973 if (addr2 != XEXP (operands[2], 0))
15974 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15975
15976 count = operands[3];
15977 countreg = ix86_zero_extend_to_Pmode (count);
15978
15979 /* %%% Iff we are testing strict equality, we can use known alignment
15980 to good advantage. This may be possible with combine, particularly
15981 once cc0 is dead. */
15982 align = operands[4];
15983
15984 emit_insn (gen_cld ());
15985 if (GET_CODE (count) == CONST_INT)
15986 {
15987 if (INTVAL (count) == 0)
15988 {
15989 emit_move_insn (operands[0], const0_rtx);
15990 DONE;
15991 }
15992 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15993 operands[1], operands[2]));
15994 }
15995 else
15996 {
15997 if (TARGET_64BIT)
15998 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15999 else
16000 emit_insn (gen_cmpsi_1 (countreg, countreg));
16001 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16002 operands[1], operands[2]));
16003 }
16004
16005 outlow = gen_lowpart (QImode, out);
16006 emit_insn (gen_cmpintqi (outlow));
16007 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16008
16009 if (operands[0] != out)
16010 emit_move_insn (operands[0], out);
16011
16012 DONE;
16013 })
16014
16015 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16016
16017 (define_expand "cmpintqi"
16018 [(set (match_dup 1)
16019 (gtu:QI (reg:CC 17) (const_int 0)))
16020 (set (match_dup 2)
16021 (ltu:QI (reg:CC 17) (const_int 0)))
16022 (parallel [(set (match_operand:QI 0 "register_operand" "")
16023 (minus:QI (match_dup 1)
16024 (match_dup 2)))
16025 (clobber (reg:CC 17))])]
16026 ""
16027 "operands[1] = gen_reg_rtx (QImode);
16028 operands[2] = gen_reg_rtx (QImode);")
16029
16030 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16031 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16032
16033 (define_expand "cmpstrqi_nz_1"
16034 [(parallel [(set (reg:CC 17)
16035 (compare:CC (match_operand 4 "memory_operand" "")
16036 (match_operand 5 "memory_operand" "")))
16037 (use (match_operand 2 "register_operand" ""))
16038 (use (match_operand:SI 3 "immediate_operand" ""))
16039 (use (reg:SI 19))
16040 (clobber (match_operand 0 "register_operand" ""))
16041 (clobber (match_operand 1 "register_operand" ""))
16042 (clobber (match_dup 2))])]
16043 ""
16044 "")
16045
16046 (define_insn "*cmpstrqi_nz_1"
16047 [(set (reg:CC 17)
16048 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16049 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16050 (use (match_operand:SI 6 "register_operand" "2"))
16051 (use (match_operand:SI 3 "immediate_operand" "i"))
16052 (use (reg:SI 19))
16053 (clobber (match_operand:SI 0 "register_operand" "=S"))
16054 (clobber (match_operand:SI 1 "register_operand" "=D"))
16055 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16056 "!TARGET_64BIT"
16057 "repz{\;| }cmpsb"
16058 [(set_attr "type" "str")
16059 (set_attr "mode" "QI")
16060 (set_attr "prefix_rep" "1")])
16061
16062 (define_insn "*cmpstrqi_nz_rex_1"
16063 [(set (reg:CC 17)
16064 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16065 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16066 (use (match_operand:DI 6 "register_operand" "2"))
16067 (use (match_operand:SI 3 "immediate_operand" "i"))
16068 (use (reg:SI 19))
16069 (clobber (match_operand:DI 0 "register_operand" "=S"))
16070 (clobber (match_operand:DI 1 "register_operand" "=D"))
16071 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16072 "TARGET_64BIT"
16073 "repz{\;| }cmpsb"
16074 [(set_attr "type" "str")
16075 (set_attr "mode" "QI")
16076 (set_attr "prefix_rep" "1")])
16077
16078 ;; The same, but the count is not known to not be zero.
16079
16080 (define_expand "cmpstrqi_1"
16081 [(parallel [(set (reg:CC 17)
16082 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16083 (const_int 0))
16084 (compare:CC (match_operand 4 "memory_operand" "")
16085 (match_operand 5 "memory_operand" ""))
16086 (const_int 0)))
16087 (use (match_operand:SI 3 "immediate_operand" ""))
16088 (use (reg:CC 17))
16089 (use (reg:SI 19))
16090 (clobber (match_operand 0 "register_operand" ""))
16091 (clobber (match_operand 1 "register_operand" ""))
16092 (clobber (match_dup 2))])]
16093 ""
16094 "")
16095
16096 (define_insn "*cmpstrqi_1"
16097 [(set (reg:CC 17)
16098 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16099 (const_int 0))
16100 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16101 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16102 (const_int 0)))
16103 (use (match_operand:SI 3 "immediate_operand" "i"))
16104 (use (reg:CC 17))
16105 (use (reg:SI 19))
16106 (clobber (match_operand:SI 0 "register_operand" "=S"))
16107 (clobber (match_operand:SI 1 "register_operand" "=D"))
16108 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16109 "!TARGET_64BIT"
16110 "repz{\;| }cmpsb"
16111 [(set_attr "type" "str")
16112 (set_attr "mode" "QI")
16113 (set_attr "prefix_rep" "1")])
16114
16115 (define_insn "*cmpstrqi_rex_1"
16116 [(set (reg:CC 17)
16117 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16118 (const_int 0))
16119 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16120 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16121 (const_int 0)))
16122 (use (match_operand:SI 3 "immediate_operand" "i"))
16123 (use (reg:CC 17))
16124 (use (reg:SI 19))
16125 (clobber (match_operand:DI 0 "register_operand" "=S"))
16126 (clobber (match_operand:DI 1 "register_operand" "=D"))
16127 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16128 "TARGET_64BIT"
16129 "repz{\;| }cmpsb"
16130 [(set_attr "type" "str")
16131 (set_attr "mode" "QI")
16132 (set_attr "prefix_rep" "1")])
16133
16134 (define_expand "strlensi"
16135 [(set (match_operand:SI 0 "register_operand" "")
16136 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16137 (match_operand:QI 2 "immediate_operand" "")
16138 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16139 ""
16140 {
16141 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16142 DONE;
16143 else
16144 FAIL;
16145 })
16146
16147 (define_expand "strlendi"
16148 [(set (match_operand:DI 0 "register_operand" "")
16149 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16150 (match_operand:QI 2 "immediate_operand" "")
16151 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16152 ""
16153 {
16154 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16155 DONE;
16156 else
16157 FAIL;
16158 })
16159
16160 (define_expand "strlenqi_1"
16161 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16162 (use (reg:SI 19))
16163 (clobber (match_operand 1 "register_operand" ""))
16164 (clobber (reg:CC 17))])]
16165 ""
16166 "")
16167
16168 (define_insn "*strlenqi_1"
16169 [(set (match_operand:SI 0 "register_operand" "=&c")
16170 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16171 (match_operand:QI 2 "register_operand" "a")
16172 (match_operand:SI 3 "immediate_operand" "i")
16173 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16174 (use (reg:SI 19))
16175 (clobber (match_operand:SI 1 "register_operand" "=D"))
16176 (clobber (reg:CC 17))]
16177 "!TARGET_64BIT"
16178 "repnz{\;| }scasb"
16179 [(set_attr "type" "str")
16180 (set_attr "mode" "QI")
16181 (set_attr "prefix_rep" "1")])
16182
16183 (define_insn "*strlenqi_rex_1"
16184 [(set (match_operand:DI 0 "register_operand" "=&c")
16185 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16186 (match_operand:QI 2 "register_operand" "a")
16187 (match_operand:DI 3 "immediate_operand" "i")
16188 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16189 (use (reg:SI 19))
16190 (clobber (match_operand:DI 1 "register_operand" "=D"))
16191 (clobber (reg:CC 17))]
16192 "TARGET_64BIT"
16193 "repnz{\;| }scasb"
16194 [(set_attr "type" "str")
16195 (set_attr "mode" "QI")
16196 (set_attr "prefix_rep" "1")])
16197
16198 ;; Peephole optimizations to clean up after cmpstr*. This should be
16199 ;; handled in combine, but it is not currently up to the task.
16200 ;; When used for their truth value, the cmpstr* expanders generate
16201 ;; code like this:
16202 ;;
16203 ;; repz cmpsb
16204 ;; seta %al
16205 ;; setb %dl
16206 ;; cmpb %al, %dl
16207 ;; jcc label
16208 ;;
16209 ;; The intermediate three instructions are unnecessary.
16210
16211 ;; This one handles cmpstr*_nz_1...
16212 (define_peephole2
16213 [(parallel[
16214 (set (reg:CC 17)
16215 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16216 (mem:BLK (match_operand 5 "register_operand" ""))))
16217 (use (match_operand 6 "register_operand" ""))
16218 (use (match_operand:SI 3 "immediate_operand" ""))
16219 (use (reg:SI 19))
16220 (clobber (match_operand 0 "register_operand" ""))
16221 (clobber (match_operand 1 "register_operand" ""))
16222 (clobber (match_operand 2 "register_operand" ""))])
16223 (set (match_operand:QI 7 "register_operand" "")
16224 (gtu:QI (reg:CC 17) (const_int 0)))
16225 (set (match_operand:QI 8 "register_operand" "")
16226 (ltu:QI (reg:CC 17) (const_int 0)))
16227 (set (reg 17)
16228 (compare (match_dup 7) (match_dup 8)))
16229 ]
16230 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16231 [(parallel[
16232 (set (reg:CC 17)
16233 (compare:CC (mem:BLK (match_dup 4))
16234 (mem:BLK (match_dup 5))))
16235 (use (match_dup 6))
16236 (use (match_dup 3))
16237 (use (reg:SI 19))
16238 (clobber (match_dup 0))
16239 (clobber (match_dup 1))
16240 (clobber (match_dup 2))])]
16241 "")
16242
16243 ;; ...and this one handles cmpstr*_1.
16244 (define_peephole2
16245 [(parallel[
16246 (set (reg:CC 17)
16247 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16248 (const_int 0))
16249 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16250 (mem:BLK (match_operand 5 "register_operand" "")))
16251 (const_int 0)))
16252 (use (match_operand:SI 3 "immediate_operand" ""))
16253 (use (reg:CC 17))
16254 (use (reg:SI 19))
16255 (clobber (match_operand 0 "register_operand" ""))
16256 (clobber (match_operand 1 "register_operand" ""))
16257 (clobber (match_operand 2 "register_operand" ""))])
16258 (set (match_operand:QI 7 "register_operand" "")
16259 (gtu:QI (reg:CC 17) (const_int 0)))
16260 (set (match_operand:QI 8 "register_operand" "")
16261 (ltu:QI (reg:CC 17) (const_int 0)))
16262 (set (reg 17)
16263 (compare (match_dup 7) (match_dup 8)))
16264 ]
16265 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16266 [(parallel[
16267 (set (reg:CC 17)
16268 (if_then_else:CC (ne (match_dup 6)
16269 (const_int 0))
16270 (compare:CC (mem:BLK (match_dup 4))
16271 (mem:BLK (match_dup 5)))
16272 (const_int 0)))
16273 (use (match_dup 3))
16274 (use (reg:CC 17))
16275 (use (reg:SI 19))
16276 (clobber (match_dup 0))
16277 (clobber (match_dup 1))
16278 (clobber (match_dup 2))])]
16279 "")
16280
16281
16282 \f
16283 ;; Conditional move instructions.
16284
16285 (define_expand "movdicc"
16286 [(set (match_operand:DI 0 "register_operand" "")
16287 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16288 (match_operand:DI 2 "general_operand" "")
16289 (match_operand:DI 3 "general_operand" "")))]
16290 "TARGET_64BIT"
16291 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16292
16293 (define_insn "x86_movdicc_0_m1_rex64"
16294 [(set (match_operand:DI 0 "register_operand" "=r")
16295 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16296 (const_int -1)
16297 (const_int 0)))
16298 (clobber (reg:CC 17))]
16299 "TARGET_64BIT"
16300 "sbb{q}\t%0, %0"
16301 ; Since we don't have the proper number of operands for an alu insn,
16302 ; fill in all the blanks.
16303 [(set_attr "type" "alu")
16304 (set_attr "pent_pair" "pu")
16305 (set_attr "memory" "none")
16306 (set_attr "imm_disp" "false")
16307 (set_attr "mode" "DI")
16308 (set_attr "length_immediate" "0")])
16309
16310 (define_insn "movdicc_c_rex64"
16311 [(set (match_operand:DI 0 "register_operand" "=r,r")
16312 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16313 [(reg 17) (const_int 0)])
16314 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16315 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16316 "TARGET_64BIT && TARGET_CMOVE
16317 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16318 "@
16319 cmov%O2%C1\t{%2, %0|%0, %2}
16320 cmov%O2%c1\t{%3, %0|%0, %3}"
16321 [(set_attr "type" "icmov")
16322 (set_attr "mode" "DI")])
16323
16324 (define_expand "movsicc"
16325 [(set (match_operand:SI 0 "register_operand" "")
16326 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16327 (match_operand:SI 2 "general_operand" "")
16328 (match_operand:SI 3 "general_operand" "")))]
16329 ""
16330 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16331
16332 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16333 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16334 ;; So just document what we're doing explicitly.
16335
16336 (define_insn "x86_movsicc_0_m1"
16337 [(set (match_operand:SI 0 "register_operand" "=r")
16338 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16339 (const_int -1)
16340 (const_int 0)))
16341 (clobber (reg:CC 17))]
16342 ""
16343 "sbb{l}\t%0, %0"
16344 ; Since we don't have the proper number of operands for an alu insn,
16345 ; fill in all the blanks.
16346 [(set_attr "type" "alu")
16347 (set_attr "pent_pair" "pu")
16348 (set_attr "memory" "none")
16349 (set_attr "imm_disp" "false")
16350 (set_attr "mode" "SI")
16351 (set_attr "length_immediate" "0")])
16352
16353 (define_insn "*movsicc_noc"
16354 [(set (match_operand:SI 0 "register_operand" "=r,r")
16355 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16356 [(reg 17) (const_int 0)])
16357 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16358 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16359 "TARGET_CMOVE
16360 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16361 "@
16362 cmov%O2%C1\t{%2, %0|%0, %2}
16363 cmov%O2%c1\t{%3, %0|%0, %3}"
16364 [(set_attr "type" "icmov")
16365 (set_attr "mode" "SI")])
16366
16367 (define_expand "movhicc"
16368 [(set (match_operand:HI 0 "register_operand" "")
16369 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16370 (match_operand:HI 2 "general_operand" "")
16371 (match_operand:HI 3 "general_operand" "")))]
16372 "TARGET_HIMODE_MATH"
16373 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16374
16375 (define_insn "*movhicc_noc"
16376 [(set (match_operand:HI 0 "register_operand" "=r,r")
16377 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16378 [(reg 17) (const_int 0)])
16379 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16380 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16381 "TARGET_CMOVE
16382 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16383 "@
16384 cmov%O2%C1\t{%2, %0|%0, %2}
16385 cmov%O2%c1\t{%3, %0|%0, %3}"
16386 [(set_attr "type" "icmov")
16387 (set_attr "mode" "HI")])
16388
16389 (define_expand "movqicc"
16390 [(set (match_operand:QI 0 "register_operand" "")
16391 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16392 (match_operand:QI 2 "general_operand" "")
16393 (match_operand:QI 3 "general_operand" "")))]
16394 "TARGET_QIMODE_MATH"
16395 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16396
16397 (define_insn_and_split "*movqicc_noc"
16398 [(set (match_operand:QI 0 "register_operand" "=r,r")
16399 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16400 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16401 (match_operand:QI 2 "register_operand" "r,0")
16402 (match_operand:QI 3 "register_operand" "0,r")))]
16403 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16404 "#"
16405 "&& reload_completed"
16406 [(set (match_dup 0)
16407 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16408 (match_dup 2)
16409 (match_dup 3)))]
16410 "operands[0] = gen_lowpart (SImode, operands[0]);
16411 operands[2] = gen_lowpart (SImode, operands[2]);
16412 operands[3] = gen_lowpart (SImode, operands[3]);"
16413 [(set_attr "type" "icmov")
16414 (set_attr "mode" "SI")])
16415
16416 (define_expand "movsfcc"
16417 [(set (match_operand:SF 0 "register_operand" "")
16418 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16419 (match_operand:SF 2 "register_operand" "")
16420 (match_operand:SF 3 "register_operand" "")))]
16421 "TARGET_CMOVE"
16422 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16423
16424 (define_insn "*movsfcc_1"
16425 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16426 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16427 [(reg 17) (const_int 0)])
16428 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16429 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16430 "TARGET_CMOVE
16431 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16432 "@
16433 fcmov%F1\t{%2, %0|%0, %2}
16434 fcmov%f1\t{%3, %0|%0, %3}
16435 cmov%O2%C1\t{%2, %0|%0, %2}
16436 cmov%O2%c1\t{%3, %0|%0, %3}"
16437 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16438 (set_attr "mode" "SF,SF,SI,SI")])
16439
16440 (define_expand "movdfcc"
16441 [(set (match_operand:DF 0 "register_operand" "")
16442 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16443 (match_operand:DF 2 "register_operand" "")
16444 (match_operand:DF 3 "register_operand" "")))]
16445 "TARGET_CMOVE"
16446 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16447
16448 (define_insn "*movdfcc_1"
16449 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16450 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16451 [(reg 17) (const_int 0)])
16452 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16453 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16454 "!TARGET_64BIT && TARGET_CMOVE
16455 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16456 "@
16457 fcmov%F1\t{%2, %0|%0, %2}
16458 fcmov%f1\t{%3, %0|%0, %3}
16459 #
16460 #"
16461 [(set_attr "type" "fcmov,fcmov,multi,multi")
16462 (set_attr "mode" "DF")])
16463
16464 (define_insn "*movdfcc_1_rex64"
16465 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16466 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16467 [(reg 17) (const_int 0)])
16468 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16469 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16470 "TARGET_64BIT && TARGET_CMOVE
16471 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16472 "@
16473 fcmov%F1\t{%2, %0|%0, %2}
16474 fcmov%f1\t{%3, %0|%0, %3}
16475 cmov%O2%C1\t{%2, %0|%0, %2}
16476 cmov%O2%c1\t{%3, %0|%0, %3}"
16477 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478 (set_attr "mode" "DF")])
16479
16480 (define_split
16481 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16482 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16483 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16484 (match_operand:DF 2 "nonimmediate_operand" "")
16485 (match_operand:DF 3 "nonimmediate_operand" "")))]
16486 "!TARGET_64BIT && reload_completed"
16487 [(set (match_dup 2)
16488 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16489 (match_dup 5)
16490 (match_dup 7)))
16491 (set (match_dup 3)
16492 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16493 (match_dup 6)
16494 (match_dup 8)))]
16495 "split_di (operands+2, 1, operands+5, operands+6);
16496 split_di (operands+3, 1, operands+7, operands+8);
16497 split_di (operands, 1, operands+2, operands+3);")
16498
16499 (define_expand "movxfcc"
16500 [(set (match_operand:XF 0 "register_operand" "")
16501 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16502 (match_operand:XF 2 "register_operand" "")
16503 (match_operand:XF 3 "register_operand" "")))]
16504 "TARGET_CMOVE"
16505 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16506
16507 (define_insn "*movxfcc_1"
16508 [(set (match_operand:XF 0 "register_operand" "=f,f")
16509 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16510 [(reg 17) (const_int 0)])
16511 (match_operand:XF 2 "register_operand" "f,0")
16512 (match_operand:XF 3 "register_operand" "0,f")))]
16513 "TARGET_CMOVE"
16514 "@
16515 fcmov%F1\t{%2, %0|%0, %2}
16516 fcmov%f1\t{%3, %0|%0, %3}"
16517 [(set_attr "type" "fcmov")
16518 (set_attr "mode" "XF")])
16519
16520 (define_expand "minsf3"
16521 [(parallel [
16522 (set (match_operand:SF 0 "register_operand" "")
16523 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16524 (match_operand:SF 2 "nonimmediate_operand" ""))
16525 (match_dup 1)
16526 (match_dup 2)))
16527 (clobber (reg:CC 17))])]
16528 "TARGET_SSE"
16529 "")
16530
16531 (define_insn "*minsf"
16532 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16533 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16534 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16535 (match_dup 1)
16536 (match_dup 2)))
16537 (clobber (reg:CC 17))]
16538 "TARGET_SSE && TARGET_IEEE_FP"
16539 "#")
16540
16541 (define_insn "*minsf_nonieee"
16542 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16543 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16544 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16545 (match_dup 1)
16546 (match_dup 2)))
16547 (clobber (reg:CC 17))]
16548 "TARGET_SSE && !TARGET_IEEE_FP
16549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16550 "#")
16551
16552 (define_split
16553 [(set (match_operand:SF 0 "register_operand" "")
16554 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16555 (match_operand:SF 2 "nonimmediate_operand" ""))
16556 (match_operand:SF 3 "register_operand" "")
16557 (match_operand:SF 4 "nonimmediate_operand" "")))
16558 (clobber (reg:CC 17))]
16559 "SSE_REG_P (operands[0]) && reload_completed
16560 && ((operands_match_p (operands[1], operands[3])
16561 && operands_match_p (operands[2], operands[4]))
16562 || (operands_match_p (operands[1], operands[4])
16563 && operands_match_p (operands[2], operands[3])))"
16564 [(set (match_dup 0)
16565 (if_then_else:SF (lt (match_dup 1)
16566 (match_dup 2))
16567 (match_dup 1)
16568 (match_dup 2)))])
16569
16570 ;; Conditional addition patterns
16571 (define_expand "addqicc"
16572 [(match_operand:QI 0 "register_operand" "")
16573 (match_operand 1 "comparison_operator" "")
16574 (match_operand:QI 2 "register_operand" "")
16575 (match_operand:QI 3 "const_int_operand" "")]
16576 ""
16577 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16578
16579 (define_expand "addhicc"
16580 [(match_operand:HI 0 "register_operand" "")
16581 (match_operand 1 "comparison_operator" "")
16582 (match_operand:HI 2 "register_operand" "")
16583 (match_operand:HI 3 "const_int_operand" "")]
16584 ""
16585 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16586
16587 (define_expand "addsicc"
16588 [(match_operand:SI 0 "register_operand" "")
16589 (match_operand 1 "comparison_operator" "")
16590 (match_operand:SI 2 "register_operand" "")
16591 (match_operand:SI 3 "const_int_operand" "")]
16592 ""
16593 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16594
16595 (define_expand "adddicc"
16596 [(match_operand:DI 0 "register_operand" "")
16597 (match_operand 1 "comparison_operator" "")
16598 (match_operand:DI 2 "register_operand" "")
16599 (match_operand:DI 3 "const_int_operand" "")]
16600 "TARGET_64BIT"
16601 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16602
16603 ;; We can't represent the LT test directly. Do this by swapping the operands.
16604
16605 (define_split
16606 [(set (match_operand:SF 0 "fp_register_operand" "")
16607 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16608 (match_operand:SF 2 "register_operand" ""))
16609 (match_operand:SF 3 "register_operand" "")
16610 (match_operand:SF 4 "register_operand" "")))
16611 (clobber (reg:CC 17))]
16612 "reload_completed
16613 && ((operands_match_p (operands[1], operands[3])
16614 && operands_match_p (operands[2], operands[4]))
16615 || (operands_match_p (operands[1], operands[4])
16616 && operands_match_p (operands[2], operands[3])))"
16617 [(set (reg:CCFP 17)
16618 (compare:CCFP (match_dup 2)
16619 (match_dup 1)))
16620 (set (match_dup 0)
16621 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16622 (match_dup 1)
16623 (match_dup 2)))])
16624
16625 (define_insn "*minsf_sse"
16626 [(set (match_operand:SF 0 "register_operand" "=x")
16627 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16628 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16629 (match_dup 1)
16630 (match_dup 2)))]
16631 "TARGET_SSE && reload_completed"
16632 "minss\t{%2, %0|%0, %2}"
16633 [(set_attr "type" "sse")
16634 (set_attr "mode" "SF")])
16635
16636 (define_expand "mindf3"
16637 [(parallel [
16638 (set (match_operand:DF 0 "register_operand" "")
16639 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16640 (match_operand:DF 2 "nonimmediate_operand" ""))
16641 (match_dup 1)
16642 (match_dup 2)))
16643 (clobber (reg:CC 17))])]
16644 "TARGET_SSE2 && TARGET_SSE_MATH"
16645 "#")
16646
16647 (define_insn "*mindf"
16648 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16649 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16650 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16651 (match_dup 1)
16652 (match_dup 2)))
16653 (clobber (reg:CC 17))]
16654 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16655 "#")
16656
16657 (define_insn "*mindf_nonieee"
16658 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16659 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16660 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16661 (match_dup 1)
16662 (match_dup 2)))
16663 (clobber (reg:CC 17))]
16664 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16666 "#")
16667
16668 (define_split
16669 [(set (match_operand:DF 0 "register_operand" "")
16670 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16671 (match_operand:DF 2 "nonimmediate_operand" ""))
16672 (match_operand:DF 3 "register_operand" "")
16673 (match_operand:DF 4 "nonimmediate_operand" "")))
16674 (clobber (reg:CC 17))]
16675 "SSE_REG_P (operands[0]) && reload_completed
16676 && ((operands_match_p (operands[1], operands[3])
16677 && operands_match_p (operands[2], operands[4]))
16678 || (operands_match_p (operands[1], operands[4])
16679 && operands_match_p (operands[2], operands[3])))"
16680 [(set (match_dup 0)
16681 (if_then_else:DF (lt (match_dup 1)
16682 (match_dup 2))
16683 (match_dup 1)
16684 (match_dup 2)))])
16685
16686 ;; We can't represent the LT test directly. Do this by swapping the operands.
16687 (define_split
16688 [(set (match_operand:DF 0 "fp_register_operand" "")
16689 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16690 (match_operand:DF 2 "register_operand" ""))
16691 (match_operand:DF 3 "register_operand" "")
16692 (match_operand:DF 4 "register_operand" "")))
16693 (clobber (reg:CC 17))]
16694 "reload_completed
16695 && ((operands_match_p (operands[1], operands[3])
16696 && operands_match_p (operands[2], operands[4]))
16697 || (operands_match_p (operands[1], operands[4])
16698 && operands_match_p (operands[2], operands[3])))"
16699 [(set (reg:CCFP 17)
16700 (compare:CCFP (match_dup 2)
16701 (match_dup 1)))
16702 (set (match_dup 0)
16703 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
16704 (match_dup 1)
16705 (match_dup 2)))])
16706
16707 (define_insn "*mindf_sse"
16708 [(set (match_operand:DF 0 "register_operand" "=Y")
16709 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16710 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16711 (match_dup 1)
16712 (match_dup 2)))]
16713 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16714 "minsd\t{%2, %0|%0, %2}"
16715 [(set_attr "type" "sse")
16716 (set_attr "mode" "DF")])
16717
16718 (define_expand "maxsf3"
16719 [(parallel [
16720 (set (match_operand:SF 0 "register_operand" "")
16721 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16722 (match_operand:SF 2 "nonimmediate_operand" ""))
16723 (match_dup 1)
16724 (match_dup 2)))
16725 (clobber (reg:CC 17))])]
16726 "TARGET_SSE"
16727 "#")
16728
16729 (define_insn "*maxsf"
16730 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16731 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16732 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16733 (match_dup 1)
16734 (match_dup 2)))
16735 (clobber (reg:CC 17))]
16736 "TARGET_SSE && TARGET_IEEE_FP"
16737 "#")
16738
16739 (define_insn "*maxsf_nonieee"
16740 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16741 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16742 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16743 (match_dup 1)
16744 (match_dup 2)))
16745 (clobber (reg:CC 17))]
16746 "TARGET_SSE && !TARGET_IEEE_FP
16747 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16748 "#")
16749
16750 (define_split
16751 [(set (match_operand:SF 0 "register_operand" "")
16752 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16753 (match_operand:SF 2 "nonimmediate_operand" ""))
16754 (match_operand:SF 3 "register_operand" "")
16755 (match_operand:SF 4 "nonimmediate_operand" "")))
16756 (clobber (reg:CC 17))]
16757 "SSE_REG_P (operands[0]) && reload_completed
16758 && ((operands_match_p (operands[1], operands[3])
16759 && operands_match_p (operands[2], operands[4]))
16760 || (operands_match_p (operands[1], operands[4])
16761 && operands_match_p (operands[2], operands[3])))"
16762 [(set (match_dup 0)
16763 (if_then_else:SF (gt (match_dup 1)
16764 (match_dup 2))
16765 (match_dup 1)
16766 (match_dup 2)))])
16767
16768 (define_split
16769 [(set (match_operand:SF 0 "fp_register_operand" "")
16770 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16771 (match_operand:SF 2 "register_operand" ""))
16772 (match_operand:SF 3 "register_operand" "")
16773 (match_operand:SF 4 "register_operand" "")))
16774 (clobber (reg:CC 17))]
16775 "reload_completed
16776 && ((operands_match_p (operands[1], operands[3])
16777 && operands_match_p (operands[2], operands[4]))
16778 || (operands_match_p (operands[1], operands[4])
16779 && operands_match_p (operands[2], operands[3])))"
16780 [(set (reg:CCFP 17)
16781 (compare:CCFP (match_dup 1)
16782 (match_dup 2)))
16783 (set (match_dup 0)
16784 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16785 (match_dup 1)
16786 (match_dup 2)))])
16787
16788 (define_insn "*maxsf_sse"
16789 [(set (match_operand:SF 0 "register_operand" "=x")
16790 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16791 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16792 (match_dup 1)
16793 (match_dup 2)))]
16794 "TARGET_SSE && reload_completed"
16795 "maxss\t{%2, %0|%0, %2}"
16796 [(set_attr "type" "sse")
16797 (set_attr "mode" "SF")])
16798
16799 (define_expand "maxdf3"
16800 [(parallel [
16801 (set (match_operand:DF 0 "register_operand" "")
16802 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16803 (match_operand:DF 2 "nonimmediate_operand" ""))
16804 (match_dup 1)
16805 (match_dup 2)))
16806 (clobber (reg:CC 17))])]
16807 "TARGET_SSE2 && TARGET_SSE_MATH"
16808 "#")
16809
16810 (define_insn "*maxdf"
16811 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16812 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16813 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16814 (match_dup 1)
16815 (match_dup 2)))
16816 (clobber (reg:CC 17))]
16817 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16818 "#")
16819
16820 (define_insn "*maxdf_nonieee"
16821 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16822 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16823 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16824 (match_dup 1)
16825 (match_dup 2)))
16826 (clobber (reg:CC 17))]
16827 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16828 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16829 "#")
16830
16831 (define_split
16832 [(set (match_operand:DF 0 "register_operand" "")
16833 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16834 (match_operand:DF 2 "nonimmediate_operand" ""))
16835 (match_operand:DF 3 "register_operand" "")
16836 (match_operand:DF 4 "nonimmediate_operand" "")))
16837 (clobber (reg:CC 17))]
16838 "SSE_REG_P (operands[0]) && reload_completed
16839 && ((operands_match_p (operands[1], operands[3])
16840 && operands_match_p (operands[2], operands[4]))
16841 || (operands_match_p (operands[1], operands[4])
16842 && operands_match_p (operands[2], operands[3])))"
16843 [(set (match_dup 0)
16844 (if_then_else:DF (gt (match_dup 1)
16845 (match_dup 2))
16846 (match_dup 1)
16847 (match_dup 2)))])
16848
16849 (define_split
16850 [(set (match_operand:DF 0 "fp_register_operand" "")
16851 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16852 (match_operand:DF 2 "register_operand" ""))
16853 (match_operand:DF 3 "register_operand" "")
16854 (match_operand:DF 4 "register_operand" "")))
16855 (clobber (reg:CC 17))]
16856 "reload_completed
16857 && ((operands_match_p (operands[1], operands[3])
16858 && operands_match_p (operands[2], operands[4]))
16859 || (operands_match_p (operands[1], operands[4])
16860 && operands_match_p (operands[2], operands[3])))"
16861 [(set (reg:CCFP 17)
16862 (compare:CCFP (match_dup 1)
16863 (match_dup 2)))
16864 (set (match_dup 0)
16865 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16866 (match_dup 1)
16867 (match_dup 2)))])
16868
16869 (define_insn "*maxdf_sse"
16870 [(set (match_operand:DF 0 "register_operand" "=Y")
16871 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16872 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16873 (match_dup 1)
16874 (match_dup 2)))]
16875 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16876 "maxsd\t{%2, %0|%0, %2}"
16877 [(set_attr "type" "sse")
16878 (set_attr "mode" "DF")])
16879 \f
16880 ;; Misc patterns (?)
16881
16882 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16883 ;; Otherwise there will be nothing to keep
16884 ;;
16885 ;; [(set (reg ebp) (reg esp))]
16886 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16887 ;; (clobber (eflags)]
16888 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16889 ;;
16890 ;; in proper program order.
16891 (define_insn "pro_epilogue_adjust_stack_1"
16892 [(set (match_operand:SI 0 "register_operand" "=r,r")
16893 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16894 (match_operand:SI 2 "immediate_operand" "i,i")))
16895 (clobber (reg:CC 17))
16896 (clobber (mem:BLK (scratch)))]
16897 "!TARGET_64BIT"
16898 {
16899 switch (get_attr_type (insn))
16900 {
16901 case TYPE_IMOV:
16902 return "mov{l}\t{%1, %0|%0, %1}";
16903
16904 case TYPE_ALU:
16905 if (GET_CODE (operands[2]) == CONST_INT
16906 && (INTVAL (operands[2]) == 128
16907 || (INTVAL (operands[2]) < 0
16908 && INTVAL (operands[2]) != -128)))
16909 {
16910 operands[2] = GEN_INT (-INTVAL (operands[2]));
16911 return "sub{l}\t{%2, %0|%0, %2}";
16912 }
16913 return "add{l}\t{%2, %0|%0, %2}";
16914
16915 case TYPE_LEA:
16916 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16917 return "lea{l}\t{%a2, %0|%0, %a2}";
16918
16919 default:
16920 abort ();
16921 }
16922 }
16923 [(set (attr "type")
16924 (cond [(eq_attr "alternative" "0")
16925 (const_string "alu")
16926 (match_operand:SI 2 "const0_operand" "")
16927 (const_string "imov")
16928 ]
16929 (const_string "lea")))
16930 (set_attr "mode" "SI")])
16931
16932 (define_insn "pro_epilogue_adjust_stack_rex64"
16933 [(set (match_operand:DI 0 "register_operand" "=r,r")
16934 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16935 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16936 (clobber (reg:CC 17))
16937 (clobber (mem:BLK (scratch)))]
16938 "TARGET_64BIT"
16939 {
16940 switch (get_attr_type (insn))
16941 {
16942 case TYPE_IMOV:
16943 return "mov{q}\t{%1, %0|%0, %1}";
16944
16945 case TYPE_ALU:
16946 if (GET_CODE (operands[2]) == CONST_INT
16947 /* Avoid overflows. */
16948 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16949 && (INTVAL (operands[2]) == 128
16950 || (INTVAL (operands[2]) < 0
16951 && INTVAL (operands[2]) != -128)))
16952 {
16953 operands[2] = GEN_INT (-INTVAL (operands[2]));
16954 return "sub{q}\t{%2, %0|%0, %2}";
16955 }
16956 return "add{q}\t{%2, %0|%0, %2}";
16957
16958 case TYPE_LEA:
16959 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16960 return "lea{q}\t{%a2, %0|%0, %a2}";
16961
16962 default:
16963 abort ();
16964 }
16965 }
16966 [(set (attr "type")
16967 (cond [(eq_attr "alternative" "0")
16968 (const_string "alu")
16969 (match_operand:DI 2 "const0_operand" "")
16970 (const_string "imov")
16971 ]
16972 (const_string "lea")))
16973 (set_attr "mode" "DI")])
16974
16975 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16976 [(set (match_operand:DI 0 "register_operand" "=r,r")
16977 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16978 (match_operand:DI 3 "immediate_operand" "i,i")))
16979 (use (match_operand:DI 2 "register_operand" "r,r"))
16980 (clobber (reg:CC 17))
16981 (clobber (mem:BLK (scratch)))]
16982 "TARGET_64BIT"
16983 {
16984 switch (get_attr_type (insn))
16985 {
16986 case TYPE_ALU:
16987 return "add{q}\t{%2, %0|%0, %2}";
16988
16989 case TYPE_LEA:
16990 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16991 return "lea{q}\t{%a2, %0|%0, %a2}";
16992
16993 default:
16994 abort ();
16995 }
16996 }
16997 [(set_attr "type" "alu,lea")
16998 (set_attr "mode" "DI")])
16999
17000 ;; Placeholder for the conditional moves. This one is split either to SSE
17001 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17002 ;; fact is that compares supported by the cmp??ss instructions are exactly
17003 ;; swapped of those supported by cmove sequence.
17004 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17005 ;; supported by i387 comparisons and we do need to emit two conditional moves
17006 ;; in tandem.
17007
17008 (define_insn "sse_movsfcc"
17009 [(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")
17010 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17011 [(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")
17012 (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")])
17013 (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")
17014 (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")))
17015 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17016 (clobber (reg:CC 17))]
17017 "TARGET_SSE
17018 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17019 /* Avoid combine from being smart and converting min/max
17020 instruction patterns into conditional moves. */
17021 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17022 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17023 || !rtx_equal_p (operands[4], operands[2])
17024 || !rtx_equal_p (operands[5], operands[3]))
17025 && (!TARGET_IEEE_FP
17026 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17027 "#")
17028
17029 (define_insn "sse_movsfcc_eq"
17030 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17031 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17032 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17033 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17034 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17035 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17036 (clobber (reg:CC 17))]
17037 "TARGET_SSE
17038 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17039 "#")
17040
17041 (define_insn "sse_movdfcc"
17042 [(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")
17043 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17044 [(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")
17045 (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")])
17046 (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")
17047 (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")))
17048 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17049 (clobber (reg:CC 17))]
17050 "TARGET_SSE2
17051 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17052 /* Avoid combine from being smart and converting min/max
17053 instruction patterns into conditional moves. */
17054 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17055 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17056 || !rtx_equal_p (operands[4], operands[2])
17057 || !rtx_equal_p (operands[5], operands[3]))
17058 && (!TARGET_IEEE_FP
17059 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17060 "#")
17061
17062 (define_insn "sse_movdfcc_eq"
17063 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17064 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17065 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17066 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17067 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17068 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17069 (clobber (reg:CC 17))]
17070 "TARGET_SSE
17071 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17072 "#")
17073
17074 ;; For non-sse moves just expand the usual cmove sequence.
17075 (define_split
17076 [(set (match_operand 0 "register_operand" "")
17077 (if_then_else (match_operator 1 "comparison_operator"
17078 [(match_operand 4 "nonimmediate_operand" "")
17079 (match_operand 5 "register_operand" "")])
17080 (match_operand 2 "nonimmediate_operand" "")
17081 (match_operand 3 "nonimmediate_operand" "")))
17082 (clobber (match_operand 6 "" ""))
17083 (clobber (reg:CC 17))]
17084 "!SSE_REG_P (operands[0]) && reload_completed
17085 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17086 [(const_int 0)]
17087 {
17088 ix86_compare_op0 = operands[5];
17089 ix86_compare_op1 = operands[4];
17090 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17091 VOIDmode, operands[5], operands[4]);
17092 ix86_expand_fp_movcc (operands);
17093 DONE;
17094 })
17095
17096 ;; Split SSE based conditional move into sequence:
17097 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17098 ;; and op2, op0 - zero op2 if comparison was false
17099 ;; nand op0, op3 - load op3 to op0 if comparison was false
17100 ;; or op2, op0 - get the nonzero one into the result.
17101 (define_split
17102 [(set (match_operand:SF 0 "register_operand" "")
17103 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
17104 [(match_operand:SF 4 "register_operand" "")
17105 (match_operand:SF 5 "nonimmediate_operand" "")])
17106 (match_operand:SF 2 "register_operand" "")
17107 (match_operand:SF 3 "register_operand" "")))
17108 (clobber (match_operand 6 "" ""))
17109 (clobber (reg:CC 17))]
17110 "SSE_REG_P (operands[0]) && reload_completed"
17111 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17112 (set (match_dup 2) (and:V4SF (match_dup 2)
17113 (match_dup 8)))
17114 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
17115 (match_dup 3)))
17116 (set (match_dup 0) (ior:V4SF (match_dup 6)
17117 (match_dup 7)))]
17118 {
17119 /* If op2 == op3, op3 would be clobbered before it is used. */
17120 if (operands_match_p (operands[2], operands[3]))
17121 {
17122 emit_move_insn (operands[0], operands[2]);
17123 DONE;
17124 }
17125
17126 PUT_MODE (operands[1], GET_MODE (operands[0]));
17127 if (operands_match_p (operands[0], operands[4]))
17128 operands[6] = operands[4], operands[7] = operands[2];
17129 else
17130 operands[6] = operands[2], operands[7] = operands[4];
17131 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17132 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
17133 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
17134 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
17135 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
17136 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17137 })
17138
17139 (define_split
17140 [(set (match_operand:DF 0 "register_operand" "")
17141 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
17142 [(match_operand:DF 4 "register_operand" "")
17143 (match_operand:DF 5 "nonimmediate_operand" "")])
17144 (match_operand:DF 2 "register_operand" "")
17145 (match_operand:DF 3 "register_operand" "")))
17146 (clobber (match_operand 6 "" ""))
17147 (clobber (reg:CC 17))]
17148 "SSE_REG_P (operands[0]) && reload_completed"
17149 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17150 (set (match_dup 2) (and:V2DF (match_dup 2)
17151 (match_dup 8)))
17152 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
17153 (match_dup 3)))
17154 (set (match_dup 0) (ior:V2DF (match_dup 6)
17155 (match_dup 7)))]
17156 {
17157 if (GET_MODE (operands[2]) == DFmode
17158 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17159 {
17160 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17161 emit_insn (gen_sse2_unpcklpd (op, op, op));
17162 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17163 emit_insn (gen_sse2_unpcklpd (op, op, op));
17164 }
17165
17166 /* If op2 == op3, op3 would be clobbered before it is used. */
17167 if (operands_match_p (operands[2], operands[3]))
17168 {
17169 emit_move_insn (operands[0], operands[2]);
17170 DONE;
17171 }
17172
17173 PUT_MODE (operands[1], GET_MODE (operands[0]));
17174 if (operands_match_p (operands[0], operands[4]))
17175 operands[6] = operands[4], operands[7] = operands[2];
17176 else
17177 operands[6] = operands[2], operands[7] = operands[4];
17178 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17179 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17180 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17181 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
17182 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
17183 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17184 })
17185
17186 ;; Special case of conditional move we can handle effectively.
17187 ;; Do not brother with the integer/floating point case, since these are
17188 ;; bot considerably slower, unlike in the generic case.
17189 (define_insn "*sse_movsfcc_const0_1"
17190 [(set (match_operand:SF 0 "register_operand" "=&x")
17191 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17192 [(match_operand:SF 4 "register_operand" "0")
17193 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17194 (match_operand:SF 2 "register_operand" "x")
17195 (match_operand:SF 3 "const0_operand" "X")))]
17196 "TARGET_SSE"
17197 "#")
17198
17199 (define_insn "*sse_movsfcc_const0_2"
17200 [(set (match_operand:SF 0 "register_operand" "=&x")
17201 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17202 [(match_operand:SF 4 "register_operand" "0")
17203 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17204 (match_operand:SF 2 "const0_operand" "X")
17205 (match_operand:SF 3 "register_operand" "x")))]
17206 "TARGET_SSE"
17207 "#")
17208
17209 (define_insn "*sse_movsfcc_const0_3"
17210 [(set (match_operand:SF 0 "register_operand" "=&x")
17211 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17212 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17213 (match_operand:SF 5 "register_operand" "0")])
17214 (match_operand:SF 2 "register_operand" "x")
17215 (match_operand:SF 3 "const0_operand" "X")))]
17216 "TARGET_SSE"
17217 "#")
17218
17219 (define_insn "*sse_movsfcc_const0_4"
17220 [(set (match_operand:SF 0 "register_operand" "=&x")
17221 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17222 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17223 (match_operand:SF 5 "register_operand" "0")])
17224 (match_operand:SF 2 "const0_operand" "X")
17225 (match_operand:SF 3 "register_operand" "x")))]
17226 "TARGET_SSE"
17227 "#")
17228
17229 (define_insn "*sse_movdfcc_const0_1"
17230 [(set (match_operand:DF 0 "register_operand" "=&Y")
17231 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17232 [(match_operand:DF 4 "register_operand" "0")
17233 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17234 (match_operand:DF 2 "register_operand" "Y")
17235 (match_operand:DF 3 "const0_operand" "X")))]
17236 "TARGET_SSE2"
17237 "#")
17238
17239 (define_insn "*sse_movdfcc_const0_2"
17240 [(set (match_operand:DF 0 "register_operand" "=&Y")
17241 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17242 [(match_operand:DF 4 "register_operand" "0")
17243 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17244 (match_operand:DF 2 "const0_operand" "X")
17245 (match_operand:DF 3 "register_operand" "Y")))]
17246 "TARGET_SSE2"
17247 "#")
17248
17249 (define_insn "*sse_movdfcc_const0_3"
17250 [(set (match_operand:DF 0 "register_operand" "=&Y")
17251 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17252 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17253 (match_operand:DF 5 "register_operand" "0")])
17254 (match_operand:DF 2 "register_operand" "Y")
17255 (match_operand:DF 3 "const0_operand" "X")))]
17256 "TARGET_SSE2"
17257 "#")
17258
17259 (define_insn "*sse_movdfcc_const0_4"
17260 [(set (match_operand:DF 0 "register_operand" "=&Y")
17261 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17262 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17263 (match_operand:DF 5 "register_operand" "0")])
17264 (match_operand:DF 2 "const0_operand" "X")
17265 (match_operand:DF 3 "register_operand" "Y")))]
17266 "TARGET_SSE2"
17267 "#")
17268
17269 (define_split
17270 [(set (match_operand:SF 0 "register_operand" "")
17271 (if_then_else (match_operator:SF 1 "comparison_operator"
17272 [(match_operand:SF 4 "nonimmediate_operand" "")
17273 (match_operand:SF 5 "nonimmediate_operand" "")])
17274 (match_operand:SF 2 "nonmemory_operand" "")
17275 (match_operand:SF 3 "nonmemory_operand" "")))]
17276 "SSE_REG_P (operands[0]) && reload_completed
17277 && (const0_operand (operands[2], GET_MODE (operands[0]))
17278 || const0_operand (operands[3], GET_MODE (operands[0])))"
17279 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17280 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
17281 {
17282 PUT_MODE (operands[1], GET_MODE (operands[0]));
17283 if (!sse_comparison_operator (operands[1], VOIDmode)
17284 || !rtx_equal_p (operands[0], operands[4]))
17285 {
17286 rtx tmp = operands[5];
17287 operands[5] = operands[4];
17288 operands[4] = tmp;
17289 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17290 }
17291 if (!rtx_equal_p (operands[0], operands[4]))
17292 abort ();
17293 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
17294 if (const0_operand (operands[2], GET_MODE (operands[2])))
17295 {
17296 operands[7] = operands[3];
17297 operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
17298 }
17299 else
17300 {
17301 operands[7] = operands[2];
17302 operands[6] = operands[0];
17303 }
17304 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
17305 })
17306
17307 (define_split
17308 [(set (match_operand:DF 0 "register_operand" "")
17309 (if_then_else (match_operator:DF 1 "comparison_operator"
17310 [(match_operand:DF 4 "nonimmediate_operand" "")
17311 (match_operand:DF 5 "nonimmediate_operand" "")])
17312 (match_operand:DF 2 "nonmemory_operand" "")
17313 (match_operand:DF 3 "nonmemory_operand" "")))]
17314 "SSE_REG_P (operands[0]) && reload_completed
17315 && (const0_operand (operands[2], GET_MODE (operands[0]))
17316 || const0_operand (operands[3], GET_MODE (operands[0])))"
17317 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17318 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
17319 {
17320 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17321 && GET_MODE (operands[2]) == DFmode)
17322 {
17323 if (REG_P (operands[2]))
17324 {
17325 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17326 emit_insn (gen_sse2_unpcklpd (op, op, op));
17327 }
17328 if (REG_P (operands[3]))
17329 {
17330 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17331 emit_insn (gen_sse2_unpcklpd (op, op, op));
17332 }
17333 }
17334 PUT_MODE (operands[1], GET_MODE (operands[0]));
17335 if (!sse_comparison_operator (operands[1], VOIDmode)
17336 || !rtx_equal_p (operands[0], operands[4]))
17337 {
17338 rtx tmp = operands[5];
17339 operands[5] = operands[4];
17340 operands[4] = tmp;
17341 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17342 }
17343 if (!rtx_equal_p (operands[0], operands[4]))
17344 abort ();
17345 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
17346 if (const0_operand (operands[2], GET_MODE (operands[2])))
17347 {
17348 operands[7] = operands[3];
17349 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
17350 }
17351 else
17352 {
17353 operands[7] = operands[2];
17354 operands[6] = operands[8];
17355 }
17356 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
17357 })
17358
17359 (define_expand "allocate_stack_worker"
17360 [(match_operand:SI 0 "register_operand" "")]
17361 "TARGET_STACK_PROBE"
17362 {
17363 if (reload_completed)
17364 {
17365 if (TARGET_64BIT)
17366 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17367 else
17368 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17369 }
17370 else
17371 {
17372 if (TARGET_64BIT)
17373 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17374 else
17375 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17376 }
17377 DONE;
17378 })
17379
17380 (define_insn "allocate_stack_worker_1"
17381 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17382 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17383 (clobber (match_scratch:SI 1 "=0"))
17384 (clobber (reg:CC 17))]
17385 "!TARGET_64BIT && TARGET_STACK_PROBE"
17386 "call\t__alloca"
17387 [(set_attr "type" "multi")
17388 (set_attr "length" "5")])
17389
17390 (define_expand "allocate_stack_worker_postreload"
17391 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17392 UNSPEC_STACK_PROBE)
17393 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17394 (clobber (match_dup 0))
17395 (clobber (reg:CC 17))])]
17396 ""
17397 "")
17398
17399 (define_insn "allocate_stack_worker_rex64"
17400 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17401 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17402 (clobber (match_scratch:DI 1 "=0"))
17403 (clobber (reg:CC 17))]
17404 "TARGET_64BIT && TARGET_STACK_PROBE"
17405 "call\t__alloca"
17406 [(set_attr "type" "multi")
17407 (set_attr "length" "5")])
17408
17409 (define_expand "allocate_stack_worker_rex64_postreload"
17410 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17411 UNSPEC_STACK_PROBE)
17412 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17413 (clobber (match_dup 0))
17414 (clobber (reg:CC 17))])]
17415 ""
17416 "")
17417
17418 (define_expand "allocate_stack"
17419 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17420 (minus:SI (reg:SI 7)
17421 (match_operand:SI 1 "general_operand" "")))
17422 (clobber (reg:CC 17))])
17423 (parallel [(set (reg:SI 7)
17424 (minus:SI (reg:SI 7) (match_dup 1)))
17425 (clobber (reg:CC 17))])]
17426 "TARGET_STACK_PROBE"
17427 {
17428 #ifdef CHECK_STACK_LIMIT
17429 if (GET_CODE (operands[1]) == CONST_INT
17430 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17431 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17432 operands[1]));
17433 else
17434 #endif
17435 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17436 operands[1])));
17437
17438 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17439 DONE;
17440 })
17441
17442 (define_expand "builtin_setjmp_receiver"
17443 [(label_ref (match_operand 0 "" ""))]
17444 "!TARGET_64BIT && flag_pic"
17445 {
17446 emit_insn (gen_set_got (pic_offset_table_rtx));
17447 DONE;
17448 })
17449 \f
17450 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17451
17452 (define_split
17453 [(set (match_operand 0 "register_operand" "")
17454 (match_operator 3 "promotable_binary_operator"
17455 [(match_operand 1 "register_operand" "")
17456 (match_operand 2 "aligned_operand" "")]))
17457 (clobber (reg:CC 17))]
17458 "! TARGET_PARTIAL_REG_STALL && reload_completed
17459 && ((GET_MODE (operands[0]) == HImode
17460 && ((!optimize_size && !TARGET_FAST_PREFIX)
17461 || GET_CODE (operands[2]) != CONST_INT
17462 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17463 || (GET_MODE (operands[0]) == QImode
17464 && (TARGET_PROMOTE_QImode || optimize_size)))"
17465 [(parallel [(set (match_dup 0)
17466 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17467 (clobber (reg:CC 17))])]
17468 "operands[0] = gen_lowpart (SImode, operands[0]);
17469 operands[1] = gen_lowpart (SImode, operands[1]);
17470 if (GET_CODE (operands[3]) != ASHIFT)
17471 operands[2] = gen_lowpart (SImode, operands[2]);
17472 PUT_MODE (operands[3], SImode);")
17473
17474 ; Promote the QImode tests, as i386 has encoding of the AND
17475 ; instruction with 32-bit sign-extended immediate and thus the
17476 ; instruction size is unchanged, except in the %eax case for
17477 ; which it is increased by one byte, hence the ! optimize_size.
17478 (define_split
17479 [(set (reg 17)
17480 (compare (and (match_operand 1 "aligned_operand" "")
17481 (match_operand 2 "const_int_operand" ""))
17482 (const_int 0)))
17483 (set (match_operand 0 "register_operand" "")
17484 (and (match_dup 1) (match_dup 2)))]
17485 "! TARGET_PARTIAL_REG_STALL && reload_completed
17486 /* Ensure that the operand will remain sign-extended immediate. */
17487 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17488 && ! optimize_size
17489 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17490 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17491 [(parallel [(set (reg:CCNO 17)
17492 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17493 (const_int 0)))
17494 (set (match_dup 0)
17495 (and:SI (match_dup 1) (match_dup 2)))])]
17496 "operands[2]
17497 = gen_int_mode (INTVAL (operands[2])
17498 & GET_MODE_MASK (GET_MODE (operands[0])),
17499 SImode);
17500 operands[0] = gen_lowpart (SImode, operands[0]);
17501 operands[1] = gen_lowpart (SImode, operands[1]);")
17502
17503 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17504 ; the TEST instruction with 32-bit sign-extended immediate and thus
17505 ; the instruction size would at least double, which is not what we
17506 ; want even with ! optimize_size.
17507 (define_split
17508 [(set (reg 17)
17509 (compare (and (match_operand:HI 0 "aligned_operand" "")
17510 (match_operand:HI 1 "const_int_operand" ""))
17511 (const_int 0)))]
17512 "! TARGET_PARTIAL_REG_STALL && reload_completed
17513 /* Ensure that the operand will remain sign-extended immediate. */
17514 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17515 && ! TARGET_FAST_PREFIX
17516 && ! optimize_size"
17517 [(set (reg:CCNO 17)
17518 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17519 (const_int 0)))]
17520 "operands[1]
17521 = gen_int_mode (INTVAL (operands[1])
17522 & GET_MODE_MASK (GET_MODE (operands[0])),
17523 SImode);
17524 operands[0] = gen_lowpart (SImode, operands[0]);")
17525
17526 (define_split
17527 [(set (match_operand 0 "register_operand" "")
17528 (neg (match_operand 1 "register_operand" "")))
17529 (clobber (reg:CC 17))]
17530 "! TARGET_PARTIAL_REG_STALL && reload_completed
17531 && (GET_MODE (operands[0]) == HImode
17532 || (GET_MODE (operands[0]) == QImode
17533 && (TARGET_PROMOTE_QImode || optimize_size)))"
17534 [(parallel [(set (match_dup 0)
17535 (neg:SI (match_dup 1)))
17536 (clobber (reg:CC 17))])]
17537 "operands[0] = gen_lowpart (SImode, operands[0]);
17538 operands[1] = gen_lowpart (SImode, operands[1]);")
17539
17540 (define_split
17541 [(set (match_operand 0 "register_operand" "")
17542 (not (match_operand 1 "register_operand" "")))]
17543 "! TARGET_PARTIAL_REG_STALL && reload_completed
17544 && (GET_MODE (operands[0]) == HImode
17545 || (GET_MODE (operands[0]) == QImode
17546 && (TARGET_PROMOTE_QImode || optimize_size)))"
17547 [(set (match_dup 0)
17548 (not:SI (match_dup 1)))]
17549 "operands[0] = gen_lowpart (SImode, operands[0]);
17550 operands[1] = gen_lowpart (SImode, operands[1]);")
17551
17552 (define_split
17553 [(set (match_operand 0 "register_operand" "")
17554 (if_then_else (match_operator 1 "comparison_operator"
17555 [(reg 17) (const_int 0)])
17556 (match_operand 2 "register_operand" "")
17557 (match_operand 3 "register_operand" "")))]
17558 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17559 && (GET_MODE (operands[0]) == HImode
17560 || (GET_MODE (operands[0]) == QImode
17561 && (TARGET_PROMOTE_QImode || optimize_size)))"
17562 [(set (match_dup 0)
17563 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17564 "operands[0] = gen_lowpart (SImode, operands[0]);
17565 operands[2] = gen_lowpart (SImode, operands[2]);
17566 operands[3] = gen_lowpart (SImode, operands[3]);")
17567
17568 \f
17569 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17570 ;; transform a complex memory operation into two memory to register operations.
17571
17572 ;; Don't push memory operands
17573 (define_peephole2
17574 [(set (match_operand:SI 0 "push_operand" "")
17575 (match_operand:SI 1 "memory_operand" ""))
17576 (match_scratch:SI 2 "r")]
17577 "! optimize_size && ! TARGET_PUSH_MEMORY"
17578 [(set (match_dup 2) (match_dup 1))
17579 (set (match_dup 0) (match_dup 2))]
17580 "")
17581
17582 (define_peephole2
17583 [(set (match_operand:DI 0 "push_operand" "")
17584 (match_operand:DI 1 "memory_operand" ""))
17585 (match_scratch:DI 2 "r")]
17586 "! optimize_size && ! TARGET_PUSH_MEMORY"
17587 [(set (match_dup 2) (match_dup 1))
17588 (set (match_dup 0) (match_dup 2))]
17589 "")
17590
17591 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17592 ;; SImode pushes.
17593 (define_peephole2
17594 [(set (match_operand:SF 0 "push_operand" "")
17595 (match_operand:SF 1 "memory_operand" ""))
17596 (match_scratch:SF 2 "r")]
17597 "! optimize_size && ! TARGET_PUSH_MEMORY"
17598 [(set (match_dup 2) (match_dup 1))
17599 (set (match_dup 0) (match_dup 2))]
17600 "")
17601
17602 (define_peephole2
17603 [(set (match_operand:HI 0 "push_operand" "")
17604 (match_operand:HI 1 "memory_operand" ""))
17605 (match_scratch:HI 2 "r")]
17606 "! optimize_size && ! TARGET_PUSH_MEMORY"
17607 [(set (match_dup 2) (match_dup 1))
17608 (set (match_dup 0) (match_dup 2))]
17609 "")
17610
17611 (define_peephole2
17612 [(set (match_operand:QI 0 "push_operand" "")
17613 (match_operand:QI 1 "memory_operand" ""))
17614 (match_scratch:QI 2 "q")]
17615 "! optimize_size && ! TARGET_PUSH_MEMORY"
17616 [(set (match_dup 2) (match_dup 1))
17617 (set (match_dup 0) (match_dup 2))]
17618 "")
17619
17620 ;; Don't move an immediate directly to memory when the instruction
17621 ;; gets too big.
17622 (define_peephole2
17623 [(match_scratch:SI 1 "r")
17624 (set (match_operand:SI 0 "memory_operand" "")
17625 (const_int 0))]
17626 "! optimize_size
17627 && ! TARGET_USE_MOV0
17628 && TARGET_SPLIT_LONG_MOVES
17629 && get_attr_length (insn) >= ix86_cost->large_insn
17630 && peep2_regno_dead_p (0, FLAGS_REG)"
17631 [(parallel [(set (match_dup 1) (const_int 0))
17632 (clobber (reg:CC 17))])
17633 (set (match_dup 0) (match_dup 1))]
17634 "")
17635
17636 (define_peephole2
17637 [(match_scratch:HI 1 "r")
17638 (set (match_operand:HI 0 "memory_operand" "")
17639 (const_int 0))]
17640 "! optimize_size
17641 && ! TARGET_USE_MOV0
17642 && TARGET_SPLIT_LONG_MOVES
17643 && get_attr_length (insn) >= ix86_cost->large_insn
17644 && peep2_regno_dead_p (0, FLAGS_REG)"
17645 [(parallel [(set (match_dup 2) (const_int 0))
17646 (clobber (reg:CC 17))])
17647 (set (match_dup 0) (match_dup 1))]
17648 "operands[2] = gen_lowpart (SImode, operands[1]);")
17649
17650 (define_peephole2
17651 [(match_scratch:QI 1 "q")
17652 (set (match_operand:QI 0 "memory_operand" "")
17653 (const_int 0))]
17654 "! optimize_size
17655 && ! TARGET_USE_MOV0
17656 && TARGET_SPLIT_LONG_MOVES
17657 && get_attr_length (insn) >= ix86_cost->large_insn
17658 && peep2_regno_dead_p (0, FLAGS_REG)"
17659 [(parallel [(set (match_dup 2) (const_int 0))
17660 (clobber (reg:CC 17))])
17661 (set (match_dup 0) (match_dup 1))]
17662 "operands[2] = gen_lowpart (SImode, operands[1]);")
17663
17664 (define_peephole2
17665 [(match_scratch:SI 2 "r")
17666 (set (match_operand:SI 0 "memory_operand" "")
17667 (match_operand:SI 1 "immediate_operand" ""))]
17668 "! optimize_size
17669 && get_attr_length (insn) >= ix86_cost->large_insn
17670 && TARGET_SPLIT_LONG_MOVES"
17671 [(set (match_dup 2) (match_dup 1))
17672 (set (match_dup 0) (match_dup 2))]
17673 "")
17674
17675 (define_peephole2
17676 [(match_scratch:HI 2 "r")
17677 (set (match_operand:HI 0 "memory_operand" "")
17678 (match_operand:HI 1 "immediate_operand" ""))]
17679 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17680 && TARGET_SPLIT_LONG_MOVES"
17681 [(set (match_dup 2) (match_dup 1))
17682 (set (match_dup 0) (match_dup 2))]
17683 "")
17684
17685 (define_peephole2
17686 [(match_scratch:QI 2 "q")
17687 (set (match_operand:QI 0 "memory_operand" "")
17688 (match_operand:QI 1 "immediate_operand" ""))]
17689 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17690 && TARGET_SPLIT_LONG_MOVES"
17691 [(set (match_dup 2) (match_dup 1))
17692 (set (match_dup 0) (match_dup 2))]
17693 "")
17694
17695 ;; Don't compare memory with zero, load and use a test instead.
17696 (define_peephole2
17697 [(set (reg 17)
17698 (compare (match_operand:SI 0 "memory_operand" "")
17699 (const_int 0)))
17700 (match_scratch:SI 3 "r")]
17701 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17702 [(set (match_dup 3) (match_dup 0))
17703 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17704 "")
17705
17706 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17707 ;; Don't split NOTs with a displacement operand, because resulting XOR
17708 ;; will not be pairable anyway.
17709 ;;
17710 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17711 ;; represented using a modRM byte. The XOR replacement is long decoded,
17712 ;; so this split helps here as well.
17713 ;;
17714 ;; Note: Can't do this as a regular split because we can't get proper
17715 ;; lifetime information then.
17716
17717 (define_peephole2
17718 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17719 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17720 "!optimize_size
17721 && peep2_regno_dead_p (0, FLAGS_REG)
17722 && ((TARGET_PENTIUM
17723 && (GET_CODE (operands[0]) != MEM
17724 || !memory_displacement_operand (operands[0], SImode)))
17725 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17726 [(parallel [(set (match_dup 0)
17727 (xor:SI (match_dup 1) (const_int -1)))
17728 (clobber (reg:CC 17))])]
17729 "")
17730
17731 (define_peephole2
17732 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17733 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17734 "!optimize_size
17735 && peep2_regno_dead_p (0, FLAGS_REG)
17736 && ((TARGET_PENTIUM
17737 && (GET_CODE (operands[0]) != MEM
17738 || !memory_displacement_operand (operands[0], HImode)))
17739 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17740 [(parallel [(set (match_dup 0)
17741 (xor:HI (match_dup 1) (const_int -1)))
17742 (clobber (reg:CC 17))])]
17743 "")
17744
17745 (define_peephole2
17746 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17747 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17748 "!optimize_size
17749 && peep2_regno_dead_p (0, FLAGS_REG)
17750 && ((TARGET_PENTIUM
17751 && (GET_CODE (operands[0]) != MEM
17752 || !memory_displacement_operand (operands[0], QImode)))
17753 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17754 [(parallel [(set (match_dup 0)
17755 (xor:QI (match_dup 1) (const_int -1)))
17756 (clobber (reg:CC 17))])]
17757 "")
17758
17759 ;; Non pairable "test imm, reg" instructions can be translated to
17760 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17761 ;; byte opcode instead of two, have a short form for byte operands),
17762 ;; so do it for other CPUs as well. Given that the value was dead,
17763 ;; this should not create any new dependencies. Pass on the sub-word
17764 ;; versions if we're concerned about partial register stalls.
17765
17766 (define_peephole2
17767 [(set (reg 17)
17768 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17769 (match_operand:SI 1 "immediate_operand" ""))
17770 (const_int 0)))]
17771 "ix86_match_ccmode (insn, CCNOmode)
17772 && (true_regnum (operands[0]) != 0
17773 || (GET_CODE (operands[1]) == CONST_INT
17774 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17775 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17776 [(parallel
17777 [(set (reg:CCNO 17)
17778 (compare:CCNO (and:SI (match_dup 0)
17779 (match_dup 1))
17780 (const_int 0)))
17781 (set (match_dup 0)
17782 (and:SI (match_dup 0) (match_dup 1)))])]
17783 "")
17784
17785 ;; We don't need to handle HImode case, because it will be promoted to SImode
17786 ;; on ! TARGET_PARTIAL_REG_STALL
17787
17788 (define_peephole2
17789 [(set (reg 17)
17790 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17791 (match_operand:QI 1 "immediate_operand" ""))
17792 (const_int 0)))]
17793 "! TARGET_PARTIAL_REG_STALL
17794 && ix86_match_ccmode (insn, CCNOmode)
17795 && true_regnum (operands[0]) != 0
17796 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17797 [(parallel
17798 [(set (reg:CCNO 17)
17799 (compare:CCNO (and:QI (match_dup 0)
17800 (match_dup 1))
17801 (const_int 0)))
17802 (set (match_dup 0)
17803 (and:QI (match_dup 0) (match_dup 1)))])]
17804 "")
17805
17806 (define_peephole2
17807 [(set (reg 17)
17808 (compare
17809 (and:SI
17810 (zero_extract:SI
17811 (match_operand 0 "ext_register_operand" "")
17812 (const_int 8)
17813 (const_int 8))
17814 (match_operand 1 "const_int_operand" ""))
17815 (const_int 0)))]
17816 "! TARGET_PARTIAL_REG_STALL
17817 && ix86_match_ccmode (insn, CCNOmode)
17818 && true_regnum (operands[0]) != 0
17819 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17820 [(parallel [(set (reg:CCNO 17)
17821 (compare:CCNO
17822 (and:SI
17823 (zero_extract:SI
17824 (match_dup 0)
17825 (const_int 8)
17826 (const_int 8))
17827 (match_dup 1))
17828 (const_int 0)))
17829 (set (zero_extract:SI (match_dup 0)
17830 (const_int 8)
17831 (const_int 8))
17832 (and:SI
17833 (zero_extract:SI
17834 (match_dup 0)
17835 (const_int 8)
17836 (const_int 8))
17837 (match_dup 1)))])]
17838 "")
17839
17840 ;; Don't do logical operations with memory inputs.
17841 (define_peephole2
17842 [(match_scratch:SI 2 "r")
17843 (parallel [(set (match_operand:SI 0 "register_operand" "")
17844 (match_operator:SI 3 "arith_or_logical_operator"
17845 [(match_dup 0)
17846 (match_operand:SI 1 "memory_operand" "")]))
17847 (clobber (reg:CC 17))])]
17848 "! optimize_size && ! TARGET_READ_MODIFY"
17849 [(set (match_dup 2) (match_dup 1))
17850 (parallel [(set (match_dup 0)
17851 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17852 (clobber (reg:CC 17))])]
17853 "")
17854
17855 (define_peephole2
17856 [(match_scratch:SI 2 "r")
17857 (parallel [(set (match_operand:SI 0 "register_operand" "")
17858 (match_operator:SI 3 "arith_or_logical_operator"
17859 [(match_operand:SI 1 "memory_operand" "")
17860 (match_dup 0)]))
17861 (clobber (reg:CC 17))])]
17862 "! optimize_size && ! TARGET_READ_MODIFY"
17863 [(set (match_dup 2) (match_dup 1))
17864 (parallel [(set (match_dup 0)
17865 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17866 (clobber (reg:CC 17))])]
17867 "")
17868
17869 ; Don't do logical operations with memory outputs
17870 ;
17871 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17872 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17873 ; the same decoder scheduling characteristics as the original.
17874
17875 (define_peephole2
17876 [(match_scratch:SI 2 "r")
17877 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17878 (match_operator:SI 3 "arith_or_logical_operator"
17879 [(match_dup 0)
17880 (match_operand:SI 1 "nonmemory_operand" "")]))
17881 (clobber (reg:CC 17))])]
17882 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17883 [(set (match_dup 2) (match_dup 0))
17884 (parallel [(set (match_dup 2)
17885 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17886 (clobber (reg:CC 17))])
17887 (set (match_dup 0) (match_dup 2))]
17888 "")
17889
17890 (define_peephole2
17891 [(match_scratch:SI 2 "r")
17892 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17893 (match_operator:SI 3 "arith_or_logical_operator"
17894 [(match_operand:SI 1 "nonmemory_operand" "")
17895 (match_dup 0)]))
17896 (clobber (reg:CC 17))])]
17897 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17898 [(set (match_dup 2) (match_dup 0))
17899 (parallel [(set (match_dup 2)
17900 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17901 (clobber (reg:CC 17))])
17902 (set (match_dup 0) (match_dup 2))]
17903 "")
17904
17905 ;; Attempt to always use XOR for zeroing registers.
17906 (define_peephole2
17907 [(set (match_operand 0 "register_operand" "")
17908 (const_int 0))]
17909 "(GET_MODE (operands[0]) == QImode
17910 || GET_MODE (operands[0]) == HImode
17911 || GET_MODE (operands[0]) == SImode
17912 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17913 && (! TARGET_USE_MOV0 || optimize_size)
17914 && peep2_regno_dead_p (0, FLAGS_REG)"
17915 [(parallel [(set (match_dup 0) (const_int 0))
17916 (clobber (reg:CC 17))])]
17917 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17918 operands[0]);")
17919
17920 (define_peephole2
17921 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17922 (const_int 0))]
17923 "(GET_MODE (operands[0]) == QImode
17924 || GET_MODE (operands[0]) == HImode)
17925 && (! TARGET_USE_MOV0 || optimize_size)
17926 && peep2_regno_dead_p (0, FLAGS_REG)"
17927 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17928 (clobber (reg:CC 17))])])
17929
17930 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17931 (define_peephole2
17932 [(set (match_operand 0 "register_operand" "")
17933 (const_int -1))]
17934 "(GET_MODE (operands[0]) == HImode
17935 || GET_MODE (operands[0]) == SImode
17936 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17937 && (optimize_size || TARGET_PENTIUM)
17938 && peep2_regno_dead_p (0, FLAGS_REG)"
17939 [(parallel [(set (match_dup 0) (const_int -1))
17940 (clobber (reg:CC 17))])]
17941 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17942 operands[0]);")
17943
17944 ;; Attempt to convert simple leas to adds. These can be created by
17945 ;; move expanders.
17946 (define_peephole2
17947 [(set (match_operand:SI 0 "register_operand" "")
17948 (plus:SI (match_dup 0)
17949 (match_operand:SI 1 "nonmemory_operand" "")))]
17950 "peep2_regno_dead_p (0, FLAGS_REG)"
17951 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17952 (clobber (reg:CC 17))])]
17953 "")
17954
17955 (define_peephole2
17956 [(set (match_operand:SI 0 "register_operand" "")
17957 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17958 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17959 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17960 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17961 (clobber (reg:CC 17))])]
17962 "operands[2] = gen_lowpart (SImode, operands[2]);")
17963
17964 (define_peephole2
17965 [(set (match_operand:DI 0 "register_operand" "")
17966 (plus:DI (match_dup 0)
17967 (match_operand:DI 1 "x86_64_general_operand" "")))]
17968 "peep2_regno_dead_p (0, FLAGS_REG)"
17969 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17970 (clobber (reg:CC 17))])]
17971 "")
17972
17973 (define_peephole2
17974 [(set (match_operand:SI 0 "register_operand" "")
17975 (mult:SI (match_dup 0)
17976 (match_operand:SI 1 "const_int_operand" "")))]
17977 "exact_log2 (INTVAL (operands[1])) >= 0
17978 && peep2_regno_dead_p (0, FLAGS_REG)"
17979 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17980 (clobber (reg:CC 17))])]
17981 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17982
17983 (define_peephole2
17984 [(set (match_operand:DI 0 "register_operand" "")
17985 (mult:DI (match_dup 0)
17986 (match_operand:DI 1 "const_int_operand" "")))]
17987 "exact_log2 (INTVAL (operands[1])) >= 0
17988 && peep2_regno_dead_p (0, FLAGS_REG)"
17989 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17990 (clobber (reg:CC 17))])]
17991 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17992
17993 (define_peephole2
17994 [(set (match_operand:SI 0 "register_operand" "")
17995 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17996 (match_operand:DI 2 "const_int_operand" "")) 0))]
17997 "exact_log2 (INTVAL (operands[2])) >= 0
17998 && REGNO (operands[0]) == REGNO (operands[1])
17999 && peep2_regno_dead_p (0, FLAGS_REG)"
18000 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18001 (clobber (reg:CC 17))])]
18002 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18003
18004 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18005 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18006 ;; many CPUs it is also faster, since special hardware to avoid esp
18007 ;; dependencies is present.
18008
18009 ;; While some of these conversions may be done using splitters, we use peepholes
18010 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18011
18012 ;; Convert prologue esp subtractions to push.
18013 ;; We need register to push. In order to keep verify_flow_info happy we have
18014 ;; two choices
18015 ;; - use scratch and clobber it in order to avoid dependencies
18016 ;; - use already live register
18017 ;; We can't use the second way right now, since there is no reliable way how to
18018 ;; verify that given register is live. First choice will also most likely in
18019 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18020 ;; call clobbered registers are dead. We may want to use base pointer as an
18021 ;; alternative when no register is available later.
18022
18023 (define_peephole2
18024 [(match_scratch:SI 0 "r")
18025 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18026 (clobber (reg:CC 17))
18027 (clobber (mem:BLK (scratch)))])]
18028 "optimize_size || !TARGET_SUB_ESP_4"
18029 [(clobber (match_dup 0))
18030 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18031 (clobber (mem:BLK (scratch)))])])
18032
18033 (define_peephole2
18034 [(match_scratch:SI 0 "r")
18035 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18036 (clobber (reg:CC 17))
18037 (clobber (mem:BLK (scratch)))])]
18038 "optimize_size || !TARGET_SUB_ESP_8"
18039 [(clobber (match_dup 0))
18040 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18041 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18042 (clobber (mem:BLK (scratch)))])])
18043
18044 ;; Convert esp subtractions to push.
18045 (define_peephole2
18046 [(match_scratch:SI 0 "r")
18047 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18048 (clobber (reg:CC 17))])]
18049 "optimize_size || !TARGET_SUB_ESP_4"
18050 [(clobber (match_dup 0))
18051 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18052
18053 (define_peephole2
18054 [(match_scratch:SI 0 "r")
18055 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18056 (clobber (reg:CC 17))])]
18057 "optimize_size || !TARGET_SUB_ESP_8"
18058 [(clobber (match_dup 0))
18059 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18060 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18061
18062 ;; Convert epilogue deallocator to pop.
18063 (define_peephole2
18064 [(match_scratch:SI 0 "r")
18065 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18066 (clobber (reg:CC 17))
18067 (clobber (mem:BLK (scratch)))])]
18068 "optimize_size || !TARGET_ADD_ESP_4"
18069 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18070 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18071 (clobber (mem:BLK (scratch)))])]
18072 "")
18073
18074 ;; Two pops case is tricky, since pop causes dependency on destination register.
18075 ;; We use two registers if available.
18076 (define_peephole2
18077 [(match_scratch:SI 0 "r")
18078 (match_scratch:SI 1 "r")
18079 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18080 (clobber (reg:CC 17))
18081 (clobber (mem:BLK (scratch)))])]
18082 "optimize_size || !TARGET_ADD_ESP_8"
18083 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18084 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18085 (clobber (mem:BLK (scratch)))])
18086 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18087 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18088 "")
18089
18090 (define_peephole2
18091 [(match_scratch:SI 0 "r")
18092 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18093 (clobber (reg:CC 17))
18094 (clobber (mem:BLK (scratch)))])]
18095 "optimize_size"
18096 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18097 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18098 (clobber (mem:BLK (scratch)))])
18099 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18100 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18101 "")
18102
18103 ;; Convert esp additions to pop.
18104 (define_peephole2
18105 [(match_scratch:SI 0 "r")
18106 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18107 (clobber (reg:CC 17))])]
18108 ""
18109 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18110 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18111 "")
18112
18113 ;; Two pops case is tricky, since pop causes dependency on destination register.
18114 ;; We use two registers if available.
18115 (define_peephole2
18116 [(match_scratch:SI 0 "r")
18117 (match_scratch:SI 1 "r")
18118 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18119 (clobber (reg:CC 17))])]
18120 ""
18121 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18122 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18123 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18124 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18125 "")
18126
18127 (define_peephole2
18128 [(match_scratch:SI 0 "r")
18129 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18130 (clobber (reg:CC 17))])]
18131 "optimize_size"
18132 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18133 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18134 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18135 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18136 "")
18137 \f
18138 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18139 ;; required and register dies.
18140 (define_peephole2
18141 [(set (reg 17)
18142 (compare (match_operand:SI 0 "register_operand" "")
18143 (match_operand:SI 1 "incdec_operand" "")))]
18144 "ix86_match_ccmode (insn, CCGCmode)
18145 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18146 [(parallel [(set (reg:CCGC 17)
18147 (compare:CCGC (match_dup 0)
18148 (match_dup 1)))
18149 (clobber (match_dup 0))])]
18150 "")
18151
18152 (define_peephole2
18153 [(set (reg 17)
18154 (compare (match_operand:HI 0 "register_operand" "")
18155 (match_operand:HI 1 "incdec_operand" "")))]
18156 "ix86_match_ccmode (insn, CCGCmode)
18157 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18158 [(parallel [(set (reg:CCGC 17)
18159 (compare:CCGC (match_dup 0)
18160 (match_dup 1)))
18161 (clobber (match_dup 0))])]
18162 "")
18163
18164 (define_peephole2
18165 [(set (reg 17)
18166 (compare (match_operand:QI 0 "register_operand" "")
18167 (match_operand:QI 1 "incdec_operand" "")))]
18168 "ix86_match_ccmode (insn, CCGCmode)
18169 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18170 [(parallel [(set (reg:CCGC 17)
18171 (compare:CCGC (match_dup 0)
18172 (match_dup 1)))
18173 (clobber (match_dup 0))])]
18174 "")
18175
18176 ;; Convert compares with 128 to shorter add -128
18177 (define_peephole2
18178 [(set (reg 17)
18179 (compare (match_operand:SI 0 "register_operand" "")
18180 (const_int 128)))]
18181 "ix86_match_ccmode (insn, CCGCmode)
18182 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18183 [(parallel [(set (reg:CCGC 17)
18184 (compare:CCGC (match_dup 0)
18185 (const_int 128)))
18186 (clobber (match_dup 0))])]
18187 "")
18188
18189 (define_peephole2
18190 [(set (reg 17)
18191 (compare (match_operand:HI 0 "register_operand" "")
18192 (const_int 128)))]
18193 "ix86_match_ccmode (insn, CCGCmode)
18194 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18195 [(parallel [(set (reg:CCGC 17)
18196 (compare:CCGC (match_dup 0)
18197 (const_int 128)))
18198 (clobber (match_dup 0))])]
18199 "")
18200 \f
18201 (define_peephole2
18202 [(match_scratch:DI 0 "r")
18203 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18204 (clobber (reg:CC 17))
18205 (clobber (mem:BLK (scratch)))])]
18206 "optimize_size || !TARGET_SUB_ESP_4"
18207 [(clobber (match_dup 0))
18208 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18209 (clobber (mem:BLK (scratch)))])])
18210
18211 (define_peephole2
18212 [(match_scratch:DI 0 "r")
18213 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18214 (clobber (reg:CC 17))
18215 (clobber (mem:BLK (scratch)))])]
18216 "optimize_size || !TARGET_SUB_ESP_8"
18217 [(clobber (match_dup 0))
18218 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18219 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18220 (clobber (mem:BLK (scratch)))])])
18221
18222 ;; Convert esp subtractions to push.
18223 (define_peephole2
18224 [(match_scratch:DI 0 "r")
18225 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18226 (clobber (reg:CC 17))])]
18227 "optimize_size || !TARGET_SUB_ESP_4"
18228 [(clobber (match_dup 0))
18229 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18230
18231 (define_peephole2
18232 [(match_scratch:DI 0 "r")
18233 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18234 (clobber (reg:CC 17))])]
18235 "optimize_size || !TARGET_SUB_ESP_8"
18236 [(clobber (match_dup 0))
18237 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18238 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18239
18240 ;; Convert epilogue deallocator to pop.
18241 (define_peephole2
18242 [(match_scratch:DI 0 "r")
18243 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18244 (clobber (reg:CC 17))
18245 (clobber (mem:BLK (scratch)))])]
18246 "optimize_size || !TARGET_ADD_ESP_4"
18247 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18248 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18249 (clobber (mem:BLK (scratch)))])]
18250 "")
18251
18252 ;; Two pops case is tricky, since pop causes dependency on destination register.
18253 ;; We use two registers if available.
18254 (define_peephole2
18255 [(match_scratch:DI 0 "r")
18256 (match_scratch:DI 1 "r")
18257 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18258 (clobber (reg:CC 17))
18259 (clobber (mem:BLK (scratch)))])]
18260 "optimize_size || !TARGET_ADD_ESP_8"
18261 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18262 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18263 (clobber (mem:BLK (scratch)))])
18264 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18265 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18266 "")
18267
18268 (define_peephole2
18269 [(match_scratch:DI 0 "r")
18270 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18271 (clobber (reg:CC 17))
18272 (clobber (mem:BLK (scratch)))])]
18273 "optimize_size"
18274 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18275 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18276 (clobber (mem:BLK (scratch)))])
18277 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18278 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18279 "")
18280
18281 ;; Convert esp additions to pop.
18282 (define_peephole2
18283 [(match_scratch:DI 0 "r")
18284 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18285 (clobber (reg:CC 17))])]
18286 ""
18287 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18288 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18289 "")
18290
18291 ;; Two pops case is tricky, since pop causes dependency on destination register.
18292 ;; We use two registers if available.
18293 (define_peephole2
18294 [(match_scratch:DI 0 "r")
18295 (match_scratch:DI 1 "r")
18296 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18297 (clobber (reg:CC 17))])]
18298 ""
18299 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18300 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18301 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18302 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18303 "")
18304
18305 (define_peephole2
18306 [(match_scratch:DI 0 "r")
18307 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18308 (clobber (reg:CC 17))])]
18309 "optimize_size"
18310 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18311 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18312 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18313 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18314 "")
18315 \f
18316 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18317 ;; imul $32bit_imm, reg, reg is direct decoded.
18318 (define_peephole2
18319 [(match_scratch:DI 3 "r")
18320 (parallel [(set (match_operand:DI 0 "register_operand" "")
18321 (mult:DI (match_operand:DI 1 "memory_operand" "")
18322 (match_operand:DI 2 "immediate_operand" "")))
18323 (clobber (reg:CC 17))])]
18324 "TARGET_K8 && !optimize_size
18325 && (GET_CODE (operands[2]) != CONST_INT
18326 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18327 [(set (match_dup 3) (match_dup 1))
18328 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18329 (clobber (reg:CC 17))])]
18330 "")
18331
18332 (define_peephole2
18333 [(match_scratch:SI 3 "r")
18334 (parallel [(set (match_operand:SI 0 "register_operand" "")
18335 (mult:SI (match_operand:SI 1 "memory_operand" "")
18336 (match_operand:SI 2 "immediate_operand" "")))
18337 (clobber (reg:CC 17))])]
18338 "TARGET_K8 && !optimize_size
18339 && (GET_CODE (operands[2]) != CONST_INT
18340 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18341 [(set (match_dup 3) (match_dup 1))
18342 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18343 (clobber (reg:CC 17))])]
18344 "")
18345
18346 (define_peephole2
18347 [(match_scratch:SI 3 "r")
18348 (parallel [(set (match_operand:DI 0 "register_operand" "")
18349 (zero_extend:DI
18350 (mult:SI (match_operand:SI 1 "memory_operand" "")
18351 (match_operand:SI 2 "immediate_operand" ""))))
18352 (clobber (reg:CC 17))])]
18353 "TARGET_K8 && !optimize_size
18354 && (GET_CODE (operands[2]) != CONST_INT
18355 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18356 [(set (match_dup 3) (match_dup 1))
18357 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18358 (clobber (reg:CC 17))])]
18359 "")
18360
18361 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18362 ;; Convert it into imul reg, reg
18363 ;; It would be better to force assembler to encode instruction using long
18364 ;; immediate, but there is apparently no way to do so.
18365 (define_peephole2
18366 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18367 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18368 (match_operand:DI 2 "const_int_operand" "")))
18369 (clobber (reg:CC 17))])
18370 (match_scratch:DI 3 "r")]
18371 "TARGET_K8 && !optimize_size
18372 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18373 [(set (match_dup 3) (match_dup 2))
18374 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18375 (clobber (reg:CC 17))])]
18376 {
18377 if (!rtx_equal_p (operands[0], operands[1]))
18378 emit_move_insn (operands[0], operands[1]);
18379 })
18380
18381 (define_peephole2
18382 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18383 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18384 (match_operand:SI 2 "const_int_operand" "")))
18385 (clobber (reg:CC 17))])
18386 (match_scratch:SI 3 "r")]
18387 "TARGET_K8 && !optimize_size
18388 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18389 [(set (match_dup 3) (match_dup 2))
18390 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18391 (clobber (reg:CC 17))])]
18392 {
18393 if (!rtx_equal_p (operands[0], operands[1]))
18394 emit_move_insn (operands[0], operands[1]);
18395 })
18396
18397 (define_peephole2
18398 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18399 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18400 (match_operand:HI 2 "immediate_operand" "")))
18401 (clobber (reg:CC 17))])
18402 (match_scratch:HI 3 "r")]
18403 "TARGET_K8 && !optimize_size"
18404 [(set (match_dup 3) (match_dup 2))
18405 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18406 (clobber (reg:CC 17))])]
18407 {
18408 if (!rtx_equal_p (operands[0], operands[1]))
18409 emit_move_insn (operands[0], operands[1]);
18410 })
18411 \f
18412 ;; Call-value patterns last so that the wildcard operand does not
18413 ;; disrupt insn-recog's switch tables.
18414
18415 (define_insn "*call_value_pop_0"
18416 [(set (match_operand 0 "" "")
18417 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18418 (match_operand:SI 2 "" "")))
18419 (set (reg:SI 7) (plus:SI (reg:SI 7)
18420 (match_operand:SI 3 "immediate_operand" "")))]
18421 "!TARGET_64BIT"
18422 {
18423 if (SIBLING_CALL_P (insn))
18424 return "jmp\t%P1";
18425 else
18426 return "call\t%P1";
18427 }
18428 [(set_attr "type" "callv")])
18429
18430 (define_insn "*call_value_pop_1"
18431 [(set (match_operand 0 "" "")
18432 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18433 (match_operand:SI 2 "" "")))
18434 (set (reg:SI 7) (plus:SI (reg:SI 7)
18435 (match_operand:SI 3 "immediate_operand" "i")))]
18436 "!TARGET_64BIT"
18437 {
18438 if (constant_call_address_operand (operands[1], QImode))
18439 {
18440 if (SIBLING_CALL_P (insn))
18441 return "jmp\t%P1";
18442 else
18443 return "call\t%P1";
18444 }
18445 if (SIBLING_CALL_P (insn))
18446 return "jmp\t%A1";
18447 else
18448 return "call\t%A1";
18449 }
18450 [(set_attr "type" "callv")])
18451
18452 (define_insn "*call_value_0"
18453 [(set (match_operand 0 "" "")
18454 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18455 (match_operand:SI 2 "" "")))]
18456 "!TARGET_64BIT"
18457 {
18458 if (SIBLING_CALL_P (insn))
18459 return "jmp\t%P1";
18460 else
18461 return "call\t%P1";
18462 }
18463 [(set_attr "type" "callv")])
18464
18465 (define_insn "*call_value_0_rex64"
18466 [(set (match_operand 0 "" "")
18467 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18468 (match_operand:DI 2 "const_int_operand" "")))]
18469 "TARGET_64BIT"
18470 {
18471 if (SIBLING_CALL_P (insn))
18472 return "jmp\t%P1";
18473 else
18474 return "call\t%P1";
18475 }
18476 [(set_attr "type" "callv")])
18477
18478 (define_insn "*call_value_1"
18479 [(set (match_operand 0 "" "")
18480 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18481 (match_operand:SI 2 "" "")))]
18482 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18483 {
18484 if (constant_call_address_operand (operands[1], QImode))
18485 return "call\t%P1";
18486 return "call\t%*%1";
18487 }
18488 [(set_attr "type" "callv")])
18489
18490 (define_insn "*sibcall_value_1"
18491 [(set (match_operand 0 "" "")
18492 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18493 (match_operand:SI 2 "" "")))]
18494 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18495 {
18496 if (constant_call_address_operand (operands[1], QImode))
18497 return "jmp\t%P1";
18498 return "jmp\t%*%1";
18499 }
18500 [(set_attr "type" "callv")])
18501
18502 (define_insn "*call_value_1_rex64"
18503 [(set (match_operand 0 "" "")
18504 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18505 (match_operand:DI 2 "" "")))]
18506 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18507 {
18508 if (constant_call_address_operand (operands[1], QImode))
18509 return "call\t%P1";
18510 return "call\t%A1";
18511 }
18512 [(set_attr "type" "callv")])
18513
18514 (define_insn "*sibcall_value_1_rex64"
18515 [(set (match_operand 0 "" "")
18516 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18517 (match_operand:DI 2 "" "")))]
18518 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18519 "jmp\t%P1"
18520 [(set_attr "type" "callv")])
18521
18522 (define_insn "*sibcall_value_1_rex64_v"
18523 [(set (match_operand 0 "" "")
18524 (call (mem:QI (reg:DI 40))
18525 (match_operand:DI 1 "" "")))]
18526 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18527 "jmp\t*%%r11"
18528 [(set_attr "type" "callv")])
18529 \f
18530 (define_insn "trap"
18531 [(trap_if (const_int 1) (const_int 5))]
18532 ""
18533 "int\t$5")
18534
18535 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18536 ;;; for the sake of bounds checking. By emitting bounds checks as
18537 ;;; conditional traps rather than as conditional jumps around
18538 ;;; unconditional traps we avoid introducing spurious basic-block
18539 ;;; boundaries and facilitate elimination of redundant checks. In
18540 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18541 ;;; interrupt 5.
18542 ;;;
18543 ;;; FIXME: Static branch prediction rules for ix86 are such that
18544 ;;; forward conditional branches predict as untaken. As implemented
18545 ;;; below, pseudo conditional traps violate that rule. We should use
18546 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18547 ;;; section loaded at the end of the text segment and branch forward
18548 ;;; there on bounds-failure, and then jump back immediately (in case
18549 ;;; the system chooses to ignore bounds violations, or to report
18550 ;;; violations and continue execution).
18551
18552 (define_expand "conditional_trap"
18553 [(trap_if (match_operator 0 "comparison_operator"
18554 [(match_dup 2) (const_int 0)])
18555 (match_operand 1 "const_int_operand" ""))]
18556 ""
18557 {
18558 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18559 ix86_expand_compare (GET_CODE (operands[0]),
18560 NULL, NULL),
18561 operands[1]));
18562 DONE;
18563 })
18564
18565 (define_insn "*conditional_trap_1"
18566 [(trap_if (match_operator 0 "comparison_operator"
18567 [(reg 17) (const_int 0)])
18568 (match_operand 1 "const_int_operand" ""))]
18569 ""
18570 {
18571 operands[2] = gen_label_rtx ();
18572 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18573 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18574 CODE_LABEL_NUMBER (operands[2]));
18575 RET;
18576 })
18577
18578 ;; Pentium III SIMD instructions.
18579
18580 ;; Moves for SSE/MMX regs.
18581
18582 (define_insn "movv4sf_internal"
18583 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18584 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18585 "TARGET_SSE"
18586 "@
18587 xorps\t%0, %0
18588 movaps\t{%1, %0|%0, %1}
18589 movaps\t{%1, %0|%0, %1}"
18590 [(set_attr "type" "ssemov")
18591 (set_attr "mode" "V4SF")])
18592
18593 (define_split
18594 [(set (match_operand:V4SF 0 "register_operand" "")
18595 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18596 "TARGET_SSE"
18597 [(set (match_dup 0)
18598 (vec_merge:V4SF
18599 (vec_duplicate:V4SF (match_dup 1))
18600 (match_dup 2)
18601 (const_int 1)))]
18602 {
18603 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18604 operands[2] = CONST0_RTX (V4SFmode);
18605 })
18606
18607 (define_insn "movv4si_internal"
18608 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18609 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18610 "TARGET_SSE"
18611 {
18612 switch (which_alternative)
18613 {
18614 case 0:
18615 if (get_attr_mode (insn) == MODE_V4SF)
18616 return "xorps\t%0, %0";
18617 else
18618 return "pxor\t%0, %0";
18619 case 1:
18620 case 2:
18621 if (get_attr_mode (insn) == MODE_V4SF)
18622 return "movaps\t{%1, %0|%0, %1}";
18623 else
18624 return "movdqa\t{%1, %0|%0, %1}";
18625 default:
18626 abort ();
18627 }
18628 }
18629 [(set_attr "type" "ssemov")
18630 (set (attr "mode")
18631 (cond [(eq_attr "alternative" "0,1")
18632 (if_then_else
18633 (ne (symbol_ref "optimize_size")
18634 (const_int 0))
18635 (const_string "V4SF")
18636 (const_string "TI"))
18637 (eq_attr "alternative" "2")
18638 (if_then_else
18639 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18640 (const_int 0))
18641 (ne (symbol_ref "optimize_size")
18642 (const_int 0)))
18643 (const_string "V4SF")
18644 (const_string "TI"))]
18645 (const_string "TI")))])
18646
18647 (define_insn "movv2di_internal"
18648 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18649 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18650 "TARGET_SSE2"
18651 {
18652 switch (which_alternative)
18653 {
18654 case 0:
18655 if (get_attr_mode (insn) == MODE_V4SF)
18656 return "xorps\t%0, %0";
18657 else
18658 return "pxor\t%0, %0";
18659 case 1:
18660 case 2:
18661 if (get_attr_mode (insn) == MODE_V4SF)
18662 return "movaps\t{%1, %0|%0, %1}";
18663 else
18664 return "movdqa\t{%1, %0|%0, %1}";
18665 default:
18666 abort ();
18667 }
18668 }
18669 [(set_attr "type" "ssemov")
18670 (set (attr "mode")
18671 (cond [(eq_attr "alternative" "0,1")
18672 (if_then_else
18673 (ne (symbol_ref "optimize_size")
18674 (const_int 0))
18675 (const_string "V4SF")
18676 (const_string "TI"))
18677 (eq_attr "alternative" "2")
18678 (if_then_else
18679 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18680 (const_int 0))
18681 (ne (symbol_ref "optimize_size")
18682 (const_int 0)))
18683 (const_string "V4SF")
18684 (const_string "TI"))]
18685 (const_string "TI")))])
18686
18687 (define_split
18688 [(set (match_operand:V2DF 0 "register_operand" "")
18689 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18690 "TARGET_SSE2"
18691 [(set (match_dup 0)
18692 (vec_merge:V2DF
18693 (vec_duplicate:V2DF (match_dup 1))
18694 (match_dup 2)
18695 (const_int 1)))]
18696 {
18697 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18698 operands[2] = CONST0_RTX (V2DFmode);
18699 })
18700
18701 (define_insn "movv8qi_internal"
18702 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18703 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18704 "TARGET_MMX
18705 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18706 "@
18707 pxor\t%0, %0
18708 movq\t{%1, %0|%0, %1}
18709 movq\t{%1, %0|%0, %1}"
18710 [(set_attr "type" "mmxmov")
18711 (set_attr "mode" "DI")])
18712
18713 (define_insn "movv4hi_internal"
18714 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18715 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18716 "TARGET_MMX
18717 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18718 "@
18719 pxor\t%0, %0
18720 movq\t{%1, %0|%0, %1}
18721 movq\t{%1, %0|%0, %1}"
18722 [(set_attr "type" "mmxmov")
18723 (set_attr "mode" "DI")])
18724
18725 (define_insn "movv2si_internal"
18726 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18727 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18728 "TARGET_MMX
18729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18730 "@
18731 pxor\t%0, %0
18732 movq\t{%1, %0|%0, %1}
18733 movq\t{%1, %0|%0, %1}"
18734 [(set_attr "type" "mmxcvt")
18735 (set_attr "mode" "DI")])
18736
18737 (define_insn "movv2sf_internal"
18738 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18739 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18740 "TARGET_3DNOW
18741 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18742 "@
18743 pxor\t%0, %0
18744 movq\t{%1, %0|%0, %1}
18745 movq\t{%1, %0|%0, %1}"
18746 [(set_attr "type" "mmxcvt")
18747 (set_attr "mode" "DI")])
18748
18749 (define_expand "movti"
18750 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18751 (match_operand:TI 1 "nonimmediate_operand" ""))]
18752 "TARGET_SSE || TARGET_64BIT"
18753 {
18754 if (TARGET_64BIT)
18755 ix86_expand_move (TImode, operands);
18756 else
18757 ix86_expand_vector_move (TImode, operands);
18758 DONE;
18759 })
18760
18761 (define_expand "movtf"
18762 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18763 (match_operand:TF 1 "nonimmediate_operand" ""))]
18764 "TARGET_64BIT"
18765 {
18766 if (TARGET_64BIT)
18767 ix86_expand_move (TFmode, operands);
18768 else
18769 ix86_expand_vector_move (TFmode, operands);
18770 DONE;
18771 })
18772
18773 (define_insn "movv2df_internal"
18774 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18775 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18776 "TARGET_SSE2
18777 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18778 {
18779 switch (which_alternative)
18780 {
18781 case 0:
18782 if (get_attr_mode (insn) == MODE_V4SF)
18783 return "xorps\t%0, %0";
18784 else
18785 return "xorpd\t%0, %0";
18786 case 1:
18787 case 2:
18788 if (get_attr_mode (insn) == MODE_V4SF)
18789 return "movaps\t{%1, %0|%0, %1}";
18790 else
18791 return "movapd\t{%1, %0|%0, %1}";
18792 default:
18793 abort ();
18794 }
18795 }
18796 [(set_attr "type" "ssemov")
18797 (set (attr "mode")
18798 (cond [(eq_attr "alternative" "0,1")
18799 (if_then_else
18800 (ne (symbol_ref "optimize_size")
18801 (const_int 0))
18802 (const_string "V4SF")
18803 (const_string "V2DF"))
18804 (eq_attr "alternative" "2")
18805 (if_then_else
18806 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18807 (const_int 0))
18808 (ne (symbol_ref "optimize_size")
18809 (const_int 0)))
18810 (const_string "V4SF")
18811 (const_string "V2DF"))]
18812 (const_string "V2DF")))])
18813
18814 (define_insn "movv8hi_internal"
18815 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18816 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18817 "TARGET_SSE2
18818 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18819 {
18820 switch (which_alternative)
18821 {
18822 case 0:
18823 if (get_attr_mode (insn) == MODE_V4SF)
18824 return "xorps\t%0, %0";
18825 else
18826 return "pxor\t%0, %0";
18827 case 1:
18828 case 2:
18829 if (get_attr_mode (insn) == MODE_V4SF)
18830 return "movaps\t{%1, %0|%0, %1}";
18831 else
18832 return "movdqa\t{%1, %0|%0, %1}";
18833 default:
18834 abort ();
18835 }
18836 }
18837 [(set_attr "type" "ssemov")
18838 (set (attr "mode")
18839 (cond [(eq_attr "alternative" "0,1")
18840 (if_then_else
18841 (ne (symbol_ref "optimize_size")
18842 (const_int 0))
18843 (const_string "V4SF")
18844 (const_string "TI"))
18845 (eq_attr "alternative" "2")
18846 (if_then_else
18847 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18848 (const_int 0))
18849 (ne (symbol_ref "optimize_size")
18850 (const_int 0)))
18851 (const_string "V4SF")
18852 (const_string "TI"))]
18853 (const_string "TI")))])
18854
18855 (define_insn "movv16qi_internal"
18856 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18857 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18858 "TARGET_SSE2
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")
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 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18889 (const_int 0))
18890 (ne (symbol_ref "optimize_size")
18891 (const_int 0)))
18892 (const_string "V4SF")
18893 (const_string "TI"))]
18894 (const_string "TI")))])
18895
18896 (define_expand "movv2df"
18897 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18898 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18899 "TARGET_SSE2"
18900 {
18901 ix86_expand_vector_move (V2DFmode, operands);
18902 DONE;
18903 })
18904
18905 (define_expand "movv8hi"
18906 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18907 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18908 "TARGET_SSE2"
18909 {
18910 ix86_expand_vector_move (V8HImode, operands);
18911 DONE;
18912 })
18913
18914 (define_expand "movv16qi"
18915 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18916 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18917 "TARGET_SSE2"
18918 {
18919 ix86_expand_vector_move (V16QImode, operands);
18920 DONE;
18921 })
18922
18923 (define_expand "movv4sf"
18924 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18925 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18926 "TARGET_SSE"
18927 {
18928 ix86_expand_vector_move (V4SFmode, operands);
18929 DONE;
18930 })
18931
18932 (define_expand "movv4si"
18933 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18934 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18935 "TARGET_SSE"
18936 {
18937 ix86_expand_vector_move (V4SImode, operands);
18938 DONE;
18939 })
18940
18941 (define_expand "movv2di"
18942 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18943 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18944 "TARGET_SSE"
18945 {
18946 ix86_expand_vector_move (V2DImode, operands);
18947 DONE;
18948 })
18949
18950 (define_expand "movv2si"
18951 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18952 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18953 "TARGET_MMX"
18954 {
18955 ix86_expand_vector_move (V2SImode, operands);
18956 DONE;
18957 })
18958
18959 (define_expand "movv4hi"
18960 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18961 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18962 "TARGET_MMX"
18963 {
18964 ix86_expand_vector_move (V4HImode, operands);
18965 DONE;
18966 })
18967
18968 (define_expand "movv8qi"
18969 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18970 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18971 "TARGET_MMX"
18972 {
18973 ix86_expand_vector_move (V8QImode, operands);
18974 DONE;
18975 })
18976
18977 (define_expand "movv2sf"
18978 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18979 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18980 "TARGET_3DNOW"
18981 {
18982 ix86_expand_vector_move (V2SFmode, operands);
18983 DONE;
18984 })
18985
18986 (define_insn "*pushti"
18987 [(set (match_operand:TI 0 "push_operand" "=<")
18988 (match_operand:TI 1 "register_operand" "x"))]
18989 "TARGET_SSE"
18990 "#")
18991
18992 (define_insn "*pushv2df"
18993 [(set (match_operand:V2DF 0 "push_operand" "=<")
18994 (match_operand:V2DF 1 "register_operand" "x"))]
18995 "TARGET_SSE"
18996 "#")
18997
18998 (define_insn "*pushv2di"
18999 [(set (match_operand:V2DI 0 "push_operand" "=<")
19000 (match_operand:V2DI 1 "register_operand" "x"))]
19001 "TARGET_SSE2"
19002 "#")
19003
19004 (define_insn "*pushv8hi"
19005 [(set (match_operand:V8HI 0 "push_operand" "=<")
19006 (match_operand:V8HI 1 "register_operand" "x"))]
19007 "TARGET_SSE2"
19008 "#")
19009
19010 (define_insn "*pushv16qi"
19011 [(set (match_operand:V16QI 0 "push_operand" "=<")
19012 (match_operand:V16QI 1 "register_operand" "x"))]
19013 "TARGET_SSE2"
19014 "#")
19015
19016 (define_insn "*pushv4sf"
19017 [(set (match_operand:V4SF 0 "push_operand" "=<")
19018 (match_operand:V4SF 1 "register_operand" "x"))]
19019 "TARGET_SSE"
19020 "#")
19021
19022 (define_insn "*pushv4si"
19023 [(set (match_operand:V4SI 0 "push_operand" "=<")
19024 (match_operand:V4SI 1 "register_operand" "x"))]
19025 "TARGET_SSE2"
19026 "#")
19027
19028 (define_insn "*pushv2si"
19029 [(set (match_operand:V2SI 0 "push_operand" "=<")
19030 (match_operand:V2SI 1 "register_operand" "y"))]
19031 "TARGET_MMX"
19032 "#")
19033
19034 (define_insn "*pushv4hi"
19035 [(set (match_operand:V4HI 0 "push_operand" "=<")
19036 (match_operand:V4HI 1 "register_operand" "y"))]
19037 "TARGET_MMX"
19038 "#")
19039
19040 (define_insn "*pushv8qi"
19041 [(set (match_operand:V8QI 0 "push_operand" "=<")
19042 (match_operand:V8QI 1 "register_operand" "y"))]
19043 "TARGET_MMX"
19044 "#")
19045
19046 (define_insn "*pushv2sf"
19047 [(set (match_operand:V2SF 0 "push_operand" "=<")
19048 (match_operand:V2SF 1 "register_operand" "y"))]
19049 "TARGET_3DNOW"
19050 "#")
19051
19052 (define_split
19053 [(set (match_operand 0 "push_operand" "")
19054 (match_operand 1 "register_operand" ""))]
19055 "!TARGET_64BIT && reload_completed
19056 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19057 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19058 (set (match_dup 2) (match_dup 1))]
19059 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19060 stack_pointer_rtx);
19061 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19062
19063 (define_split
19064 [(set (match_operand 0 "push_operand" "")
19065 (match_operand 1 "register_operand" ""))]
19066 "TARGET_64BIT && reload_completed
19067 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19068 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19069 (set (match_dup 2) (match_dup 1))]
19070 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19071 stack_pointer_rtx);
19072 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19073
19074
19075 (define_insn "movti_internal"
19076 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19077 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19078 "TARGET_SSE && !TARGET_64BIT
19079 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19080 {
19081 switch (which_alternative)
19082 {
19083 case 0:
19084 if (get_attr_mode (insn) == MODE_V4SF)
19085 return "xorps\t%0, %0";
19086 else
19087 return "pxor\t%0, %0";
19088 case 1:
19089 case 2:
19090 if (get_attr_mode (insn) == MODE_V4SF)
19091 return "movaps\t{%1, %0|%0, %1}";
19092 else
19093 return "movdqa\t{%1, %0|%0, %1}";
19094 default:
19095 abort ();
19096 }
19097 }
19098 [(set_attr "type" "ssemov,ssemov,ssemov")
19099 (set (attr "mode")
19100 (cond [(eq_attr "alternative" "0,1")
19101 (if_then_else
19102 (ne (symbol_ref "optimize_size")
19103 (const_int 0))
19104 (const_string "V4SF")
19105 (const_string "TI"))
19106 (eq_attr "alternative" "2")
19107 (if_then_else
19108 (ne (symbol_ref "optimize_size")
19109 (const_int 0))
19110 (const_string "V4SF")
19111 (const_string "TI"))]
19112 (const_string "TI")))])
19113
19114 (define_insn "*movti_rex64"
19115 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19116 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19117 "TARGET_64BIT
19118 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19119 {
19120 switch (which_alternative)
19121 {
19122 case 0:
19123 case 1:
19124 return "#";
19125 case 2:
19126 if (get_attr_mode (insn) == MODE_V4SF)
19127 return "xorps\t%0, %0";
19128 else
19129 return "pxor\t%0, %0";
19130 case 3:
19131 case 4:
19132 if (get_attr_mode (insn) == MODE_V4SF)
19133 return "movaps\t{%1, %0|%0, %1}";
19134 else
19135 return "movdqa\t{%1, %0|%0, %1}";
19136 default:
19137 abort ();
19138 }
19139 }
19140 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19141 (set (attr "mode")
19142 (cond [(eq_attr "alternative" "2,3")
19143 (if_then_else
19144 (ne (symbol_ref "optimize_size")
19145 (const_int 0))
19146 (const_string "V4SF")
19147 (const_string "TI"))
19148 (eq_attr "alternative" "4")
19149 (if_then_else
19150 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19151 (const_int 0))
19152 (ne (symbol_ref "optimize_size")
19153 (const_int 0)))
19154 (const_string "V4SF")
19155 (const_string "TI"))]
19156 (const_string "DI")))])
19157
19158 (define_insn "*movtf_rex64"
19159 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
19160 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
19161 "TARGET_64BIT
19162 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19163 {
19164 switch (which_alternative)
19165 {
19166 case 0:
19167 case 1:
19168 return "#";
19169 case 2:
19170 if (get_attr_mode (insn) == MODE_V4SF)
19171 return "xorps\t%0, %0";
19172 else
19173 return "pxor\t%0, %0";
19174 case 3:
19175 case 4:
19176 if (get_attr_mode (insn) == MODE_V4SF)
19177 return "movaps\t{%1, %0|%0, %1}";
19178 else
19179 return "movdqa\t{%1, %0|%0, %1}";
19180 default:
19181 abort ();
19182 }
19183 }
19184 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19185 (set (attr "mode")
19186 (cond [(eq_attr "alternative" "2,3")
19187 (if_then_else
19188 (ne (symbol_ref "optimize_size")
19189 (const_int 0))
19190 (const_string "V4SF")
19191 (const_string "TI"))
19192 (eq_attr "alternative" "4")
19193 (if_then_else
19194 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19195 (const_int 0))
19196 (ne (symbol_ref "optimize_size")
19197 (const_int 0)))
19198 (const_string "V4SF")
19199 (const_string "TI"))]
19200 (const_string "DI")))])
19201
19202 (define_split
19203 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19204 (match_operand:TI 1 "general_operand" ""))]
19205 "reload_completed && !SSE_REG_P (operands[0])
19206 && !SSE_REG_P (operands[1])"
19207 [(const_int 0)]
19208 "ix86_split_long_move (operands); DONE;")
19209
19210 (define_split
19211 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19212 (match_operand:TF 1 "general_operand" ""))]
19213 "reload_completed && !SSE_REG_P (operands[0])
19214 && !SSE_REG_P (operands[1])"
19215 [(const_int 0)]
19216 "ix86_split_long_move (operands); DONE;")
19217
19218 ;; These two patterns are useful for specifying exactly whether to use
19219 ;; movaps or movups
19220 (define_expand "sse_movaps"
19221 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19222 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19223 UNSPEC_MOVA))]
19224 "TARGET_SSE"
19225 {
19226 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19227 {
19228 rtx tmp = gen_reg_rtx (V4SFmode);
19229 emit_insn (gen_sse_movaps (tmp, operands[1]));
19230 emit_move_insn (operands[0], tmp);
19231 DONE;
19232 }
19233 })
19234
19235 (define_insn "*sse_movaps_1"
19236 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19237 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19238 UNSPEC_MOVA))]
19239 "TARGET_SSE
19240 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19241 "movaps\t{%1, %0|%0, %1}"
19242 [(set_attr "type" "ssemov,ssemov")
19243 (set_attr "mode" "V4SF")])
19244
19245 (define_expand "sse_movups"
19246 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19247 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19248 UNSPEC_MOVU))]
19249 "TARGET_SSE"
19250 {
19251 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19252 {
19253 rtx tmp = gen_reg_rtx (V4SFmode);
19254 emit_insn (gen_sse_movups (tmp, operands[1]));
19255 emit_move_insn (operands[0], tmp);
19256 DONE;
19257 }
19258 })
19259
19260 (define_insn "*sse_movups_1"
19261 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19262 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19263 UNSPEC_MOVU))]
19264 "TARGET_SSE
19265 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19266 "movups\t{%1, %0|%0, %1}"
19267 [(set_attr "type" "ssecvt,ssecvt")
19268 (set_attr "mode" "V4SF")])
19269
19270 ;; SSE Strange Moves.
19271
19272 (define_insn "sse_movmskps"
19273 [(set (match_operand:SI 0 "register_operand" "=r")
19274 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19275 UNSPEC_MOVMSK))]
19276 "TARGET_SSE"
19277 "movmskps\t{%1, %0|%0, %1}"
19278 [(set_attr "type" "ssecvt")
19279 (set_attr "mode" "V4SF")])
19280
19281 (define_insn "mmx_pmovmskb"
19282 [(set (match_operand:SI 0 "register_operand" "=r")
19283 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19284 UNSPEC_MOVMSK))]
19285 "TARGET_SSE || TARGET_3DNOW_A"
19286 "pmovmskb\t{%1, %0|%0, %1}"
19287 [(set_attr "type" "ssecvt")
19288 (set_attr "mode" "V4SF")])
19289
19290
19291 (define_insn "mmx_maskmovq"
19292 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19293 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19294 (match_operand:V8QI 2 "register_operand" "y")]
19295 UNSPEC_MASKMOV))]
19296 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19297 ;; @@@ check ordering of operands in intel/nonintel syntax
19298 "maskmovq\t{%2, %1|%1, %2}"
19299 [(set_attr "type" "mmxcvt")
19300 (set_attr "mode" "DI")])
19301
19302 (define_insn "mmx_maskmovq_rex"
19303 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19304 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19305 (match_operand:V8QI 2 "register_operand" "y")]
19306 UNSPEC_MASKMOV))]
19307 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19308 ;; @@@ check ordering of operands in intel/nonintel syntax
19309 "maskmovq\t{%2, %1|%1, %2}"
19310 [(set_attr "type" "mmxcvt")
19311 (set_attr "mode" "DI")])
19312
19313 (define_insn "sse_movntv4sf"
19314 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19315 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19316 UNSPEC_MOVNT))]
19317 "TARGET_SSE"
19318 "movntps\t{%1, %0|%0, %1}"
19319 [(set_attr "type" "ssemov")
19320 (set_attr "mode" "V4SF")])
19321
19322 (define_insn "sse_movntdi"
19323 [(set (match_operand:DI 0 "memory_operand" "=m")
19324 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19325 UNSPEC_MOVNT))]
19326 "TARGET_SSE || TARGET_3DNOW_A"
19327 "movntq\t{%1, %0|%0, %1}"
19328 [(set_attr "type" "mmxmov")
19329 (set_attr "mode" "DI")])
19330
19331 (define_insn "sse_movhlps"
19332 [(set (match_operand:V4SF 0 "register_operand" "=x")
19333 (vec_merge:V4SF
19334 (match_operand:V4SF 1 "register_operand" "0")
19335 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19336 (parallel [(const_int 2)
19337 (const_int 3)
19338 (const_int 0)
19339 (const_int 1)]))
19340 (const_int 3)))]
19341 "TARGET_SSE"
19342 "movhlps\t{%2, %0|%0, %2}"
19343 [(set_attr "type" "ssecvt")
19344 (set_attr "mode" "V4SF")])
19345
19346 (define_insn "sse_movlhps"
19347 [(set (match_operand:V4SF 0 "register_operand" "=x")
19348 (vec_merge:V4SF
19349 (match_operand:V4SF 1 "register_operand" "0")
19350 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19351 (parallel [(const_int 2)
19352 (const_int 3)
19353 (const_int 0)
19354 (const_int 1)]))
19355 (const_int 12)))]
19356 "TARGET_SSE"
19357 "movlhps\t{%2, %0|%0, %2}"
19358 [(set_attr "type" "ssecvt")
19359 (set_attr "mode" "V4SF")])
19360
19361 (define_insn "sse_movhps"
19362 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19363 (vec_merge:V4SF
19364 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19365 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19366 (const_int 12)))]
19367 "TARGET_SSE
19368 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19369 "movhps\t{%2, %0|%0, %2}"
19370 [(set_attr "type" "ssecvt")
19371 (set_attr "mode" "V4SF")])
19372
19373 (define_insn "sse_movlps"
19374 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19375 (vec_merge:V4SF
19376 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19377 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19378 (const_int 3)))]
19379 "TARGET_SSE
19380 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19381 "movlps\t{%2, %0|%0, %2}"
19382 [(set_attr "type" "ssecvt")
19383 (set_attr "mode" "V4SF")])
19384
19385 (define_expand "sse_loadss"
19386 [(match_operand:V4SF 0 "register_operand" "")
19387 (match_operand:SF 1 "memory_operand" "")]
19388 "TARGET_SSE"
19389 {
19390 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19391 CONST0_RTX (V4SFmode)));
19392 DONE;
19393 })
19394
19395 (define_insn "sse_loadss_1"
19396 [(set (match_operand:V4SF 0 "register_operand" "=x")
19397 (vec_merge:V4SF
19398 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19399 (match_operand:V4SF 2 "const0_operand" "X")
19400 (const_int 1)))]
19401 "TARGET_SSE"
19402 "movss\t{%1, %0|%0, %1}"
19403 [(set_attr "type" "ssemov")
19404 (set_attr "mode" "SF")])
19405
19406 (define_insn "sse_movss"
19407 [(set (match_operand:V4SF 0 "register_operand" "=x")
19408 (vec_merge:V4SF
19409 (match_operand:V4SF 1 "register_operand" "0")
19410 (match_operand:V4SF 2 "register_operand" "x")
19411 (const_int 1)))]
19412 "TARGET_SSE"
19413 "movss\t{%2, %0|%0, %2}"
19414 [(set_attr "type" "ssemov")
19415 (set_attr "mode" "SF")])
19416
19417 (define_insn "sse_storess"
19418 [(set (match_operand:SF 0 "memory_operand" "=m")
19419 (vec_select:SF
19420 (match_operand:V4SF 1 "register_operand" "x")
19421 (parallel [(const_int 0)])))]
19422 "TARGET_SSE"
19423 "movss\t{%1, %0|%0, %1}"
19424 [(set_attr "type" "ssemov")
19425 (set_attr "mode" "SF")])
19426
19427 (define_insn "sse_shufps"
19428 [(set (match_operand:V4SF 0 "register_operand" "=x")
19429 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19430 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19431 (match_operand:SI 3 "immediate_operand" "i")]
19432 UNSPEC_SHUFFLE))]
19433 "TARGET_SSE"
19434 ;; @@@ check operand order for intel/nonintel syntax
19435 "shufps\t{%3, %2, %0|%0, %2, %3}"
19436 [(set_attr "type" "ssecvt")
19437 (set_attr "mode" "V4SF")])
19438
19439
19440 ;; SSE arithmetic
19441
19442 (define_insn "addv4sf3"
19443 [(set (match_operand:V4SF 0 "register_operand" "=x")
19444 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19445 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19446 "TARGET_SSE"
19447 "addps\t{%2, %0|%0, %2}"
19448 [(set_attr "type" "sseadd")
19449 (set_attr "mode" "V4SF")])
19450
19451 (define_insn "vmaddv4sf3"
19452 [(set (match_operand:V4SF 0 "register_operand" "=x")
19453 (vec_merge:V4SF
19454 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19455 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19456 (match_dup 1)
19457 (const_int 1)))]
19458 "TARGET_SSE"
19459 "addss\t{%2, %0|%0, %2}"
19460 [(set_attr "type" "sseadd")
19461 (set_attr "mode" "SF")])
19462
19463 (define_insn "subv4sf3"
19464 [(set (match_operand:V4SF 0 "register_operand" "=x")
19465 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19466 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19467 "TARGET_SSE"
19468 "subps\t{%2, %0|%0, %2}"
19469 [(set_attr "type" "sseadd")
19470 (set_attr "mode" "V4SF")])
19471
19472 (define_insn "vmsubv4sf3"
19473 [(set (match_operand:V4SF 0 "register_operand" "=x")
19474 (vec_merge:V4SF
19475 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19476 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19477 (match_dup 1)
19478 (const_int 1)))]
19479 "TARGET_SSE"
19480 "subss\t{%2, %0|%0, %2}"
19481 [(set_attr "type" "sseadd")
19482 (set_attr "mode" "SF")])
19483
19484 (define_insn "mulv4sf3"
19485 [(set (match_operand:V4SF 0 "register_operand" "=x")
19486 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19487 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19488 "TARGET_SSE"
19489 "mulps\t{%2, %0|%0, %2}"
19490 [(set_attr "type" "ssemul")
19491 (set_attr "mode" "V4SF")])
19492
19493 (define_insn "vmmulv4sf3"
19494 [(set (match_operand:V4SF 0 "register_operand" "=x")
19495 (vec_merge:V4SF
19496 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19497 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19498 (match_dup 1)
19499 (const_int 1)))]
19500 "TARGET_SSE"
19501 "mulss\t{%2, %0|%0, %2}"
19502 [(set_attr "type" "ssemul")
19503 (set_attr "mode" "SF")])
19504
19505 (define_insn "divv4sf3"
19506 [(set (match_operand:V4SF 0 "register_operand" "=x")
19507 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19508 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19509 "TARGET_SSE"
19510 "divps\t{%2, %0|%0, %2}"
19511 [(set_attr "type" "ssediv")
19512 (set_attr "mode" "V4SF")])
19513
19514 (define_insn "vmdivv4sf3"
19515 [(set (match_operand:V4SF 0 "register_operand" "=x")
19516 (vec_merge:V4SF
19517 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19518 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19519 (match_dup 1)
19520 (const_int 1)))]
19521 "TARGET_SSE"
19522 "divss\t{%2, %0|%0, %2}"
19523 [(set_attr "type" "ssediv")
19524 (set_attr "mode" "SF")])
19525
19526
19527 ;; SSE square root/reciprocal
19528
19529 (define_insn "rcpv4sf2"
19530 [(set (match_operand:V4SF 0 "register_operand" "=x")
19531 (unspec:V4SF
19532 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19533 "TARGET_SSE"
19534 "rcpps\t{%1, %0|%0, %1}"
19535 [(set_attr "type" "sse")
19536 (set_attr "mode" "V4SF")])
19537
19538 (define_insn "vmrcpv4sf2"
19539 [(set (match_operand:V4SF 0 "register_operand" "=x")
19540 (vec_merge:V4SF
19541 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19542 UNSPEC_RCP)
19543 (match_operand:V4SF 2 "register_operand" "0")
19544 (const_int 1)))]
19545 "TARGET_SSE"
19546 "rcpss\t{%1, %0|%0, %1}"
19547 [(set_attr "type" "sse")
19548 (set_attr "mode" "SF")])
19549
19550 (define_insn "rsqrtv4sf2"
19551 [(set (match_operand:V4SF 0 "register_operand" "=x")
19552 (unspec:V4SF
19553 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19554 "TARGET_SSE"
19555 "rsqrtps\t{%1, %0|%0, %1}"
19556 [(set_attr "type" "sse")
19557 (set_attr "mode" "V4SF")])
19558
19559 (define_insn "vmrsqrtv4sf2"
19560 [(set (match_operand:V4SF 0 "register_operand" "=x")
19561 (vec_merge:V4SF
19562 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19563 UNSPEC_RSQRT)
19564 (match_operand:V4SF 2 "register_operand" "0")
19565 (const_int 1)))]
19566 "TARGET_SSE"
19567 "rsqrtss\t{%1, %0|%0, %1}"
19568 [(set_attr "type" "sse")
19569 (set_attr "mode" "SF")])
19570
19571 (define_insn "sqrtv4sf2"
19572 [(set (match_operand:V4SF 0 "register_operand" "=x")
19573 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19574 "TARGET_SSE"
19575 "sqrtps\t{%1, %0|%0, %1}"
19576 [(set_attr "type" "sse")
19577 (set_attr "mode" "V4SF")])
19578
19579 (define_insn "vmsqrtv4sf2"
19580 [(set (match_operand:V4SF 0 "register_operand" "=x")
19581 (vec_merge:V4SF
19582 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19583 (match_operand:V4SF 2 "register_operand" "0")
19584 (const_int 1)))]
19585 "TARGET_SSE"
19586 "sqrtss\t{%1, %0|%0, %1}"
19587 [(set_attr "type" "sse")
19588 (set_attr "mode" "SF")])
19589
19590 ;; SSE logical operations.
19591
19592 ;; SSE defines logical operations on floating point values. This brings
19593 ;; interesting challenge to RTL representation where logicals are only valid
19594 ;; on integral types. We deal with this by representing the floating point
19595 ;; logical as logical on arguments casted to TImode as this is what hardware
19596 ;; really does. Unfortunately hardware requires the type information to be
19597 ;; present and thus we must avoid subregs from being simplified and eliminated
19598 ;; in later compilation phases.
19599 ;;
19600 ;; We have following variants from each instruction:
19601 ;; sse_andsf3 - the operation taking V4SF vector operands
19602 ;; and doing TImode cast on them
19603 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19604 ;; TImode, since backend insist on eliminating casts
19605 ;; on memory operands
19606 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19607 ;; We can not accept memory operand here as instruction reads
19608 ;; whole scalar. This is generated only post reload by GCC
19609 ;; scalar float operations that expands to logicals (fabs)
19610 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19611 ;; memory operand. Eventually combine can be able
19612 ;; to synthesize these using splitter.
19613 ;; sse2_anddf3, *sse2_anddf3_memory
19614 ;;
19615 ;;
19616 ;; These are not called andti3 etc. because we really really don't want
19617 ;; the compiler to widen DImode ands to TImode ands and then try to move
19618 ;; into DImode subregs of SSE registers, and them together, and move out
19619 ;; of DImode subregs again!
19620 ;; SSE1 single precision floating point logical operation
19621 (define_expand "sse_andv4sf3"
19622 [(set (match_operand:V4SF 0 "register_operand" "")
19623 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
19624 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19625 "TARGET_SSE"
19626 "")
19627
19628 (define_insn "*sse_andv4sf3"
19629 [(set (match_operand:V4SF 0 "register_operand" "=x")
19630 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19631 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19632 "TARGET_SSE
19633 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19634 "andps\t{%2, %0|%0, %2}"
19635 [(set_attr "type" "sselog")
19636 (set_attr "mode" "V4SF")])
19637
19638 (define_expand "sse_nandv4sf3"
19639 [(set (match_operand:V4SF 0 "register_operand" "")
19640 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
19641 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19642 "TARGET_SSE"
19643 "")
19644
19645 (define_insn "*sse_nandv4sf3"
19646 [(set (match_operand:V4SF 0 "register_operand" "=x")
19647 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
19648 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19649 "TARGET_SSE"
19650 "andnps\t{%2, %0|%0, %2}"
19651 [(set_attr "type" "sselog")
19652 (set_attr "mode" "V4SF")])
19653
19654 (define_expand "sse_iorv4sf3"
19655 [(set (match_operand:V4SF 0 "register_operand" "")
19656 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
19657 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19658 "TARGET_SSE"
19659 "")
19660
19661 (define_insn "*sse_iorv4sf3"
19662 [(set (match_operand:V4SF 0 "register_operand" "=x")
19663 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19664 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19665 "TARGET_SSE
19666 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19667 "orps\t{%2, %0|%0, %2}"
19668 [(set_attr "type" "sselog")
19669 (set_attr "mode" "V4SF")])
19670
19671 (define_expand "sse_xorv4sf3"
19672 [(set (match_operand:V4SF 0 "register_operand" "")
19673 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
19674 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
19675 "TARGET_SSE"
19676 "")
19677
19678 (define_insn "*sse_xorv4sf3"
19679 [(set (match_operand:V4SF 0 "register_operand" "=x")
19680 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
19681 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19682 "TARGET_SSE
19683 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19684 "xorps\t{%2, %0|%0, %2}"
19685 [(set_attr "type" "sselog")
19686 (set_attr "mode" "V4SF")])
19687
19688 ;; SSE2 double precision floating point logical operation
19689
19690 (define_expand "sse2_andv2df3"
19691 [(set (match_operand:V2DF 0 "register_operand" "")
19692 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
19693 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19694 "TARGET_SSE2"
19695 "")
19696
19697 (define_insn "*sse2_andv2df3"
19698 [(set (match_operand:V2DF 0 "register_operand" "=x")
19699 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19700 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19701 "TARGET_SSE2
19702 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19703 "andpd\t{%2, %0|%0, %2}"
19704 [(set_attr "type" "sselog")
19705 (set_attr "mode" "V2DF")])
19706
19707 (define_expand "sse2_nandv2df3"
19708 [(set (match_operand:V2DF 0 "register_operand" "")
19709 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
19710 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19711 "TARGET_SSE2"
19712 "")
19713
19714 (define_insn "*sse2_nandv2df3"
19715 [(set (match_operand:V2DF 0 "register_operand" "=x")
19716 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
19717 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19718 "TARGET_SSE2"
19719 "andnpd\t{%2, %0|%0, %2}"
19720 [(set_attr "type" "sselog")
19721 (set_attr "mode" "V2DF")])
19722
19723 (define_expand "sse2_iorv2df3"
19724 [(set (match_operand:V2DF 0 "register_operand" "")
19725 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
19726 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19727 "TARGET_SSE2"
19728 "")
19729
19730 (define_insn "*sse2_iorv2df3"
19731 [(set (match_operand:V2DF 0 "register_operand" "=x")
19732 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19733 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19734 "TARGET_SSE2
19735 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19736 "orpd\t{%2, %0|%0, %2}"
19737 [(set_attr "type" "sselog")
19738 (set_attr "mode" "V2DF")])
19739
19740 (define_expand "sse2_xorv2df3"
19741 [(set (match_operand:V2DF 0 "register_operand" "")
19742 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
19743 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
19744 "TARGET_SSE2"
19745 "")
19746
19747 (define_insn "*sse2_xorv2df3"
19748 [(set (match_operand:V2DF 0 "register_operand" "=x")
19749 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
19750 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
19751 "TARGET_SSE2
19752 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19753 "xorpd\t{%2, %0|%0, %2}"
19754 [(set_attr "type" "sselog")
19755 (set_attr "mode" "V2DF")])
19756
19757 ;; SSE2 integral logicals. These patterns must always come after floating
19758 ;; point ones since we don't want compiler to use integer opcodes on floating
19759 ;; point SSE values to avoid matching of subregs in the match_operand.
19760 (define_insn "*sse2_andti3"
19761 [(set (match_operand:TI 0 "register_operand" "=x")
19762 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19763 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19764 "TARGET_SSE2
19765 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19766 "pand\t{%2, %0|%0, %2}"
19767 [(set_attr "type" "sselog")
19768 (set_attr "mode" "TI")])
19769
19770 (define_insn "sse2_andv2di3"
19771 [(set (match_operand:V2DI 0 "register_operand" "=x")
19772 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19773 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19774 "TARGET_SSE2
19775 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19776 "pand\t{%2, %0|%0, %2}"
19777 [(set_attr "type" "sselog")
19778 (set_attr "mode" "TI")])
19779
19780 (define_insn "*sse2_nandti3"
19781 [(set (match_operand:TI 0 "register_operand" "=x")
19782 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19783 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19784 "TARGET_SSE2"
19785 "pandn\t{%2, %0|%0, %2}"
19786 [(set_attr "type" "sselog")
19787 (set_attr "mode" "TI")])
19788
19789 (define_insn "sse2_nandv2di3"
19790 [(set (match_operand:V2DI 0 "register_operand" "=x")
19791 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19792 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19793 "TARGET_SSE2
19794 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19795 "pandn\t{%2, %0|%0, %2}"
19796 [(set_attr "type" "sselog")
19797 (set_attr "mode" "TI")])
19798
19799 (define_insn "*sse2_iorti3"
19800 [(set (match_operand:TI 0 "register_operand" "=x")
19801 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19802 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19803 "TARGET_SSE2
19804 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19805 "por\t{%2, %0|%0, %2}"
19806 [(set_attr "type" "sselog")
19807 (set_attr "mode" "TI")])
19808
19809 (define_insn "sse2_iorv2di3"
19810 [(set (match_operand:V2DI 0 "register_operand" "=x")
19811 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19812 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19813 "TARGET_SSE2
19814 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19815 "por\t{%2, %0|%0, %2}"
19816 [(set_attr "type" "sselog")
19817 (set_attr "mode" "TI")])
19818
19819 (define_insn "*sse2_xorti3"
19820 [(set (match_operand:TI 0 "register_operand" "=x")
19821 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19822 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19823 "TARGET_SSE2
19824 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19825 "pxor\t{%2, %0|%0, %2}"
19826 [(set_attr "type" "sselog")
19827 (set_attr "mode" "TI")])
19828
19829 (define_insn "sse2_xorv2di3"
19830 [(set (match_operand:V2DI 0 "register_operand" "=x")
19831 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19832 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19833 "TARGET_SSE2
19834 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19835 "pxor\t{%2, %0|%0, %2}"
19836 [(set_attr "type" "sselog")
19837 (set_attr "mode" "TI")])
19838
19839 ;; Use xor, but don't show input operands so they aren't live before
19840 ;; this insn.
19841 (define_insn "sse_clrv4sf"
19842 [(set (match_operand:V4SF 0 "register_operand" "=x")
19843 (match_operand:V4SF 1 "const0_operand" "X"))]
19844 "TARGET_SSE"
19845 {
19846 if (get_attr_mode (insn) == MODE_TI)
19847 return "pxor\t{%0, %0|%0, %0}";
19848 else
19849 return "xorps\t{%0, %0|%0, %0}";
19850 }
19851 [(set_attr "type" "sselog")
19852 (set_attr "memory" "none")
19853 (set (attr "mode")
19854 (if_then_else
19855 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19856 (const_int 0))
19857 (ne (symbol_ref "TARGET_SSE2")
19858 (const_int 0)))
19859 (eq (symbol_ref "optimize_size")
19860 (const_int 0)))
19861 (const_string "TI")
19862 (const_string "V4SF")))])
19863
19864 ;; Use xor, but don't show input operands so they aren't live before
19865 ;; this insn.
19866 (define_insn "sse_clrv2df"
19867 [(set (match_operand:V2DF 0 "register_operand" "=x")
19868 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19869 "TARGET_SSE2"
19870 "xorpd\t{%0, %0|%0, %0}"
19871 [(set_attr "type" "sselog")
19872 (set_attr "memory" "none")
19873 (set_attr "mode" "V4SF")])
19874
19875 ;; SSE mask-generating compares
19876
19877 (define_insn "maskcmpv4sf3"
19878 [(set (match_operand:V4SI 0 "register_operand" "=x")
19879 (match_operator:V4SI 3 "sse_comparison_operator"
19880 [(match_operand:V4SF 1 "register_operand" "0")
19881 (match_operand:V4SF 2 "register_operand" "x")]))]
19882 "TARGET_SSE"
19883 "cmp%D3ps\t{%2, %0|%0, %2}"
19884 [(set_attr "type" "ssecmp")
19885 (set_attr "mode" "V4SF")])
19886
19887 (define_insn "maskncmpv4sf3"
19888 [(set (match_operand:V4SI 0 "register_operand" "=x")
19889 (not:V4SI
19890 (match_operator:V4SI 3 "sse_comparison_operator"
19891 [(match_operand:V4SF 1 "register_operand" "0")
19892 (match_operand:V4SF 2 "register_operand" "x")])))]
19893 "TARGET_SSE"
19894 {
19895 if (GET_CODE (operands[3]) == UNORDERED)
19896 return "cmpordps\t{%2, %0|%0, %2}";
19897 else
19898 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19899 }
19900 [(set_attr "type" "ssecmp")
19901 (set_attr "mode" "V4SF")])
19902
19903 (define_insn "vmmaskcmpv4sf3"
19904 [(set (match_operand:V4SI 0 "register_operand" "=x")
19905 (vec_merge:V4SI
19906 (match_operator:V4SI 3 "sse_comparison_operator"
19907 [(match_operand:V4SF 1 "register_operand" "0")
19908 (match_operand:V4SF 2 "register_operand" "x")])
19909 (subreg:V4SI (match_dup 1) 0)
19910 (const_int 1)))]
19911 "TARGET_SSE"
19912 "cmp%D3ss\t{%2, %0|%0, %2}"
19913 [(set_attr "type" "ssecmp")
19914 (set_attr "mode" "SF")])
19915
19916 (define_insn "vmmaskncmpv4sf3"
19917 [(set (match_operand:V4SI 0 "register_operand" "=x")
19918 (vec_merge:V4SI
19919 (not:V4SI
19920 (match_operator:V4SI 3 "sse_comparison_operator"
19921 [(match_operand:V4SF 1 "register_operand" "0")
19922 (match_operand:V4SF 2 "register_operand" "x")]))
19923 (subreg:V4SI (match_dup 1) 0)
19924 (const_int 1)))]
19925 "TARGET_SSE"
19926 {
19927 if (GET_CODE (operands[3]) == UNORDERED)
19928 return "cmpordss\t{%2, %0|%0, %2}";
19929 else
19930 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19931 }
19932 [(set_attr "type" "ssecmp")
19933 (set_attr "mode" "SF")])
19934
19935 (define_insn "sse_comi"
19936 [(set (reg:CCFP 17)
19937 (compare:CCFP (vec_select:SF
19938 (match_operand:V4SF 0 "register_operand" "x")
19939 (parallel [(const_int 0)]))
19940 (vec_select:SF
19941 (match_operand:V4SF 1 "register_operand" "x")
19942 (parallel [(const_int 0)]))))]
19943 "TARGET_SSE"
19944 "comiss\t{%1, %0|%0, %1}"
19945 [(set_attr "type" "ssecomi")
19946 (set_attr "mode" "SF")])
19947
19948 (define_insn "sse_ucomi"
19949 [(set (reg:CCFPU 17)
19950 (compare:CCFPU (vec_select:SF
19951 (match_operand:V4SF 0 "register_operand" "x")
19952 (parallel [(const_int 0)]))
19953 (vec_select:SF
19954 (match_operand:V4SF 1 "register_operand" "x")
19955 (parallel [(const_int 0)]))))]
19956 "TARGET_SSE"
19957 "ucomiss\t{%1, %0|%0, %1}"
19958 [(set_attr "type" "ssecomi")
19959 (set_attr "mode" "SF")])
19960
19961
19962 ;; SSE unpack
19963
19964 (define_insn "sse_unpckhps"
19965 [(set (match_operand:V4SF 0 "register_operand" "=x")
19966 (vec_merge:V4SF
19967 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19968 (parallel [(const_int 2)
19969 (const_int 0)
19970 (const_int 3)
19971 (const_int 1)]))
19972 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19973 (parallel [(const_int 0)
19974 (const_int 2)
19975 (const_int 1)
19976 (const_int 3)]))
19977 (const_int 5)))]
19978 "TARGET_SSE"
19979 "unpckhps\t{%2, %0|%0, %2}"
19980 [(set_attr "type" "ssecvt")
19981 (set_attr "mode" "V4SF")])
19982
19983 (define_insn "sse_unpcklps"
19984 [(set (match_operand:V4SF 0 "register_operand" "=x")
19985 (vec_merge:V4SF
19986 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19987 (parallel [(const_int 0)
19988 (const_int 2)
19989 (const_int 1)
19990 (const_int 3)]))
19991 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19992 (parallel [(const_int 2)
19993 (const_int 0)
19994 (const_int 3)
19995 (const_int 1)]))
19996 (const_int 5)))]
19997 "TARGET_SSE"
19998 "unpcklps\t{%2, %0|%0, %2}"
19999 [(set_attr "type" "ssecvt")
20000 (set_attr "mode" "V4SF")])
20001
20002
20003 ;; SSE min/max
20004
20005 (define_insn "smaxv4sf3"
20006 [(set (match_operand:V4SF 0 "register_operand" "=x")
20007 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20008 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20009 "TARGET_SSE"
20010 "maxps\t{%2, %0|%0, %2}"
20011 [(set_attr "type" "sse")
20012 (set_attr "mode" "V4SF")])
20013
20014 (define_insn "vmsmaxv4sf3"
20015 [(set (match_operand:V4SF 0 "register_operand" "=x")
20016 (vec_merge:V4SF
20017 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20018 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20019 (match_dup 1)
20020 (const_int 1)))]
20021 "TARGET_SSE"
20022 "maxss\t{%2, %0|%0, %2}"
20023 [(set_attr "type" "sse")
20024 (set_attr "mode" "SF")])
20025
20026 (define_insn "sminv4sf3"
20027 [(set (match_operand:V4SF 0 "register_operand" "=x")
20028 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20029 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20030 "TARGET_SSE"
20031 "minps\t{%2, %0|%0, %2}"
20032 [(set_attr "type" "sse")
20033 (set_attr "mode" "V4SF")])
20034
20035 (define_insn "vmsminv4sf3"
20036 [(set (match_operand:V4SF 0 "register_operand" "=x")
20037 (vec_merge:V4SF
20038 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20039 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20040 (match_dup 1)
20041 (const_int 1)))]
20042 "TARGET_SSE"
20043 "minss\t{%2, %0|%0, %2}"
20044 [(set_attr "type" "sse")
20045 (set_attr "mode" "SF")])
20046
20047 ;; SSE <-> integer/MMX conversions
20048
20049 (define_insn "cvtpi2ps"
20050 [(set (match_operand:V4SF 0 "register_operand" "=x")
20051 (vec_merge:V4SF
20052 (match_operand:V4SF 1 "register_operand" "0")
20053 (vec_duplicate:V4SF
20054 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20055 (const_int 12)))]
20056 "TARGET_SSE"
20057 "cvtpi2ps\t{%2, %0|%0, %2}"
20058 [(set_attr "type" "ssecvt")
20059 (set_attr "mode" "V4SF")])
20060
20061 (define_insn "cvtps2pi"
20062 [(set (match_operand:V2SI 0 "register_operand" "=y")
20063 (vec_select:V2SI
20064 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20065 (parallel [(const_int 0) (const_int 1)])))]
20066 "TARGET_SSE"
20067 "cvtps2pi\t{%1, %0|%0, %1}"
20068 [(set_attr "type" "ssecvt")
20069 (set_attr "mode" "V4SF")])
20070
20071 (define_insn "cvttps2pi"
20072 [(set (match_operand:V2SI 0 "register_operand" "=y")
20073 (vec_select:V2SI
20074 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20075 UNSPEC_FIX)
20076 (parallel [(const_int 0) (const_int 1)])))]
20077 "TARGET_SSE"
20078 "cvttps2pi\t{%1, %0|%0, %1}"
20079 [(set_attr "type" "ssecvt")
20080 (set_attr "mode" "SF")])
20081
20082 (define_insn "cvtsi2ss"
20083 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20084 (vec_merge:V4SF
20085 (match_operand:V4SF 1 "register_operand" "0,0")
20086 (vec_duplicate:V4SF
20087 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20088 (const_int 14)))]
20089 "TARGET_SSE"
20090 "cvtsi2ss\t{%2, %0|%0, %2}"
20091 [(set_attr "type" "sseicvt")
20092 (set_attr "athlon_decode" "vector,double")
20093 (set_attr "mode" "SF")])
20094
20095 (define_insn "cvtsi2ssq"
20096 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20097 (vec_merge:V4SF
20098 (match_operand:V4SF 1 "register_operand" "0,0")
20099 (vec_duplicate:V4SF
20100 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20101 (const_int 14)))]
20102 "TARGET_SSE && TARGET_64BIT"
20103 "cvtsi2ssq\t{%2, %0|%0, %2}"
20104 [(set_attr "type" "sseicvt")
20105 (set_attr "athlon_decode" "vector,double")
20106 (set_attr "mode" "SF")])
20107
20108 (define_insn "cvtss2si"
20109 [(set (match_operand:SI 0 "register_operand" "=r,r")
20110 (vec_select:SI
20111 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20112 (parallel [(const_int 0)])))]
20113 "TARGET_SSE"
20114 "cvtss2si\t{%1, %0|%0, %1}"
20115 [(set_attr "type" "sseicvt")
20116 (set_attr "athlon_decode" "double,vector")
20117 (set_attr "mode" "SI")])
20118
20119 (define_insn "cvtss2siq"
20120 [(set (match_operand:DI 0 "register_operand" "=r,r")
20121 (vec_select:DI
20122 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20123 (parallel [(const_int 0)])))]
20124 "TARGET_SSE"
20125 "cvtss2siq\t{%1, %0|%0, %1}"
20126 [(set_attr "type" "sseicvt")
20127 (set_attr "athlon_decode" "double,vector")
20128 (set_attr "mode" "DI")])
20129
20130 (define_insn "cvttss2si"
20131 [(set (match_operand:SI 0 "register_operand" "=r,r")
20132 (vec_select:SI
20133 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20134 UNSPEC_FIX)
20135 (parallel [(const_int 0)])))]
20136 "TARGET_SSE"
20137 "cvttss2si\t{%1, %0|%0, %1}"
20138 [(set_attr "type" "sseicvt")
20139 (set_attr "mode" "SF")
20140 (set_attr "athlon_decode" "double,vector")])
20141
20142 (define_insn "cvttss2siq"
20143 [(set (match_operand:DI 0 "register_operand" "=r,r")
20144 (vec_select:DI
20145 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20146 UNSPEC_FIX)
20147 (parallel [(const_int 0)])))]
20148 "TARGET_SSE && TARGET_64BIT"
20149 "cvttss2siq\t{%1, %0|%0, %1}"
20150 [(set_attr "type" "sseicvt")
20151 (set_attr "mode" "SF")
20152 (set_attr "athlon_decode" "double,vector")])
20153
20154
20155 ;; MMX insns
20156
20157 ;; MMX arithmetic
20158
20159 (define_insn "addv8qi3"
20160 [(set (match_operand:V8QI 0 "register_operand" "=y")
20161 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20162 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20163 "TARGET_MMX"
20164 "paddb\t{%2, %0|%0, %2}"
20165 [(set_attr "type" "mmxadd")
20166 (set_attr "mode" "DI")])
20167
20168 (define_insn "addv4hi3"
20169 [(set (match_operand:V4HI 0 "register_operand" "=y")
20170 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20171 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20172 "TARGET_MMX"
20173 "paddw\t{%2, %0|%0, %2}"
20174 [(set_attr "type" "mmxadd")
20175 (set_attr "mode" "DI")])
20176
20177 (define_insn "addv2si3"
20178 [(set (match_operand:V2SI 0 "register_operand" "=y")
20179 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20180 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20181 "TARGET_MMX"
20182 "paddd\t{%2, %0|%0, %2}"
20183 [(set_attr "type" "mmxadd")
20184 (set_attr "mode" "DI")])
20185
20186 (define_insn "mmx_adddi3"
20187 [(set (match_operand:DI 0 "register_operand" "=y")
20188 (unspec:DI
20189 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20190 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20191 UNSPEC_NOP))]
20192 "TARGET_MMX"
20193 "paddq\t{%2, %0|%0, %2}"
20194 [(set_attr "type" "mmxadd")
20195 (set_attr "mode" "DI")])
20196
20197 (define_insn "ssaddv8qi3"
20198 [(set (match_operand:V8QI 0 "register_operand" "=y")
20199 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20200 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20201 "TARGET_MMX"
20202 "paddsb\t{%2, %0|%0, %2}"
20203 [(set_attr "type" "mmxadd")
20204 (set_attr "mode" "DI")])
20205
20206 (define_insn "ssaddv4hi3"
20207 [(set (match_operand:V4HI 0 "register_operand" "=y")
20208 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20209 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20210 "TARGET_MMX"
20211 "paddsw\t{%2, %0|%0, %2}"
20212 [(set_attr "type" "mmxadd")
20213 (set_attr "mode" "DI")])
20214
20215 (define_insn "usaddv8qi3"
20216 [(set (match_operand:V8QI 0 "register_operand" "=y")
20217 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20218 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20219 "TARGET_MMX"
20220 "paddusb\t{%2, %0|%0, %2}"
20221 [(set_attr "type" "mmxadd")
20222 (set_attr "mode" "DI")])
20223
20224 (define_insn "usaddv4hi3"
20225 [(set (match_operand:V4HI 0 "register_operand" "=y")
20226 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20227 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20228 "TARGET_MMX"
20229 "paddusw\t{%2, %0|%0, %2}"
20230 [(set_attr "type" "mmxadd")
20231 (set_attr "mode" "DI")])
20232
20233 (define_insn "subv8qi3"
20234 [(set (match_operand:V8QI 0 "register_operand" "=y")
20235 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20236 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20237 "TARGET_MMX"
20238 "psubb\t{%2, %0|%0, %2}"
20239 [(set_attr "type" "mmxadd")
20240 (set_attr "mode" "DI")])
20241
20242 (define_insn "subv4hi3"
20243 [(set (match_operand:V4HI 0 "register_operand" "=y")
20244 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20245 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20246 "TARGET_MMX"
20247 "psubw\t{%2, %0|%0, %2}"
20248 [(set_attr "type" "mmxadd")
20249 (set_attr "mode" "DI")])
20250
20251 (define_insn "subv2si3"
20252 [(set (match_operand:V2SI 0 "register_operand" "=y")
20253 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20254 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20255 "TARGET_MMX"
20256 "psubd\t{%2, %0|%0, %2}"
20257 [(set_attr "type" "mmxadd")
20258 (set_attr "mode" "DI")])
20259
20260 (define_insn "mmx_subdi3"
20261 [(set (match_operand:DI 0 "register_operand" "=y")
20262 (unspec:DI
20263 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20264 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20265 UNSPEC_NOP))]
20266 "TARGET_MMX"
20267 "psubq\t{%2, %0|%0, %2}"
20268 [(set_attr "type" "mmxadd")
20269 (set_attr "mode" "DI")])
20270
20271 (define_insn "sssubv8qi3"
20272 [(set (match_operand:V8QI 0 "register_operand" "=y")
20273 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20274 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20275 "TARGET_MMX"
20276 "psubsb\t{%2, %0|%0, %2}"
20277 [(set_attr "type" "mmxadd")
20278 (set_attr "mode" "DI")])
20279
20280 (define_insn "sssubv4hi3"
20281 [(set (match_operand:V4HI 0 "register_operand" "=y")
20282 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20283 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20284 "TARGET_MMX"
20285 "psubsw\t{%2, %0|%0, %2}"
20286 [(set_attr "type" "mmxadd")
20287 (set_attr "mode" "DI")])
20288
20289 (define_insn "ussubv8qi3"
20290 [(set (match_operand:V8QI 0 "register_operand" "=y")
20291 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20292 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20293 "TARGET_MMX"
20294 "psubusb\t{%2, %0|%0, %2}"
20295 [(set_attr "type" "mmxadd")
20296 (set_attr "mode" "DI")])
20297
20298 (define_insn "ussubv4hi3"
20299 [(set (match_operand:V4HI 0 "register_operand" "=y")
20300 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20301 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20302 "TARGET_MMX"
20303 "psubusw\t{%2, %0|%0, %2}"
20304 [(set_attr "type" "mmxadd")
20305 (set_attr "mode" "DI")])
20306
20307 (define_insn "mulv4hi3"
20308 [(set (match_operand:V4HI 0 "register_operand" "=y")
20309 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20310 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20311 "TARGET_MMX"
20312 "pmullw\t{%2, %0|%0, %2}"
20313 [(set_attr "type" "mmxmul")
20314 (set_attr "mode" "DI")])
20315
20316 (define_insn "smulv4hi3_highpart"
20317 [(set (match_operand:V4HI 0 "register_operand" "=y")
20318 (truncate:V4HI
20319 (lshiftrt:V4SI
20320 (mult:V4SI (sign_extend:V4SI
20321 (match_operand:V4HI 1 "register_operand" "0"))
20322 (sign_extend:V4SI
20323 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20324 (const_int 16))))]
20325 "TARGET_MMX"
20326 "pmulhw\t{%2, %0|%0, %2}"
20327 [(set_attr "type" "mmxmul")
20328 (set_attr "mode" "DI")])
20329
20330 (define_insn "umulv4hi3_highpart"
20331 [(set (match_operand:V4HI 0 "register_operand" "=y")
20332 (truncate:V4HI
20333 (lshiftrt:V4SI
20334 (mult:V4SI (zero_extend:V4SI
20335 (match_operand:V4HI 1 "register_operand" "0"))
20336 (zero_extend:V4SI
20337 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20338 (const_int 16))))]
20339 "TARGET_SSE || TARGET_3DNOW_A"
20340 "pmulhuw\t{%2, %0|%0, %2}"
20341 [(set_attr "type" "mmxmul")
20342 (set_attr "mode" "DI")])
20343
20344 (define_insn "mmx_pmaddwd"
20345 [(set (match_operand:V2SI 0 "register_operand" "=y")
20346 (plus:V2SI
20347 (mult:V2SI
20348 (sign_extend:V2SI
20349 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20350 (parallel [(const_int 0) (const_int 2)])))
20351 (sign_extend:V2SI
20352 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20353 (parallel [(const_int 0) (const_int 2)]))))
20354 (mult:V2SI
20355 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20356 (parallel [(const_int 1)
20357 (const_int 3)])))
20358 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20359 (parallel [(const_int 1)
20360 (const_int 3)]))))))]
20361 "TARGET_MMX"
20362 "pmaddwd\t{%2, %0|%0, %2}"
20363 [(set_attr "type" "mmxmul")
20364 (set_attr "mode" "DI")])
20365
20366
20367 ;; MMX logical operations
20368 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20369 ;; normal code that also wants to use the FPU from getting broken.
20370 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20371 (define_insn "mmx_iordi3"
20372 [(set (match_operand:DI 0 "register_operand" "=y")
20373 (unspec:DI
20374 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20375 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20376 UNSPEC_NOP))]
20377 "TARGET_MMX"
20378 "por\t{%2, %0|%0, %2}"
20379 [(set_attr "type" "mmxadd")
20380 (set_attr "mode" "DI")])
20381
20382 (define_insn "mmx_xordi3"
20383 [(set (match_operand:DI 0 "register_operand" "=y")
20384 (unspec:DI
20385 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20386 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20387 UNSPEC_NOP))]
20388 "TARGET_MMX"
20389 "pxor\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "mmxadd")
20391 (set_attr "mode" "DI")
20392 (set_attr "memory" "none")])
20393
20394 ;; Same as pxor, but don't show input operands so that we don't think
20395 ;; they are live.
20396 (define_insn "mmx_clrdi"
20397 [(set (match_operand:DI 0 "register_operand" "=y")
20398 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20399 "TARGET_MMX"
20400 "pxor\t{%0, %0|%0, %0}"
20401 [(set_attr "type" "mmxadd")
20402 (set_attr "mode" "DI")
20403 (set_attr "memory" "none")])
20404
20405 (define_insn "mmx_anddi3"
20406 [(set (match_operand:DI 0 "register_operand" "=y")
20407 (unspec:DI
20408 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20409 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20410 UNSPEC_NOP))]
20411 "TARGET_MMX"
20412 "pand\t{%2, %0|%0, %2}"
20413 [(set_attr "type" "mmxadd")
20414 (set_attr "mode" "DI")])
20415
20416 (define_insn "mmx_nanddi3"
20417 [(set (match_operand:DI 0 "register_operand" "=y")
20418 (unspec:DI
20419 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20420 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20421 UNSPEC_NOP))]
20422 "TARGET_MMX"
20423 "pandn\t{%2, %0|%0, %2}"
20424 [(set_attr "type" "mmxadd")
20425 (set_attr "mode" "DI")])
20426
20427
20428 ;; MMX unsigned averages/sum of absolute differences
20429
20430 (define_insn "mmx_uavgv8qi3"
20431 [(set (match_operand:V8QI 0 "register_operand" "=y")
20432 (ashiftrt:V8QI
20433 (plus:V8QI (plus:V8QI
20434 (match_operand:V8QI 1 "register_operand" "0")
20435 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20436 (const_vector:V8QI [(const_int 1)
20437 (const_int 1)
20438 (const_int 1)
20439 (const_int 1)
20440 (const_int 1)
20441 (const_int 1)
20442 (const_int 1)
20443 (const_int 1)]))
20444 (const_int 1)))]
20445 "TARGET_SSE || TARGET_3DNOW_A"
20446 "pavgb\t{%2, %0|%0, %2}"
20447 [(set_attr "type" "mmxshft")
20448 (set_attr "mode" "DI")])
20449
20450 (define_insn "mmx_uavgv4hi3"
20451 [(set (match_operand:V4HI 0 "register_operand" "=y")
20452 (ashiftrt:V4HI
20453 (plus:V4HI (plus:V4HI
20454 (match_operand:V4HI 1 "register_operand" "0")
20455 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20456 (const_vector:V4HI [(const_int 1)
20457 (const_int 1)
20458 (const_int 1)
20459 (const_int 1)]))
20460 (const_int 1)))]
20461 "TARGET_SSE || TARGET_3DNOW_A"
20462 "pavgw\t{%2, %0|%0, %2}"
20463 [(set_attr "type" "mmxshft")
20464 (set_attr "mode" "DI")])
20465
20466 (define_insn "mmx_psadbw"
20467 [(set (match_operand:DI 0 "register_operand" "=y")
20468 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20469 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20470 UNSPEC_PSADBW))]
20471 "TARGET_SSE || TARGET_3DNOW_A"
20472 "psadbw\t{%2, %0|%0, %2}"
20473 [(set_attr "type" "mmxshft")
20474 (set_attr "mode" "DI")])
20475
20476
20477 ;; MMX insert/extract/shuffle
20478
20479 (define_insn "mmx_pinsrw"
20480 [(set (match_operand:V4HI 0 "register_operand" "=y")
20481 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20482 (vec_duplicate:V4HI
20483 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20484 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20485 "TARGET_SSE || TARGET_3DNOW_A"
20486 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20487 [(set_attr "type" "mmxcvt")
20488 (set_attr "mode" "DI")])
20489
20490 (define_insn "mmx_pextrw"
20491 [(set (match_operand:SI 0 "register_operand" "=r")
20492 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20493 (parallel
20494 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20495 "TARGET_SSE || TARGET_3DNOW_A"
20496 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20497 [(set_attr "type" "mmxcvt")
20498 (set_attr "mode" "DI")])
20499
20500 (define_insn "mmx_pshufw"
20501 [(set (match_operand:V4HI 0 "register_operand" "=y")
20502 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20503 (match_operand:SI 2 "immediate_operand" "i")]
20504 UNSPEC_SHUFFLE))]
20505 "TARGET_SSE || TARGET_3DNOW_A"
20506 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20507 [(set_attr "type" "mmxcvt")
20508 (set_attr "mode" "DI")])
20509
20510
20511 ;; MMX mask-generating comparisons
20512
20513 (define_insn "eqv8qi3"
20514 [(set (match_operand:V8QI 0 "register_operand" "=y")
20515 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20516 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20517 "TARGET_MMX"
20518 "pcmpeqb\t{%2, %0|%0, %2}"
20519 [(set_attr "type" "mmxcmp")
20520 (set_attr "mode" "DI")])
20521
20522 (define_insn "eqv4hi3"
20523 [(set (match_operand:V4HI 0 "register_operand" "=y")
20524 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20525 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20526 "TARGET_MMX"
20527 "pcmpeqw\t{%2, %0|%0, %2}"
20528 [(set_attr "type" "mmxcmp")
20529 (set_attr "mode" "DI")])
20530
20531 (define_insn "eqv2si3"
20532 [(set (match_operand:V2SI 0 "register_operand" "=y")
20533 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20534 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20535 "TARGET_MMX"
20536 "pcmpeqd\t{%2, %0|%0, %2}"
20537 [(set_attr "type" "mmxcmp")
20538 (set_attr "mode" "DI")])
20539
20540 (define_insn "gtv8qi3"
20541 [(set (match_operand:V8QI 0 "register_operand" "=y")
20542 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20543 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20544 "TARGET_MMX"
20545 "pcmpgtb\t{%2, %0|%0, %2}"
20546 [(set_attr "type" "mmxcmp")
20547 (set_attr "mode" "DI")])
20548
20549 (define_insn "gtv4hi3"
20550 [(set (match_operand:V4HI 0 "register_operand" "=y")
20551 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20552 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20553 "TARGET_MMX"
20554 "pcmpgtw\t{%2, %0|%0, %2}"
20555 [(set_attr "type" "mmxcmp")
20556 (set_attr "mode" "DI")])
20557
20558 (define_insn "gtv2si3"
20559 [(set (match_operand:V2SI 0 "register_operand" "=y")
20560 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20561 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20562 "TARGET_MMX"
20563 "pcmpgtd\t{%2, %0|%0, %2}"
20564 [(set_attr "type" "mmxcmp")
20565 (set_attr "mode" "DI")])
20566
20567
20568 ;; MMX max/min insns
20569
20570 (define_insn "umaxv8qi3"
20571 [(set (match_operand:V8QI 0 "register_operand" "=y")
20572 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20573 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20574 "TARGET_SSE || TARGET_3DNOW_A"
20575 "pmaxub\t{%2, %0|%0, %2}"
20576 [(set_attr "type" "mmxadd")
20577 (set_attr "mode" "DI")])
20578
20579 (define_insn "smaxv4hi3"
20580 [(set (match_operand:V4HI 0 "register_operand" "=y")
20581 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20582 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20583 "TARGET_SSE || TARGET_3DNOW_A"
20584 "pmaxsw\t{%2, %0|%0, %2}"
20585 [(set_attr "type" "mmxadd")
20586 (set_attr "mode" "DI")])
20587
20588 (define_insn "uminv8qi3"
20589 [(set (match_operand:V8QI 0 "register_operand" "=y")
20590 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20591 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20592 "TARGET_SSE || TARGET_3DNOW_A"
20593 "pminub\t{%2, %0|%0, %2}"
20594 [(set_attr "type" "mmxadd")
20595 (set_attr "mode" "DI")])
20596
20597 (define_insn "sminv4hi3"
20598 [(set (match_operand:V4HI 0 "register_operand" "=y")
20599 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20600 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20601 "TARGET_SSE || TARGET_3DNOW_A"
20602 "pminsw\t{%2, %0|%0, %2}"
20603 [(set_attr "type" "mmxadd")
20604 (set_attr "mode" "DI")])
20605
20606
20607 ;; MMX shifts
20608
20609 (define_insn "ashrv4hi3"
20610 [(set (match_operand:V4HI 0 "register_operand" "=y")
20611 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20612 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20613 "TARGET_MMX"
20614 "psraw\t{%2, %0|%0, %2}"
20615 [(set_attr "type" "mmxshft")
20616 (set_attr "mode" "DI")])
20617
20618 (define_insn "ashrv2si3"
20619 [(set (match_operand:V2SI 0 "register_operand" "=y")
20620 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20621 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20622 "TARGET_MMX"
20623 "psrad\t{%2, %0|%0, %2}"
20624 [(set_attr "type" "mmxshft")
20625 (set_attr "mode" "DI")])
20626
20627 (define_insn "lshrv4hi3"
20628 [(set (match_operand:V4HI 0 "register_operand" "=y")
20629 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20630 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20631 "TARGET_MMX"
20632 "psrlw\t{%2, %0|%0, %2}"
20633 [(set_attr "type" "mmxshft")
20634 (set_attr "mode" "DI")])
20635
20636 (define_insn "lshrv2si3"
20637 [(set (match_operand:V2SI 0 "register_operand" "=y")
20638 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20639 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20640 "TARGET_MMX"
20641 "psrld\t{%2, %0|%0, %2}"
20642 [(set_attr "type" "mmxshft")
20643 (set_attr "mode" "DI")])
20644
20645 ;; See logical MMX insns.
20646 (define_insn "mmx_lshrdi3"
20647 [(set (match_operand:DI 0 "register_operand" "=y")
20648 (unspec:DI
20649 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20650 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20651 UNSPEC_NOP))]
20652 "TARGET_MMX"
20653 "psrlq\t{%2, %0|%0, %2}"
20654 [(set_attr "type" "mmxshft")
20655 (set_attr "mode" "DI")])
20656
20657 (define_insn "ashlv4hi3"
20658 [(set (match_operand:V4HI 0 "register_operand" "=y")
20659 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20660 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20661 "TARGET_MMX"
20662 "psllw\t{%2, %0|%0, %2}"
20663 [(set_attr "type" "mmxshft")
20664 (set_attr "mode" "DI")])
20665
20666 (define_insn "ashlv2si3"
20667 [(set (match_operand:V2SI 0 "register_operand" "=y")
20668 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20669 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20670 "TARGET_MMX"
20671 "pslld\t{%2, %0|%0, %2}"
20672 [(set_attr "type" "mmxshft")
20673 (set_attr "mode" "DI")])
20674
20675 ;; See logical MMX insns.
20676 (define_insn "mmx_ashldi3"
20677 [(set (match_operand:DI 0 "register_operand" "=y")
20678 (unspec:DI
20679 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20680 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20681 UNSPEC_NOP))]
20682 "TARGET_MMX"
20683 "psllq\t{%2, %0|%0, %2}"
20684 [(set_attr "type" "mmxshft")
20685 (set_attr "mode" "DI")])
20686
20687
20688 ;; MMX pack/unpack insns.
20689
20690 (define_insn "mmx_packsswb"
20691 [(set (match_operand:V8QI 0 "register_operand" "=y")
20692 (vec_concat:V8QI
20693 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20694 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20695 "TARGET_MMX"
20696 "packsswb\t{%2, %0|%0, %2}"
20697 [(set_attr "type" "mmxshft")
20698 (set_attr "mode" "DI")])
20699
20700 (define_insn "mmx_packssdw"
20701 [(set (match_operand:V4HI 0 "register_operand" "=y")
20702 (vec_concat:V4HI
20703 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20704 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20705 "TARGET_MMX"
20706 "packssdw\t{%2, %0|%0, %2}"
20707 [(set_attr "type" "mmxshft")
20708 (set_attr "mode" "DI")])
20709
20710 (define_insn "mmx_packuswb"
20711 [(set (match_operand:V8QI 0 "register_operand" "=y")
20712 (vec_concat:V8QI
20713 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20714 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20715 "TARGET_MMX"
20716 "packuswb\t{%2, %0|%0, %2}"
20717 [(set_attr "type" "mmxshft")
20718 (set_attr "mode" "DI")])
20719
20720 (define_insn "mmx_punpckhbw"
20721 [(set (match_operand:V8QI 0 "register_operand" "=y")
20722 (vec_merge:V8QI
20723 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20724 (parallel [(const_int 4)
20725 (const_int 0)
20726 (const_int 5)
20727 (const_int 1)
20728 (const_int 6)
20729 (const_int 2)
20730 (const_int 7)
20731 (const_int 3)]))
20732 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20733 (parallel [(const_int 0)
20734 (const_int 4)
20735 (const_int 1)
20736 (const_int 5)
20737 (const_int 2)
20738 (const_int 6)
20739 (const_int 3)
20740 (const_int 7)]))
20741 (const_int 85)))]
20742 "TARGET_MMX"
20743 "punpckhbw\t{%2, %0|%0, %2}"
20744 [(set_attr "type" "mmxcvt")
20745 (set_attr "mode" "DI")])
20746
20747 (define_insn "mmx_punpckhwd"
20748 [(set (match_operand:V4HI 0 "register_operand" "=y")
20749 (vec_merge:V4HI
20750 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20751 (parallel [(const_int 0)
20752 (const_int 2)
20753 (const_int 1)
20754 (const_int 3)]))
20755 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20756 (parallel [(const_int 2)
20757 (const_int 0)
20758 (const_int 3)
20759 (const_int 1)]))
20760 (const_int 5)))]
20761 "TARGET_MMX"
20762 "punpckhwd\t{%2, %0|%0, %2}"
20763 [(set_attr "type" "mmxcvt")
20764 (set_attr "mode" "DI")])
20765
20766 (define_insn "mmx_punpckhdq"
20767 [(set (match_operand:V2SI 0 "register_operand" "=y")
20768 (vec_merge:V2SI
20769 (match_operand:V2SI 1 "register_operand" "0")
20770 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20771 (parallel [(const_int 1)
20772 (const_int 0)]))
20773 (const_int 1)))]
20774 "TARGET_MMX"
20775 "punpckhdq\t{%2, %0|%0, %2}"
20776 [(set_attr "type" "mmxcvt")
20777 (set_attr "mode" "DI")])
20778
20779 (define_insn "mmx_punpcklbw"
20780 [(set (match_operand:V8QI 0 "register_operand" "=y")
20781 (vec_merge:V8QI
20782 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20783 (parallel [(const_int 0)
20784 (const_int 4)
20785 (const_int 1)
20786 (const_int 5)
20787 (const_int 2)
20788 (const_int 6)
20789 (const_int 3)
20790 (const_int 7)]))
20791 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20792 (parallel [(const_int 4)
20793 (const_int 0)
20794 (const_int 5)
20795 (const_int 1)
20796 (const_int 6)
20797 (const_int 2)
20798 (const_int 7)
20799 (const_int 3)]))
20800 (const_int 85)))]
20801 "TARGET_MMX"
20802 "punpcklbw\t{%2, %0|%0, %2}"
20803 [(set_attr "type" "mmxcvt")
20804 (set_attr "mode" "DI")])
20805
20806 (define_insn "mmx_punpcklwd"
20807 [(set (match_operand:V4HI 0 "register_operand" "=y")
20808 (vec_merge:V4HI
20809 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20810 (parallel [(const_int 2)
20811 (const_int 0)
20812 (const_int 3)
20813 (const_int 1)]))
20814 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20815 (parallel [(const_int 0)
20816 (const_int 2)
20817 (const_int 1)
20818 (const_int 3)]))
20819 (const_int 5)))]
20820 "TARGET_MMX"
20821 "punpcklwd\t{%2, %0|%0, %2}"
20822 [(set_attr "type" "mmxcvt")
20823 (set_attr "mode" "DI")])
20824
20825 (define_insn "mmx_punpckldq"
20826 [(set (match_operand:V2SI 0 "register_operand" "=y")
20827 (vec_merge:V2SI
20828 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20829 (parallel [(const_int 1)
20830 (const_int 0)]))
20831 (match_operand:V2SI 2 "register_operand" "y")
20832 (const_int 1)))]
20833 "TARGET_MMX"
20834 "punpckldq\t{%2, %0|%0, %2}"
20835 [(set_attr "type" "mmxcvt")
20836 (set_attr "mode" "DI")])
20837
20838
20839 ;; Miscellaneous stuff
20840
20841 (define_insn "emms"
20842 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20843 (clobber (reg:XF 8))
20844 (clobber (reg:XF 9))
20845 (clobber (reg:XF 10))
20846 (clobber (reg:XF 11))
20847 (clobber (reg:XF 12))
20848 (clobber (reg:XF 13))
20849 (clobber (reg:XF 14))
20850 (clobber (reg:XF 15))
20851 (clobber (reg:DI 29))
20852 (clobber (reg:DI 30))
20853 (clobber (reg:DI 31))
20854 (clobber (reg:DI 32))
20855 (clobber (reg:DI 33))
20856 (clobber (reg:DI 34))
20857 (clobber (reg:DI 35))
20858 (clobber (reg:DI 36))]
20859 "TARGET_MMX"
20860 "emms"
20861 [(set_attr "type" "mmx")
20862 (set_attr "memory" "unknown")])
20863
20864 (define_insn "ldmxcsr"
20865 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20866 UNSPECV_LDMXCSR)]
20867 "TARGET_SSE"
20868 "ldmxcsr\t%0"
20869 [(set_attr "type" "sse")
20870 (set_attr "memory" "load")])
20871
20872 (define_insn "stmxcsr"
20873 [(set (match_operand:SI 0 "memory_operand" "=m")
20874 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20875 "TARGET_SSE"
20876 "stmxcsr\t%0"
20877 [(set_attr "type" "sse")
20878 (set_attr "memory" "store")])
20879
20880 (define_expand "sfence"
20881 [(set (match_dup 0)
20882 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20883 "TARGET_SSE || TARGET_3DNOW_A"
20884 {
20885 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20886 MEM_VOLATILE_P (operands[0]) = 1;
20887 })
20888
20889 (define_insn "*sfence_insn"
20890 [(set (match_operand:BLK 0 "" "")
20891 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20892 "TARGET_SSE || TARGET_3DNOW_A"
20893 "sfence"
20894 [(set_attr "type" "sse")
20895 (set_attr "memory" "unknown")])
20896
20897 (define_expand "sse_prologue_save"
20898 [(parallel [(set (match_operand:BLK 0 "" "")
20899 (unspec:BLK [(reg:DI 21)
20900 (reg:DI 22)
20901 (reg:DI 23)
20902 (reg:DI 24)
20903 (reg:DI 25)
20904 (reg:DI 26)
20905 (reg:DI 27)
20906 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20907 (use (match_operand:DI 1 "register_operand" ""))
20908 (use (match_operand:DI 2 "immediate_operand" ""))
20909 (use (label_ref:DI (match_operand 3 "" "")))])]
20910 "TARGET_64BIT"
20911 "")
20912
20913 (define_insn "*sse_prologue_save_insn"
20914 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20915 (match_operand:DI 4 "const_int_operand" "n")))
20916 (unspec:BLK [(reg:DI 21)
20917 (reg:DI 22)
20918 (reg:DI 23)
20919 (reg:DI 24)
20920 (reg:DI 25)
20921 (reg:DI 26)
20922 (reg:DI 27)
20923 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20924 (use (match_operand:DI 1 "register_operand" "r"))
20925 (use (match_operand:DI 2 "const_int_operand" "i"))
20926 (use (label_ref:DI (match_operand 3 "" "X")))]
20927 "TARGET_64BIT
20928 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20929 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20930 "*
20931 {
20932 int i;
20933 operands[0] = gen_rtx_MEM (Pmode,
20934 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20935 output_asm_insn (\"jmp\\t%A1\", operands);
20936 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20937 {
20938 operands[4] = adjust_address (operands[0], DImode, i*16);
20939 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20940 PUT_MODE (operands[4], TImode);
20941 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20942 output_asm_insn (\"rex\", operands);
20943 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20944 }
20945 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20946 CODE_LABEL_NUMBER (operands[3]));
20947 RET;
20948 }
20949 "
20950 [(set_attr "type" "other")
20951 (set_attr "length_immediate" "0")
20952 (set_attr "length_address" "0")
20953 (set_attr "length" "135")
20954 (set_attr "memory" "store")
20955 (set_attr "modrm" "0")
20956 (set_attr "mode" "DI")])
20957
20958 ;; 3Dnow! instructions
20959
20960 (define_insn "addv2sf3"
20961 [(set (match_operand:V2SF 0 "register_operand" "=y")
20962 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20963 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20964 "TARGET_3DNOW"
20965 "pfadd\\t{%2, %0|%0, %2}"
20966 [(set_attr "type" "mmxadd")
20967 (set_attr "mode" "V2SF")])
20968
20969 (define_insn "subv2sf3"
20970 [(set (match_operand:V2SF 0 "register_operand" "=y")
20971 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20972 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20973 "TARGET_3DNOW"
20974 "pfsub\\t{%2, %0|%0, %2}"
20975 [(set_attr "type" "mmxadd")
20976 (set_attr "mode" "V2SF")])
20977
20978 (define_insn "subrv2sf3"
20979 [(set (match_operand:V2SF 0 "register_operand" "=y")
20980 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20981 (match_operand:V2SF 1 "register_operand" "0")))]
20982 "TARGET_3DNOW"
20983 "pfsubr\\t{%2, %0|%0, %2}"
20984 [(set_attr "type" "mmxadd")
20985 (set_attr "mode" "V2SF")])
20986
20987 (define_insn "gtv2sf3"
20988 [(set (match_operand:V2SI 0 "register_operand" "=y")
20989 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20990 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20991 "TARGET_3DNOW"
20992 "pfcmpgt\\t{%2, %0|%0, %2}"
20993 [(set_attr "type" "mmxcmp")
20994 (set_attr "mode" "V2SF")])
20995
20996 (define_insn "gev2sf3"
20997 [(set (match_operand:V2SI 0 "register_operand" "=y")
20998 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20999 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21000 "TARGET_3DNOW"
21001 "pfcmpge\\t{%2, %0|%0, %2}"
21002 [(set_attr "type" "mmxcmp")
21003 (set_attr "mode" "V2SF")])
21004
21005 (define_insn "eqv2sf3"
21006 [(set (match_operand:V2SI 0 "register_operand" "=y")
21007 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21008 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21009 "TARGET_3DNOW"
21010 "pfcmpeq\\t{%2, %0|%0, %2}"
21011 [(set_attr "type" "mmxcmp")
21012 (set_attr "mode" "V2SF")])
21013
21014 (define_insn "pfmaxv2sf3"
21015 [(set (match_operand:V2SF 0 "register_operand" "=y")
21016 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21017 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21018 "TARGET_3DNOW"
21019 "pfmax\\t{%2, %0|%0, %2}"
21020 [(set_attr "type" "mmxadd")
21021 (set_attr "mode" "V2SF")])
21022
21023 (define_insn "pfminv2sf3"
21024 [(set (match_operand:V2SF 0 "register_operand" "=y")
21025 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21026 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21027 "TARGET_3DNOW"
21028 "pfmin\\t{%2, %0|%0, %2}"
21029 [(set_attr "type" "mmxadd")
21030 (set_attr "mode" "V2SF")])
21031
21032 (define_insn "mulv2sf3"
21033 [(set (match_operand:V2SF 0 "register_operand" "=y")
21034 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21035 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21036 "TARGET_3DNOW"
21037 "pfmul\\t{%2, %0|%0, %2}"
21038 [(set_attr "type" "mmxmul")
21039 (set_attr "mode" "V2SF")])
21040
21041 (define_insn "femms"
21042 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21043 (clobber (reg:XF 8))
21044 (clobber (reg:XF 9))
21045 (clobber (reg:XF 10))
21046 (clobber (reg:XF 11))
21047 (clobber (reg:XF 12))
21048 (clobber (reg:XF 13))
21049 (clobber (reg:XF 14))
21050 (clobber (reg:XF 15))
21051 (clobber (reg:DI 29))
21052 (clobber (reg:DI 30))
21053 (clobber (reg:DI 31))
21054 (clobber (reg:DI 32))
21055 (clobber (reg:DI 33))
21056 (clobber (reg:DI 34))
21057 (clobber (reg:DI 35))
21058 (clobber (reg:DI 36))]
21059 "TARGET_3DNOW"
21060 "femms"
21061 [(set_attr "type" "mmx")
21062 (set_attr "memory" "none")])
21063
21064 (define_insn "pf2id"
21065 [(set (match_operand:V2SI 0 "register_operand" "=y")
21066 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21067 "TARGET_3DNOW"
21068 "pf2id\\t{%1, %0|%0, %1}"
21069 [(set_attr "type" "mmxcvt")
21070 (set_attr "mode" "V2SF")])
21071
21072 (define_insn "pf2iw"
21073 [(set (match_operand:V2SI 0 "register_operand" "=y")
21074 (sign_extend:V2SI
21075 (ss_truncate:V2HI
21076 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21077 "TARGET_3DNOW_A"
21078 "pf2iw\\t{%1, %0|%0, %1}"
21079 [(set_attr "type" "mmxcvt")
21080 (set_attr "mode" "V2SF")])
21081
21082 (define_insn "pfacc"
21083 [(set (match_operand:V2SF 0 "register_operand" "=y")
21084 (vec_concat:V2SF
21085 (plus:SF
21086 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21087 (parallel [(const_int 0)]))
21088 (vec_select:SF (match_dup 1)
21089 (parallel [(const_int 1)])))
21090 (plus:SF
21091 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21092 (parallel [(const_int 0)]))
21093 (vec_select:SF (match_dup 2)
21094 (parallel [(const_int 1)])))))]
21095 "TARGET_3DNOW"
21096 "pfacc\\t{%2, %0|%0, %2}"
21097 [(set_attr "type" "mmxadd")
21098 (set_attr "mode" "V2SF")])
21099
21100 (define_insn "pfnacc"
21101 [(set (match_operand:V2SF 0 "register_operand" "=y")
21102 (vec_concat:V2SF
21103 (minus:SF
21104 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21105 (parallel [(const_int 0)]))
21106 (vec_select:SF (match_dup 1)
21107 (parallel [(const_int 1)])))
21108 (minus:SF
21109 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21110 (parallel [(const_int 0)]))
21111 (vec_select:SF (match_dup 2)
21112 (parallel [(const_int 1)])))))]
21113 "TARGET_3DNOW_A"
21114 "pfnacc\\t{%2, %0|%0, %2}"
21115 [(set_attr "type" "mmxadd")
21116 (set_attr "mode" "V2SF")])
21117
21118 (define_insn "pfpnacc"
21119 [(set (match_operand:V2SF 0 "register_operand" "=y")
21120 (vec_concat:V2SF
21121 (minus:SF
21122 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21123 (parallel [(const_int 0)]))
21124 (vec_select:SF (match_dup 1)
21125 (parallel [(const_int 1)])))
21126 (plus:SF
21127 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21128 (parallel [(const_int 0)]))
21129 (vec_select:SF (match_dup 2)
21130 (parallel [(const_int 1)])))))]
21131 "TARGET_3DNOW_A"
21132 "pfpnacc\\t{%2, %0|%0, %2}"
21133 [(set_attr "type" "mmxadd")
21134 (set_attr "mode" "V2SF")])
21135
21136 (define_insn "pi2fw"
21137 [(set (match_operand:V2SF 0 "register_operand" "=y")
21138 (float:V2SF
21139 (vec_concat:V2SI
21140 (sign_extend:SI
21141 (truncate:HI
21142 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21143 (parallel [(const_int 0)]))))
21144 (sign_extend:SI
21145 (truncate:HI
21146 (vec_select:SI (match_dup 1)
21147 (parallel [(const_int 1)])))))))]
21148 "TARGET_3DNOW_A"
21149 "pi2fw\\t{%1, %0|%0, %1}"
21150 [(set_attr "type" "mmxcvt")
21151 (set_attr "mode" "V2SF")])
21152
21153 (define_insn "floatv2si2"
21154 [(set (match_operand:V2SF 0 "register_operand" "=y")
21155 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21156 "TARGET_3DNOW"
21157 "pi2fd\\t{%1, %0|%0, %1}"
21158 [(set_attr "type" "mmxcvt")
21159 (set_attr "mode" "V2SF")])
21160
21161 ;; This insn is identical to pavgb in operation, but the opcode is
21162 ;; different. To avoid accidentally matching pavgb, use an unspec.
21163
21164 (define_insn "pavgusb"
21165 [(set (match_operand:V8QI 0 "register_operand" "=y")
21166 (unspec:V8QI
21167 [(match_operand:V8QI 1 "register_operand" "0")
21168 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21169 UNSPEC_PAVGUSB))]
21170 "TARGET_3DNOW"
21171 "pavgusb\\t{%2, %0|%0, %2}"
21172 [(set_attr "type" "mmxshft")
21173 (set_attr "mode" "TI")])
21174
21175 ;; 3DNow reciprocal and sqrt
21176
21177 (define_insn "pfrcpv2sf2"
21178 [(set (match_operand:V2SF 0 "register_operand" "=y")
21179 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21180 UNSPEC_PFRCP))]
21181 "TARGET_3DNOW"
21182 "pfrcp\\t{%1, %0|%0, %1}"
21183 [(set_attr "type" "mmx")
21184 (set_attr "mode" "TI")])
21185
21186 (define_insn "pfrcpit1v2sf3"
21187 [(set (match_operand:V2SF 0 "register_operand" "=y")
21188 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21189 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21190 UNSPEC_PFRCPIT1))]
21191 "TARGET_3DNOW"
21192 "pfrcpit1\\t{%2, %0|%0, %2}"
21193 [(set_attr "type" "mmx")
21194 (set_attr "mode" "TI")])
21195
21196 (define_insn "pfrcpit2v2sf3"
21197 [(set (match_operand:V2SF 0 "register_operand" "=y")
21198 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21199 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21200 UNSPEC_PFRCPIT2))]
21201 "TARGET_3DNOW"
21202 "pfrcpit2\\t{%2, %0|%0, %2}"
21203 [(set_attr "type" "mmx")
21204 (set_attr "mode" "TI")])
21205
21206 (define_insn "pfrsqrtv2sf2"
21207 [(set (match_operand:V2SF 0 "register_operand" "=y")
21208 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21209 UNSPEC_PFRSQRT))]
21210 "TARGET_3DNOW"
21211 "pfrsqrt\\t{%1, %0|%0, %1}"
21212 [(set_attr "type" "mmx")
21213 (set_attr "mode" "TI")])
21214
21215 (define_insn "pfrsqit1v2sf3"
21216 [(set (match_operand:V2SF 0 "register_operand" "=y")
21217 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21218 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21219 UNSPEC_PFRSQIT1))]
21220 "TARGET_3DNOW"
21221 "pfrsqit1\\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "mmx")
21223 (set_attr "mode" "TI")])
21224
21225 (define_insn "pmulhrwv4hi3"
21226 [(set (match_operand:V4HI 0 "register_operand" "=y")
21227 (truncate:V4HI
21228 (lshiftrt:V4SI
21229 (plus:V4SI
21230 (mult:V4SI
21231 (sign_extend:V4SI
21232 (match_operand:V4HI 1 "register_operand" "0"))
21233 (sign_extend:V4SI
21234 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21235 (const_vector:V4SI [(const_int 32768)
21236 (const_int 32768)
21237 (const_int 32768)
21238 (const_int 32768)]))
21239 (const_int 16))))]
21240 "TARGET_3DNOW"
21241 "pmulhrw\\t{%2, %0|%0, %2}"
21242 [(set_attr "type" "mmxmul")
21243 (set_attr "mode" "TI")])
21244
21245 (define_insn "pswapdv2si2"
21246 [(set (match_operand:V2SI 0 "register_operand" "=y")
21247 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21248 (parallel [(const_int 1) (const_int 0)])))]
21249 "TARGET_3DNOW_A"
21250 "pswapd\\t{%1, %0|%0, %1}"
21251 [(set_attr "type" "mmxcvt")
21252 (set_attr "mode" "TI")])
21253
21254 (define_insn "pswapdv2sf2"
21255 [(set (match_operand:V2SF 0 "register_operand" "=y")
21256 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21257 (parallel [(const_int 1) (const_int 0)])))]
21258 "TARGET_3DNOW_A"
21259 "pswapd\\t{%1, %0|%0, %1}"
21260 [(set_attr "type" "mmxcvt")
21261 (set_attr "mode" "TI")])
21262
21263 (define_expand "prefetch"
21264 [(prefetch (match_operand 0 "address_operand" "")
21265 (match_operand:SI 1 "const_int_operand" "")
21266 (match_operand:SI 2 "const_int_operand" ""))]
21267 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21268 {
21269 int rw = INTVAL (operands[1]);
21270 int locality = INTVAL (operands[2]);
21271
21272 if (rw != 0 && rw != 1)
21273 abort ();
21274 if (locality < 0 || locality > 3)
21275 abort ();
21276 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21277 abort ();
21278
21279 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21280 suported by SSE counterpart or the SSE prefetch is not available
21281 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21282 of locality. */
21283 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21284 operands[2] = GEN_INT (3);
21285 else
21286 operands[1] = const0_rtx;
21287 })
21288
21289 (define_insn "*prefetch_sse"
21290 [(prefetch (match_operand:SI 0 "address_operand" "p")
21291 (const_int 0)
21292 (match_operand:SI 1 "const_int_operand" ""))]
21293 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21294 {
21295 static const char * const patterns[4] = {
21296 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21297 };
21298
21299 int locality = INTVAL (operands[1]);
21300 if (locality < 0 || locality > 3)
21301 abort ();
21302
21303 return patterns[locality];
21304 }
21305 [(set_attr "type" "sse")
21306 (set_attr "memory" "none")])
21307
21308 (define_insn "*prefetch_sse_rex"
21309 [(prefetch (match_operand:DI 0 "address_operand" "p")
21310 (const_int 0)
21311 (match_operand:SI 1 "const_int_operand" ""))]
21312 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21313 {
21314 static const char * const patterns[4] = {
21315 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21316 };
21317
21318 int locality = INTVAL (operands[1]);
21319 if (locality < 0 || locality > 3)
21320 abort ();
21321
21322 return patterns[locality];
21323 }
21324 [(set_attr "type" "sse")
21325 (set_attr "memory" "none")])
21326
21327 (define_insn "*prefetch_3dnow"
21328 [(prefetch (match_operand:SI 0 "address_operand" "p")
21329 (match_operand:SI 1 "const_int_operand" "n")
21330 (const_int 3))]
21331 "TARGET_3DNOW && !TARGET_64BIT"
21332 {
21333 if (INTVAL (operands[1]) == 0)
21334 return "prefetch\t%a0";
21335 else
21336 return "prefetchw\t%a0";
21337 }
21338 [(set_attr "type" "mmx")
21339 (set_attr "memory" "none")])
21340
21341 (define_insn "*prefetch_3dnow_rex"
21342 [(prefetch (match_operand:DI 0 "address_operand" "p")
21343 (match_operand:SI 1 "const_int_operand" "n")
21344 (const_int 3))]
21345 "TARGET_3DNOW && TARGET_64BIT"
21346 {
21347 if (INTVAL (operands[1]) == 0)
21348 return "prefetch\t%a0";
21349 else
21350 return "prefetchw\t%a0";
21351 }
21352 [(set_attr "type" "mmx")
21353 (set_attr "memory" "none")])
21354
21355 ;; SSE2 support
21356
21357 (define_insn "addv2df3"
21358 [(set (match_operand:V2DF 0 "register_operand" "=x")
21359 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21360 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21361 "TARGET_SSE2"
21362 "addpd\t{%2, %0|%0, %2}"
21363 [(set_attr "type" "sseadd")
21364 (set_attr "mode" "V2DF")])
21365
21366 (define_insn "vmaddv2df3"
21367 [(set (match_operand:V2DF 0 "register_operand" "=x")
21368 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21369 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21370 (match_dup 1)
21371 (const_int 1)))]
21372 "TARGET_SSE2"
21373 "addsd\t{%2, %0|%0, %2}"
21374 [(set_attr "type" "sseadd")
21375 (set_attr "mode" "DF")])
21376
21377 (define_insn "subv2df3"
21378 [(set (match_operand:V2DF 0 "register_operand" "=x")
21379 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21380 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21381 "TARGET_SSE2"
21382 "subpd\t{%2, %0|%0, %2}"
21383 [(set_attr "type" "sseadd")
21384 (set_attr "mode" "V2DF")])
21385
21386 (define_insn "vmsubv2df3"
21387 [(set (match_operand:V2DF 0 "register_operand" "=x")
21388 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21389 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21390 (match_dup 1)
21391 (const_int 1)))]
21392 "TARGET_SSE2"
21393 "subsd\t{%2, %0|%0, %2}"
21394 [(set_attr "type" "sseadd")
21395 (set_attr "mode" "DF")])
21396
21397 (define_insn "mulv2df3"
21398 [(set (match_operand:V2DF 0 "register_operand" "=x")
21399 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21400 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21401 "TARGET_SSE2"
21402 "mulpd\t{%2, %0|%0, %2}"
21403 [(set_attr "type" "ssemul")
21404 (set_attr "mode" "V2DF")])
21405
21406 (define_insn "vmmulv2df3"
21407 [(set (match_operand:V2DF 0 "register_operand" "=x")
21408 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21409 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21410 (match_dup 1)
21411 (const_int 1)))]
21412 "TARGET_SSE2"
21413 "mulsd\t{%2, %0|%0, %2}"
21414 [(set_attr "type" "ssemul")
21415 (set_attr "mode" "DF")])
21416
21417 (define_insn "divv2df3"
21418 [(set (match_operand:V2DF 0 "register_operand" "=x")
21419 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21420 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21421 "TARGET_SSE2"
21422 "divpd\t{%2, %0|%0, %2}"
21423 [(set_attr "type" "ssediv")
21424 (set_attr "mode" "V2DF")])
21425
21426 (define_insn "vmdivv2df3"
21427 [(set (match_operand:V2DF 0 "register_operand" "=x")
21428 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21429 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21430 (match_dup 1)
21431 (const_int 1)))]
21432 "TARGET_SSE2"
21433 "divsd\t{%2, %0|%0, %2}"
21434 [(set_attr "type" "ssediv")
21435 (set_attr "mode" "DF")])
21436
21437 ;; SSE min/max
21438
21439 (define_insn "smaxv2df3"
21440 [(set (match_operand:V2DF 0 "register_operand" "=x")
21441 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21442 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21443 "TARGET_SSE2"
21444 "maxpd\t{%2, %0|%0, %2}"
21445 [(set_attr "type" "sseadd")
21446 (set_attr "mode" "V2DF")])
21447
21448 (define_insn "vmsmaxv2df3"
21449 [(set (match_operand:V2DF 0 "register_operand" "=x")
21450 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21451 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21452 (match_dup 1)
21453 (const_int 1)))]
21454 "TARGET_SSE2"
21455 "maxsd\t{%2, %0|%0, %2}"
21456 [(set_attr "type" "sseadd")
21457 (set_attr "mode" "DF")])
21458
21459 (define_insn "sminv2df3"
21460 [(set (match_operand:V2DF 0 "register_operand" "=x")
21461 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21462 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21463 "TARGET_SSE2"
21464 "minpd\t{%2, %0|%0, %2}"
21465 [(set_attr "type" "sseadd")
21466 (set_attr "mode" "V2DF")])
21467
21468 (define_insn "vmsminv2df3"
21469 [(set (match_operand:V2DF 0 "register_operand" "=x")
21470 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21471 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21472 (match_dup 1)
21473 (const_int 1)))]
21474 "TARGET_SSE2"
21475 "minsd\t{%2, %0|%0, %2}"
21476 [(set_attr "type" "sseadd")
21477 (set_attr "mode" "DF")])
21478 ;; SSE2 square root. There doesn't appear to be an extension for the
21479 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21480
21481 (define_insn "sqrtv2df2"
21482 [(set (match_operand:V2DF 0 "register_operand" "=x")
21483 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21484 "TARGET_SSE2"
21485 "sqrtpd\t{%1, %0|%0, %1}"
21486 [(set_attr "type" "sse")
21487 (set_attr "mode" "V2DF")])
21488
21489 (define_insn "vmsqrtv2df2"
21490 [(set (match_operand:V2DF 0 "register_operand" "=x")
21491 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21492 (match_operand:V2DF 2 "register_operand" "0")
21493 (const_int 1)))]
21494 "TARGET_SSE2"
21495 "sqrtsd\t{%1, %0|%0, %1}"
21496 [(set_attr "type" "sse")
21497 (set_attr "mode" "SF")])
21498
21499 ;; SSE mask-generating compares
21500
21501 (define_insn "maskcmpv2df3"
21502 [(set (match_operand:V2DI 0 "register_operand" "=x")
21503 (match_operator:V2DI 3 "sse_comparison_operator"
21504 [(match_operand:V2DF 1 "register_operand" "0")
21505 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21506 "TARGET_SSE2"
21507 "cmp%D3pd\t{%2, %0|%0, %2}"
21508 [(set_attr "type" "ssecmp")
21509 (set_attr "mode" "V2DF")])
21510
21511 (define_insn "maskncmpv2df3"
21512 [(set (match_operand:V2DI 0 "register_operand" "=x")
21513 (not:V2DI
21514 (match_operator:V2DI 3 "sse_comparison_operator"
21515 [(match_operand:V2DF 1 "register_operand" "0")
21516 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21517 "TARGET_SSE2"
21518 {
21519 if (GET_CODE (operands[3]) == UNORDERED)
21520 return "cmpordps\t{%2, %0|%0, %2}";
21521 else
21522 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21523 }
21524 [(set_attr "type" "ssecmp")
21525 (set_attr "mode" "V2DF")])
21526
21527 (define_insn "vmmaskcmpv2df3"
21528 [(set (match_operand:V2DI 0 "register_operand" "=x")
21529 (vec_merge:V2DI
21530 (match_operator:V2DI 3 "sse_comparison_operator"
21531 [(match_operand:V2DF 1 "register_operand" "0")
21532 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21533 (subreg:V2DI (match_dup 1) 0)
21534 (const_int 1)))]
21535 "TARGET_SSE2"
21536 "cmp%D3sd\t{%2, %0|%0, %2}"
21537 [(set_attr "type" "ssecmp")
21538 (set_attr "mode" "DF")])
21539
21540 (define_insn "vmmaskncmpv2df3"
21541 [(set (match_operand:V2DI 0 "register_operand" "=x")
21542 (vec_merge:V2DI
21543 (not:V2DI
21544 (match_operator:V2DI 3 "sse_comparison_operator"
21545 [(match_operand:V2DF 1 "register_operand" "0")
21546 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21547 (subreg:V2DI (match_dup 1) 0)
21548 (const_int 1)))]
21549 "TARGET_SSE2"
21550 {
21551 if (GET_CODE (operands[3]) == UNORDERED)
21552 return "cmpordsd\t{%2, %0|%0, %2}";
21553 else
21554 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21555 }
21556 [(set_attr "type" "ssecmp")
21557 (set_attr "mode" "DF")])
21558
21559 (define_insn "sse2_comi"
21560 [(set (reg:CCFP 17)
21561 (compare:CCFP (vec_select:DF
21562 (match_operand:V2DF 0 "register_operand" "x")
21563 (parallel [(const_int 0)]))
21564 (vec_select:DF
21565 (match_operand:V2DF 1 "register_operand" "x")
21566 (parallel [(const_int 0)]))))]
21567 "TARGET_SSE2"
21568 "comisd\t{%1, %0|%0, %1}"
21569 [(set_attr "type" "ssecomi")
21570 (set_attr "mode" "DF")])
21571
21572 (define_insn "sse2_ucomi"
21573 [(set (reg:CCFPU 17)
21574 (compare:CCFPU (vec_select:DF
21575 (match_operand:V2DF 0 "register_operand" "x")
21576 (parallel [(const_int 0)]))
21577 (vec_select:DF
21578 (match_operand:V2DF 1 "register_operand" "x")
21579 (parallel [(const_int 0)]))))]
21580 "TARGET_SSE2"
21581 "ucomisd\t{%1, %0|%0, %1}"
21582 [(set_attr "type" "ssecomi")
21583 (set_attr "mode" "DF")])
21584
21585 ;; SSE Strange Moves.
21586
21587 (define_insn "sse2_movmskpd"
21588 [(set (match_operand:SI 0 "register_operand" "=r")
21589 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21590 UNSPEC_MOVMSK))]
21591 "TARGET_SSE2"
21592 "movmskpd\t{%1, %0|%0, %1}"
21593 [(set_attr "type" "ssecvt")
21594 (set_attr "mode" "V2DF")])
21595
21596 (define_insn "sse2_pmovmskb"
21597 [(set (match_operand:SI 0 "register_operand" "=r")
21598 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21599 UNSPEC_MOVMSK))]
21600 "TARGET_SSE2"
21601 "pmovmskb\t{%1, %0|%0, %1}"
21602 [(set_attr "type" "ssecvt")
21603 (set_attr "mode" "V2DF")])
21604
21605 (define_insn "sse2_maskmovdqu"
21606 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21607 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21608 (match_operand:V16QI 2 "register_operand" "x")]
21609 UNSPEC_MASKMOV))]
21610 "TARGET_SSE2"
21611 ;; @@@ check ordering of operands in intel/nonintel syntax
21612 "maskmovdqu\t{%2, %1|%1, %2}"
21613 [(set_attr "type" "ssecvt")
21614 (set_attr "mode" "TI")])
21615
21616 (define_insn "sse2_maskmovdqu_rex64"
21617 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21618 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21619 (match_operand:V16QI 2 "register_operand" "x")]
21620 UNSPEC_MASKMOV))]
21621 "TARGET_SSE2"
21622 ;; @@@ check ordering of operands in intel/nonintel syntax
21623 "maskmovdqu\t{%2, %1|%1, %2}"
21624 [(set_attr "type" "ssecvt")
21625 (set_attr "mode" "TI")])
21626
21627 (define_insn "sse2_movntv2df"
21628 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21629 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21630 UNSPEC_MOVNT))]
21631 "TARGET_SSE2"
21632 "movntpd\t{%1, %0|%0, %1}"
21633 [(set_attr "type" "ssecvt")
21634 (set_attr "mode" "V2DF")])
21635
21636 (define_insn "sse2_movntv2di"
21637 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21638 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21639 UNSPEC_MOVNT))]
21640 "TARGET_SSE2"
21641 "movntdq\t{%1, %0|%0, %1}"
21642 [(set_attr "type" "ssecvt")
21643 (set_attr "mode" "TI")])
21644
21645 (define_insn "sse2_movntsi"
21646 [(set (match_operand:SI 0 "memory_operand" "=m")
21647 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21648 UNSPEC_MOVNT))]
21649 "TARGET_SSE2"
21650 "movnti\t{%1, %0|%0, %1}"
21651 [(set_attr "type" "ssecvt")
21652 (set_attr "mode" "V2DF")])
21653
21654 ;; SSE <-> integer/MMX conversions
21655
21656 ;; Conversions between SI and SF
21657
21658 (define_insn "cvtdq2ps"
21659 [(set (match_operand:V4SF 0 "register_operand" "=x")
21660 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21661 "TARGET_SSE2"
21662 "cvtdq2ps\t{%1, %0|%0, %1}"
21663 [(set_attr "type" "ssecvt")
21664 (set_attr "mode" "V2DF")])
21665
21666 (define_insn "cvtps2dq"
21667 [(set (match_operand:V4SI 0 "register_operand" "=x")
21668 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21669 "TARGET_SSE2"
21670 "cvtps2dq\t{%1, %0|%0, %1}"
21671 [(set_attr "type" "ssecvt")
21672 (set_attr "mode" "TI")])
21673
21674 (define_insn "cvttps2dq"
21675 [(set (match_operand:V4SI 0 "register_operand" "=x")
21676 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21677 UNSPEC_FIX))]
21678 "TARGET_SSE2"
21679 "cvttps2dq\t{%1, %0|%0, %1}"
21680 [(set_attr "type" "ssecvt")
21681 (set_attr "mode" "TI")])
21682
21683 ;; Conversions between SI and DF
21684
21685 (define_insn "cvtdq2pd"
21686 [(set (match_operand:V2DF 0 "register_operand" "=x")
21687 (float:V2DF (vec_select:V2SI
21688 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21689 (parallel
21690 [(const_int 0)
21691 (const_int 1)]))))]
21692 "TARGET_SSE2"
21693 "cvtdq2pd\t{%1, %0|%0, %1}"
21694 [(set_attr "type" "ssecvt")
21695 (set_attr "mode" "V2DF")])
21696
21697 (define_insn "cvtpd2dq"
21698 [(set (match_operand:V4SI 0 "register_operand" "=x")
21699 (vec_concat:V4SI
21700 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21701 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21702 "TARGET_SSE2"
21703 "cvtpd2dq\t{%1, %0|%0, %1}"
21704 [(set_attr "type" "ssecvt")
21705 (set_attr "mode" "TI")])
21706
21707 (define_insn "cvttpd2dq"
21708 [(set (match_operand:V4SI 0 "register_operand" "=x")
21709 (vec_concat:V4SI
21710 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21711 UNSPEC_FIX)
21712 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21713 "TARGET_SSE2"
21714 "cvttpd2dq\t{%1, %0|%0, %1}"
21715 [(set_attr "type" "ssecvt")
21716 (set_attr "mode" "TI")])
21717
21718 (define_insn "cvtpd2pi"
21719 [(set (match_operand:V2SI 0 "register_operand" "=y")
21720 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21721 "TARGET_SSE2"
21722 "cvtpd2pi\t{%1, %0|%0, %1}"
21723 [(set_attr "type" "ssecvt")
21724 (set_attr "mode" "TI")])
21725
21726 (define_insn "cvttpd2pi"
21727 [(set (match_operand:V2SI 0 "register_operand" "=y")
21728 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21729 UNSPEC_FIX))]
21730 "TARGET_SSE2"
21731 "cvttpd2pi\t{%1, %0|%0, %1}"
21732 [(set_attr "type" "ssecvt")
21733 (set_attr "mode" "TI")])
21734
21735 (define_insn "cvtpi2pd"
21736 [(set (match_operand:V2DF 0 "register_operand" "=x")
21737 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21738 "TARGET_SSE2"
21739 "cvtpi2pd\t{%1, %0|%0, %1}"
21740 [(set_attr "type" "ssecvt")
21741 (set_attr "mode" "TI")])
21742
21743 ;; Conversions between SI and DF
21744
21745 (define_insn "cvtsd2si"
21746 [(set (match_operand:SI 0 "register_operand" "=r,r")
21747 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21748 (parallel [(const_int 0)]))))]
21749 "TARGET_SSE2"
21750 "cvtsd2si\t{%1, %0|%0, %1}"
21751 [(set_attr "type" "sseicvt")
21752 (set_attr "athlon_decode" "double,vector")
21753 (set_attr "mode" "SI")])
21754
21755 (define_insn "cvtsd2siq"
21756 [(set (match_operand:DI 0 "register_operand" "=r,r")
21757 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21758 (parallel [(const_int 0)]))))]
21759 "TARGET_SSE2 && TARGET_64BIT"
21760 "cvtsd2siq\t{%1, %0|%0, %1}"
21761 [(set_attr "type" "sseicvt")
21762 (set_attr "athlon_decode" "double,vector")
21763 (set_attr "mode" "DI")])
21764
21765 (define_insn "cvttsd2si"
21766 [(set (match_operand:SI 0 "register_operand" "=r,r")
21767 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21768 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21769 "TARGET_SSE2"
21770 "cvttsd2si\t{%1, %0|%0, %1}"
21771 [(set_attr "type" "sseicvt")
21772 (set_attr "mode" "SI")
21773 (set_attr "athlon_decode" "double,vector")])
21774
21775 (define_insn "cvttsd2siq"
21776 [(set (match_operand:DI 0 "register_operand" "=r,r")
21777 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21778 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21779 "TARGET_SSE2 && TARGET_64BIT"
21780 "cvttsd2siq\t{%1, %0|%0, %1}"
21781 [(set_attr "type" "sseicvt")
21782 (set_attr "mode" "DI")
21783 (set_attr "athlon_decode" "double,vector")])
21784
21785 (define_insn "cvtsi2sd"
21786 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21787 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21788 (vec_duplicate:V2DF
21789 (float:DF
21790 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21791 (const_int 2)))]
21792 "TARGET_SSE2"
21793 "cvtsi2sd\t{%2, %0|%0, %2}"
21794 [(set_attr "type" "sseicvt")
21795 (set_attr "mode" "DF")
21796 (set_attr "athlon_decode" "double,direct")])
21797
21798 (define_insn "cvtsi2sdq"
21799 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21800 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21801 (vec_duplicate:V2DF
21802 (float:DF
21803 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21804 (const_int 2)))]
21805 "TARGET_SSE2 && TARGET_64BIT"
21806 "cvtsi2sdq\t{%2, %0|%0, %2}"
21807 [(set_attr "type" "sseicvt")
21808 (set_attr "mode" "DF")
21809 (set_attr "athlon_decode" "double,direct")])
21810
21811 ;; Conversions between SF and DF
21812
21813 (define_insn "cvtsd2ss"
21814 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21815 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21816 (vec_duplicate:V4SF
21817 (float_truncate:V2SF
21818 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21819 (const_int 14)))]
21820 "TARGET_SSE2"
21821 "cvtsd2ss\t{%2, %0|%0, %2}"
21822 [(set_attr "type" "ssecvt")
21823 (set_attr "athlon_decode" "vector,double")
21824 (set_attr "mode" "SF")])
21825
21826 (define_insn "cvtss2sd"
21827 [(set (match_operand:V2DF 0 "register_operand" "=x")
21828 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21829 (float_extend:V2DF
21830 (vec_select:V2SF
21831 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21832 (parallel [(const_int 0)
21833 (const_int 1)])))
21834 (const_int 2)))]
21835 "TARGET_SSE2"
21836 "cvtss2sd\t{%2, %0|%0, %2}"
21837 [(set_attr "type" "ssecvt")
21838 (set_attr "mode" "DF")])
21839
21840 (define_insn "cvtpd2ps"
21841 [(set (match_operand:V4SF 0 "register_operand" "=x")
21842 (subreg:V4SF
21843 (vec_concat:V4SI
21844 (subreg:V2SI (float_truncate:V2SF
21845 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21846 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21847 "TARGET_SSE2"
21848 "cvtpd2ps\t{%1, %0|%0, %1}"
21849 [(set_attr "type" "ssecvt")
21850 (set_attr "mode" "V4SF")])
21851
21852 (define_insn "cvtps2pd"
21853 [(set (match_operand:V2DF 0 "register_operand" "=x")
21854 (float_extend:V2DF
21855 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21856 (parallel [(const_int 0)
21857 (const_int 1)]))))]
21858 "TARGET_SSE2"
21859 "cvtps2pd\t{%1, %0|%0, %1}"
21860 [(set_attr "type" "ssecvt")
21861 (set_attr "mode" "V2DF")])
21862
21863 ;; SSE2 variants of MMX insns
21864
21865 ;; MMX arithmetic
21866
21867 (define_insn "addv16qi3"
21868 [(set (match_operand:V16QI 0 "register_operand" "=x")
21869 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21870 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21871 "TARGET_SSE2"
21872 "paddb\t{%2, %0|%0, %2}"
21873 [(set_attr "type" "sseiadd")
21874 (set_attr "mode" "TI")])
21875
21876 (define_insn "addv8hi3"
21877 [(set (match_operand:V8HI 0 "register_operand" "=x")
21878 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21879 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21880 "TARGET_SSE2"
21881 "paddw\t{%2, %0|%0, %2}"
21882 [(set_attr "type" "sseiadd")
21883 (set_attr "mode" "TI")])
21884
21885 (define_insn "addv4si3"
21886 [(set (match_operand:V4SI 0 "register_operand" "=x")
21887 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21888 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21889 "TARGET_SSE2"
21890 "paddd\t{%2, %0|%0, %2}"
21891 [(set_attr "type" "sseiadd")
21892 (set_attr "mode" "TI")])
21893
21894 (define_insn "addv2di3"
21895 [(set (match_operand:V2DI 0 "register_operand" "=x")
21896 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21897 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21898 "TARGET_SSE2"
21899 "paddq\t{%2, %0|%0, %2}"
21900 [(set_attr "type" "sseiadd")
21901 (set_attr "mode" "TI")])
21902
21903 (define_insn "ssaddv16qi3"
21904 [(set (match_operand:V16QI 0 "register_operand" "=x")
21905 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21906 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21907 "TARGET_SSE2"
21908 "paddsb\t{%2, %0|%0, %2}"
21909 [(set_attr "type" "sseiadd")
21910 (set_attr "mode" "TI")])
21911
21912 (define_insn "ssaddv8hi3"
21913 [(set (match_operand:V8HI 0 "register_operand" "=x")
21914 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21915 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21916 "TARGET_SSE2"
21917 "paddsw\t{%2, %0|%0, %2}"
21918 [(set_attr "type" "sseiadd")
21919 (set_attr "mode" "TI")])
21920
21921 (define_insn "usaddv16qi3"
21922 [(set (match_operand:V16QI 0 "register_operand" "=x")
21923 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21924 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21925 "TARGET_SSE2"
21926 "paddusb\t{%2, %0|%0, %2}"
21927 [(set_attr "type" "sseiadd")
21928 (set_attr "mode" "TI")])
21929
21930 (define_insn "usaddv8hi3"
21931 [(set (match_operand:V8HI 0 "register_operand" "=x")
21932 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21933 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21934 "TARGET_SSE2"
21935 "paddusw\t{%2, %0|%0, %2}"
21936 [(set_attr "type" "sseiadd")
21937 (set_attr "mode" "TI")])
21938
21939 (define_insn "subv16qi3"
21940 [(set (match_operand:V16QI 0 "register_operand" "=x")
21941 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21942 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21943 "TARGET_SSE2"
21944 "psubb\t{%2, %0|%0, %2}"
21945 [(set_attr "type" "sseiadd")
21946 (set_attr "mode" "TI")])
21947
21948 (define_insn "subv8hi3"
21949 [(set (match_operand:V8HI 0 "register_operand" "=x")
21950 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21951 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21952 "TARGET_SSE2"
21953 "psubw\t{%2, %0|%0, %2}"
21954 [(set_attr "type" "sseiadd")
21955 (set_attr "mode" "TI")])
21956
21957 (define_insn "subv4si3"
21958 [(set (match_operand:V4SI 0 "register_operand" "=x")
21959 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21960 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21961 "TARGET_SSE2"
21962 "psubd\t{%2, %0|%0, %2}"
21963 [(set_attr "type" "sseiadd")
21964 (set_attr "mode" "TI")])
21965
21966 (define_insn "subv2di3"
21967 [(set (match_operand:V2DI 0 "register_operand" "=x")
21968 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21969 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21970 "TARGET_SSE2"
21971 "psubq\t{%2, %0|%0, %2}"
21972 [(set_attr "type" "sseiadd")
21973 (set_attr "mode" "TI")])
21974
21975 (define_insn "sssubv16qi3"
21976 [(set (match_operand:V16QI 0 "register_operand" "=x")
21977 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21978 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21979 "TARGET_SSE2"
21980 "psubsb\t{%2, %0|%0, %2}"
21981 [(set_attr "type" "sseiadd")
21982 (set_attr "mode" "TI")])
21983
21984 (define_insn "sssubv8hi3"
21985 [(set (match_operand:V8HI 0 "register_operand" "=x")
21986 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21987 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21988 "TARGET_SSE2"
21989 "psubsw\t{%2, %0|%0, %2}"
21990 [(set_attr "type" "sseiadd")
21991 (set_attr "mode" "TI")])
21992
21993 (define_insn "ussubv16qi3"
21994 [(set (match_operand:V16QI 0 "register_operand" "=x")
21995 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21996 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21997 "TARGET_SSE2"
21998 "psubusb\t{%2, %0|%0, %2}"
21999 [(set_attr "type" "sseiadd")
22000 (set_attr "mode" "TI")])
22001
22002 (define_insn "ussubv8hi3"
22003 [(set (match_operand:V8HI 0 "register_operand" "=x")
22004 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22005 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22006 "TARGET_SSE2"
22007 "psubusw\t{%2, %0|%0, %2}"
22008 [(set_attr "type" "sseiadd")
22009 (set_attr "mode" "TI")])
22010
22011 (define_insn "mulv8hi3"
22012 [(set (match_operand:V8HI 0 "register_operand" "=x")
22013 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22014 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22015 "TARGET_SSE2"
22016 "pmullw\t{%2, %0|%0, %2}"
22017 [(set_attr "type" "sseimul")
22018 (set_attr "mode" "TI")])
22019
22020 (define_insn "smulv8hi3_highpart"
22021 [(set (match_operand:V8HI 0 "register_operand" "=x")
22022 (truncate:V8HI
22023 (lshiftrt:V8SI
22024 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22025 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22026 (const_int 16))))]
22027 "TARGET_SSE2"
22028 "pmulhw\t{%2, %0|%0, %2}"
22029 [(set_attr "type" "sseimul")
22030 (set_attr "mode" "TI")])
22031
22032 (define_insn "umulv8hi3_highpart"
22033 [(set (match_operand:V8HI 0 "register_operand" "=x")
22034 (truncate:V8HI
22035 (lshiftrt:V8SI
22036 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22037 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22038 (const_int 16))))]
22039 "TARGET_SSE2"
22040 "pmulhuw\t{%2, %0|%0, %2}"
22041 [(set_attr "type" "sseimul")
22042 (set_attr "mode" "TI")])
22043
22044 (define_insn "sse2_umulsidi3"
22045 [(set (match_operand:DI 0 "register_operand" "=y")
22046 (mult:DI (zero_extend:DI (vec_select:SI
22047 (match_operand:V2SI 1 "register_operand" "0")
22048 (parallel [(const_int 0)])))
22049 (zero_extend:DI (vec_select:SI
22050 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22051 (parallel [(const_int 0)])))))]
22052 "TARGET_SSE2"
22053 "pmuludq\t{%2, %0|%0, %2}"
22054 [(set_attr "type" "sseimul")
22055 (set_attr "mode" "TI")])
22056
22057 (define_insn "sse2_umulv2siv2di3"
22058 [(set (match_operand:V2DI 0 "register_operand" "=x")
22059 (mult:V2DI (zero_extend:V2DI
22060 (vec_select:V2SI
22061 (match_operand:V4SI 1 "register_operand" "0")
22062 (parallel [(const_int 0) (const_int 2)])))
22063 (zero_extend:V2DI
22064 (vec_select:V2SI
22065 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22066 (parallel [(const_int 0) (const_int 2)])))))]
22067 "TARGET_SSE2"
22068 "pmuludq\t{%2, %0|%0, %2}"
22069 [(set_attr "type" "sseimul")
22070 (set_attr "mode" "TI")])
22071
22072 (define_insn "sse2_pmaddwd"
22073 [(set (match_operand:V4SI 0 "register_operand" "=x")
22074 (plus:V4SI
22075 (mult:V4SI
22076 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22077 (parallel [(const_int 0)
22078 (const_int 2)
22079 (const_int 4)
22080 (const_int 6)])))
22081 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22082 (parallel [(const_int 0)
22083 (const_int 2)
22084 (const_int 4)
22085 (const_int 6)]))))
22086 (mult:V4SI
22087 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22088 (parallel [(const_int 1)
22089 (const_int 3)
22090 (const_int 5)
22091 (const_int 7)])))
22092 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22093 (parallel [(const_int 1)
22094 (const_int 3)
22095 (const_int 5)
22096 (const_int 7)]))))))]
22097 "TARGET_SSE2"
22098 "pmaddwd\t{%2, %0|%0, %2}"
22099 [(set_attr "type" "sseiadd")
22100 (set_attr "mode" "TI")])
22101
22102 ;; Same as pxor, but don't show input operands so that we don't think
22103 ;; they are live.
22104 (define_insn "sse2_clrti"
22105 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22106 "TARGET_SSE2"
22107 {
22108 if (get_attr_mode (insn) == MODE_TI)
22109 return "pxor\t%0, %0";
22110 else
22111 return "xorps\t%0, %0";
22112 }
22113 [(set_attr "type" "ssemov")
22114 (set_attr "memory" "none")
22115 (set (attr "mode")
22116 (if_then_else
22117 (ne (symbol_ref "optimize_size")
22118 (const_int 0))
22119 (const_string "V4SF")
22120 (const_string "TI")))])
22121
22122 ;; MMX unsigned averages/sum of absolute differences
22123
22124 (define_insn "sse2_uavgv16qi3"
22125 [(set (match_operand:V16QI 0 "register_operand" "=x")
22126 (ashiftrt:V16QI
22127 (plus:V16QI (plus:V16QI
22128 (match_operand:V16QI 1 "register_operand" "0")
22129 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22130 (const_vector:V16QI [(const_int 1) (const_int 1)
22131 (const_int 1) (const_int 1)
22132 (const_int 1) (const_int 1)
22133 (const_int 1) (const_int 1)
22134 (const_int 1) (const_int 1)
22135 (const_int 1) (const_int 1)
22136 (const_int 1) (const_int 1)
22137 (const_int 1) (const_int 1)]))
22138 (const_int 1)))]
22139 "TARGET_SSE2"
22140 "pavgb\t{%2, %0|%0, %2}"
22141 [(set_attr "type" "sseiadd")
22142 (set_attr "mode" "TI")])
22143
22144 (define_insn "sse2_uavgv8hi3"
22145 [(set (match_operand:V8HI 0 "register_operand" "=x")
22146 (ashiftrt:V8HI
22147 (plus:V8HI (plus:V8HI
22148 (match_operand:V8HI 1 "register_operand" "0")
22149 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22150 (const_vector:V8HI [(const_int 1) (const_int 1)
22151 (const_int 1) (const_int 1)
22152 (const_int 1) (const_int 1)
22153 (const_int 1) (const_int 1)]))
22154 (const_int 1)))]
22155 "TARGET_SSE2"
22156 "pavgw\t{%2, %0|%0, %2}"
22157 [(set_attr "type" "sseiadd")
22158 (set_attr "mode" "TI")])
22159
22160 ;; @@@ this isn't the right representation.
22161 (define_insn "sse2_psadbw"
22162 [(set (match_operand:V2DI 0 "register_operand" "=x")
22163 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22164 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22165 UNSPEC_PSADBW))]
22166 "TARGET_SSE2"
22167 "psadbw\t{%2, %0|%0, %2}"
22168 [(set_attr "type" "sseiadd")
22169 (set_attr "mode" "TI")])
22170
22171
22172 ;; MMX insert/extract/shuffle
22173
22174 (define_insn "sse2_pinsrw"
22175 [(set (match_operand:V8HI 0 "register_operand" "=x")
22176 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22177 (vec_duplicate:V8HI
22178 (truncate:HI
22179 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22180 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22181 "TARGET_SSE2"
22182 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22183 [(set_attr "type" "ssecvt")
22184 (set_attr "mode" "TI")])
22185
22186 (define_insn "sse2_pextrw"
22187 [(set (match_operand:SI 0 "register_operand" "=r")
22188 (zero_extend:SI
22189 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22190 (parallel
22191 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22192 "TARGET_SSE2"
22193 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22194 [(set_attr "type" "ssecvt")
22195 (set_attr "mode" "TI")])
22196
22197 (define_insn "sse2_pshufd"
22198 [(set (match_operand:V4SI 0 "register_operand" "=x")
22199 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22200 (match_operand:SI 2 "immediate_operand" "i")]
22201 UNSPEC_SHUFFLE))]
22202 "TARGET_SSE2"
22203 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22204 [(set_attr "type" "ssecvt")
22205 (set_attr "mode" "TI")])
22206
22207 (define_insn "sse2_pshuflw"
22208 [(set (match_operand:V8HI 0 "register_operand" "=x")
22209 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22210 (match_operand:SI 2 "immediate_operand" "i")]
22211 UNSPEC_PSHUFLW))]
22212 "TARGET_SSE2"
22213 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22214 [(set_attr "type" "ssecvt")
22215 (set_attr "mode" "TI")])
22216
22217 (define_insn "sse2_pshufhw"
22218 [(set (match_operand:V8HI 0 "register_operand" "=x")
22219 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22220 (match_operand:SI 2 "immediate_operand" "i")]
22221 UNSPEC_PSHUFHW))]
22222 "TARGET_SSE2"
22223 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22224 [(set_attr "type" "ssecvt")
22225 (set_attr "mode" "TI")])
22226
22227 ;; MMX mask-generating comparisons
22228
22229 (define_insn "eqv16qi3"
22230 [(set (match_operand:V16QI 0 "register_operand" "=x")
22231 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22232 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22233 "TARGET_SSE2"
22234 "pcmpeqb\t{%2, %0|%0, %2}"
22235 [(set_attr "type" "ssecmp")
22236 (set_attr "mode" "TI")])
22237
22238 (define_insn "eqv8hi3"
22239 [(set (match_operand:V8HI 0 "register_operand" "=x")
22240 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22241 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22242 "TARGET_SSE2"
22243 "pcmpeqw\t{%2, %0|%0, %2}"
22244 [(set_attr "type" "ssecmp")
22245 (set_attr "mode" "TI")])
22246
22247 (define_insn "eqv4si3"
22248 [(set (match_operand:V4SI 0 "register_operand" "=x")
22249 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22250 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22251 "TARGET_SSE2"
22252 "pcmpeqd\t{%2, %0|%0, %2}"
22253 [(set_attr "type" "ssecmp")
22254 (set_attr "mode" "TI")])
22255
22256 (define_insn "gtv16qi3"
22257 [(set (match_operand:V16QI 0 "register_operand" "=x")
22258 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22259 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22260 "TARGET_SSE2"
22261 "pcmpgtb\t{%2, %0|%0, %2}"
22262 [(set_attr "type" "ssecmp")
22263 (set_attr "mode" "TI")])
22264
22265 (define_insn "gtv8hi3"
22266 [(set (match_operand:V8HI 0 "register_operand" "=x")
22267 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22268 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22269 "TARGET_SSE2"
22270 "pcmpgtw\t{%2, %0|%0, %2}"
22271 [(set_attr "type" "ssecmp")
22272 (set_attr "mode" "TI")])
22273
22274 (define_insn "gtv4si3"
22275 [(set (match_operand:V4SI 0 "register_operand" "=x")
22276 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22277 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22278 "TARGET_SSE2"
22279 "pcmpgtd\t{%2, %0|%0, %2}"
22280 [(set_attr "type" "ssecmp")
22281 (set_attr "mode" "TI")])
22282
22283
22284 ;; MMX max/min insns
22285
22286 (define_insn "umaxv16qi3"
22287 [(set (match_operand:V16QI 0 "register_operand" "=x")
22288 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22289 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22290 "TARGET_SSE2"
22291 "pmaxub\t{%2, %0|%0, %2}"
22292 [(set_attr "type" "sseiadd")
22293 (set_attr "mode" "TI")])
22294
22295 (define_insn "smaxv8hi3"
22296 [(set (match_operand:V8HI 0 "register_operand" "=x")
22297 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22298 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22299 "TARGET_SSE2"
22300 "pmaxsw\t{%2, %0|%0, %2}"
22301 [(set_attr "type" "sseiadd")
22302 (set_attr "mode" "TI")])
22303
22304 (define_insn "uminv16qi3"
22305 [(set (match_operand:V16QI 0 "register_operand" "=x")
22306 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22307 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22308 "TARGET_SSE2"
22309 "pminub\t{%2, %0|%0, %2}"
22310 [(set_attr "type" "sseiadd")
22311 (set_attr "mode" "TI")])
22312
22313 (define_insn "sminv8hi3"
22314 [(set (match_operand:V8HI 0 "register_operand" "=x")
22315 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22316 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22317 "TARGET_SSE2"
22318 "pminsw\t{%2, %0|%0, %2}"
22319 [(set_attr "type" "sseiadd")
22320 (set_attr "mode" "TI")])
22321
22322
22323 ;; MMX shifts
22324
22325 (define_insn "ashrv8hi3"
22326 [(set (match_operand:V8HI 0 "register_operand" "=x")
22327 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22328 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22329 "TARGET_SSE2"
22330 "psraw\t{%2, %0|%0, %2}"
22331 [(set_attr "type" "sseishft")
22332 (set_attr "mode" "TI")])
22333
22334 (define_insn "ashrv4si3"
22335 [(set (match_operand:V4SI 0 "register_operand" "=x")
22336 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22337 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22338 "TARGET_SSE2"
22339 "psrad\t{%2, %0|%0, %2}"
22340 [(set_attr "type" "sseishft")
22341 (set_attr "mode" "TI")])
22342
22343 (define_insn "lshrv8hi3"
22344 [(set (match_operand:V8HI 0 "register_operand" "=x")
22345 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22346 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22347 "TARGET_SSE2"
22348 "psrlw\t{%2, %0|%0, %2}"
22349 [(set_attr "type" "sseishft")
22350 (set_attr "mode" "TI")])
22351
22352 (define_insn "lshrv4si3"
22353 [(set (match_operand:V4SI 0 "register_operand" "=x")
22354 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22355 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22356 "TARGET_SSE2"
22357 "psrld\t{%2, %0|%0, %2}"
22358 [(set_attr "type" "sseishft")
22359 (set_attr "mode" "TI")])
22360
22361 (define_insn "lshrv2di3"
22362 [(set (match_operand:V2DI 0 "register_operand" "=x")
22363 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22364 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22365 "TARGET_SSE2"
22366 "psrlq\t{%2, %0|%0, %2}"
22367 [(set_attr "type" "sseishft")
22368 (set_attr "mode" "TI")])
22369
22370 (define_insn "ashlv8hi3"
22371 [(set (match_operand:V8HI 0 "register_operand" "=x")
22372 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22373 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22374 "TARGET_SSE2"
22375 "psllw\t{%2, %0|%0, %2}"
22376 [(set_attr "type" "sseishft")
22377 (set_attr "mode" "TI")])
22378
22379 (define_insn "ashlv4si3"
22380 [(set (match_operand:V4SI 0 "register_operand" "=x")
22381 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22382 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22383 "TARGET_SSE2"
22384 "pslld\t{%2, %0|%0, %2}"
22385 [(set_attr "type" "sseishft")
22386 (set_attr "mode" "TI")])
22387
22388 (define_insn "ashlv2di3"
22389 [(set (match_operand:V2DI 0 "register_operand" "=x")
22390 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22391 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22392 "TARGET_SSE2"
22393 "psllq\t{%2, %0|%0, %2}"
22394 [(set_attr "type" "sseishft")
22395 (set_attr "mode" "TI")])
22396
22397 (define_insn "ashrv8hi3_ti"
22398 [(set (match_operand:V8HI 0 "register_operand" "=x")
22399 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22400 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22401 "TARGET_SSE2"
22402 "psraw\t{%2, %0|%0, %2}"
22403 [(set_attr "type" "sseishft")
22404 (set_attr "mode" "TI")])
22405
22406 (define_insn "ashrv4si3_ti"
22407 [(set (match_operand:V4SI 0 "register_operand" "=x")
22408 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22409 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22410 "TARGET_SSE2"
22411 "psrad\t{%2, %0|%0, %2}"
22412 [(set_attr "type" "sseishft")
22413 (set_attr "mode" "TI")])
22414
22415 (define_insn "lshrv8hi3_ti"
22416 [(set (match_operand:V8HI 0 "register_operand" "=x")
22417 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22418 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22419 "TARGET_SSE2"
22420 "psrlw\t{%2, %0|%0, %2}"
22421 [(set_attr "type" "sseishft")
22422 (set_attr "mode" "TI")])
22423
22424 (define_insn "lshrv4si3_ti"
22425 [(set (match_operand:V4SI 0 "register_operand" "=x")
22426 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22427 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22428 "TARGET_SSE2"
22429 "psrld\t{%2, %0|%0, %2}"
22430 [(set_attr "type" "sseishft")
22431 (set_attr "mode" "TI")])
22432
22433 (define_insn "lshrv2di3_ti"
22434 [(set (match_operand:V2DI 0 "register_operand" "=x")
22435 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22436 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22437 "TARGET_SSE2"
22438 "psrlq\t{%2, %0|%0, %2}"
22439 [(set_attr "type" "sseishft")
22440 (set_attr "mode" "TI")])
22441
22442 (define_insn "ashlv8hi3_ti"
22443 [(set (match_operand:V8HI 0 "register_operand" "=x")
22444 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22445 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22446 "TARGET_SSE2"
22447 "psllw\t{%2, %0|%0, %2}"
22448 [(set_attr "type" "sseishft")
22449 (set_attr "mode" "TI")])
22450
22451 (define_insn "ashlv4si3_ti"
22452 [(set (match_operand:V4SI 0 "register_operand" "=x")
22453 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22454 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22455 "TARGET_SSE2"
22456 "pslld\t{%2, %0|%0, %2}"
22457 [(set_attr "type" "sseishft")
22458 (set_attr "mode" "TI")])
22459
22460 (define_insn "ashlv2di3_ti"
22461 [(set (match_operand:V2DI 0 "register_operand" "=x")
22462 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22463 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22464 "TARGET_SSE2"
22465 "psllq\t{%2, %0|%0, %2}"
22466 [(set_attr "type" "sseishft")
22467 (set_attr "mode" "TI")])
22468
22469 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22470 ;; we wouldn't need here it since we never generate TImode arithmetic.
22471
22472 ;; There has to be some kind of prize for the weirdest new instruction...
22473 (define_insn "sse2_ashlti3"
22474 [(set (match_operand:TI 0 "register_operand" "=x")
22475 (unspec:TI
22476 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22477 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22478 (const_int 8)))] UNSPEC_NOP))]
22479 "TARGET_SSE2"
22480 "pslldq\t{%2, %0|%0, %2}"
22481 [(set_attr "type" "sseishft")
22482 (set_attr "mode" "TI")])
22483
22484 (define_insn "sse2_lshrti3"
22485 [(set (match_operand:TI 0 "register_operand" "=x")
22486 (unspec:TI
22487 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22488 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22489 (const_int 8)))] UNSPEC_NOP))]
22490 "TARGET_SSE2"
22491 "psrldq\t{%2, %0|%0, %2}"
22492 [(set_attr "type" "sseishft")
22493 (set_attr "mode" "TI")])
22494
22495 ;; SSE unpack
22496
22497 (define_insn "sse2_unpckhpd"
22498 [(set (match_operand:V2DF 0 "register_operand" "=x")
22499 (vec_concat:V2DF
22500 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22501 (parallel [(const_int 1)]))
22502 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22503 (parallel [(const_int 1)]))))]
22504 "TARGET_SSE2"
22505 "unpckhpd\t{%2, %0|%0, %2}"
22506 [(set_attr "type" "ssecvt")
22507 (set_attr "mode" "V2DF")])
22508
22509 (define_insn "sse2_unpcklpd"
22510 [(set (match_operand:V2DF 0 "register_operand" "=x")
22511 (vec_concat:V2DF
22512 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22513 (parallel [(const_int 0)]))
22514 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22515 (parallel [(const_int 0)]))))]
22516 "TARGET_SSE2"
22517 "unpcklpd\t{%2, %0|%0, %2}"
22518 [(set_attr "type" "ssecvt")
22519 (set_attr "mode" "V2DF")])
22520
22521 ;; MMX pack/unpack insns.
22522
22523 (define_insn "sse2_packsswb"
22524 [(set (match_operand:V16QI 0 "register_operand" "=x")
22525 (vec_concat:V16QI
22526 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22527 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22528 "TARGET_SSE2"
22529 "packsswb\t{%2, %0|%0, %2}"
22530 [(set_attr "type" "ssecvt")
22531 (set_attr "mode" "TI")])
22532
22533 (define_insn "sse2_packssdw"
22534 [(set (match_operand:V8HI 0 "register_operand" "=x")
22535 (vec_concat:V8HI
22536 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22537 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22538 "TARGET_SSE2"
22539 "packssdw\t{%2, %0|%0, %2}"
22540 [(set_attr "type" "ssecvt")
22541 (set_attr "mode" "TI")])
22542
22543 (define_insn "sse2_packuswb"
22544 [(set (match_operand:V16QI 0 "register_operand" "=x")
22545 (vec_concat:V16QI
22546 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22547 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22548 "TARGET_SSE2"
22549 "packuswb\t{%2, %0|%0, %2}"
22550 [(set_attr "type" "ssecvt")
22551 (set_attr "mode" "TI")])
22552
22553 (define_insn "sse2_punpckhbw"
22554 [(set (match_operand:V16QI 0 "register_operand" "=x")
22555 (vec_merge:V16QI
22556 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22557 (parallel [(const_int 8) (const_int 0)
22558 (const_int 9) (const_int 1)
22559 (const_int 10) (const_int 2)
22560 (const_int 11) (const_int 3)
22561 (const_int 12) (const_int 4)
22562 (const_int 13) (const_int 5)
22563 (const_int 14) (const_int 6)
22564 (const_int 15) (const_int 7)]))
22565 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22566 (parallel [(const_int 0) (const_int 8)
22567 (const_int 1) (const_int 9)
22568 (const_int 2) (const_int 10)
22569 (const_int 3) (const_int 11)
22570 (const_int 4) (const_int 12)
22571 (const_int 5) (const_int 13)
22572 (const_int 6) (const_int 14)
22573 (const_int 7) (const_int 15)]))
22574 (const_int 21845)))]
22575 "TARGET_SSE2"
22576 "punpckhbw\t{%2, %0|%0, %2}"
22577 [(set_attr "type" "ssecvt")
22578 (set_attr "mode" "TI")])
22579
22580 (define_insn "sse2_punpckhwd"
22581 [(set (match_operand:V8HI 0 "register_operand" "=x")
22582 (vec_merge:V8HI
22583 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22584 (parallel [(const_int 4) (const_int 0)
22585 (const_int 5) (const_int 1)
22586 (const_int 6) (const_int 2)
22587 (const_int 7) (const_int 3)]))
22588 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22589 (parallel [(const_int 0) (const_int 4)
22590 (const_int 1) (const_int 5)
22591 (const_int 2) (const_int 6)
22592 (const_int 3) (const_int 7)]))
22593 (const_int 85)))]
22594 "TARGET_SSE2"
22595 "punpckhwd\t{%2, %0|%0, %2}"
22596 [(set_attr "type" "ssecvt")
22597 (set_attr "mode" "TI")])
22598
22599 (define_insn "sse2_punpckhdq"
22600 [(set (match_operand:V4SI 0 "register_operand" "=x")
22601 (vec_merge:V4SI
22602 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22603 (parallel [(const_int 2) (const_int 0)
22604 (const_int 3) (const_int 1)]))
22605 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22606 (parallel [(const_int 0) (const_int 2)
22607 (const_int 1) (const_int 3)]))
22608 (const_int 5)))]
22609 "TARGET_SSE2"
22610 "punpckhdq\t{%2, %0|%0, %2}"
22611 [(set_attr "type" "ssecvt")
22612 (set_attr "mode" "TI")])
22613
22614 (define_insn "sse2_punpcklbw"
22615 [(set (match_operand:V16QI 0 "register_operand" "=x")
22616 (vec_merge:V16QI
22617 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22618 (parallel [(const_int 0) (const_int 8)
22619 (const_int 1) (const_int 9)
22620 (const_int 2) (const_int 10)
22621 (const_int 3) (const_int 11)
22622 (const_int 4) (const_int 12)
22623 (const_int 5) (const_int 13)
22624 (const_int 6) (const_int 14)
22625 (const_int 7) (const_int 15)]))
22626 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22627 (parallel [(const_int 8) (const_int 0)
22628 (const_int 9) (const_int 1)
22629 (const_int 10) (const_int 2)
22630 (const_int 11) (const_int 3)
22631 (const_int 12) (const_int 4)
22632 (const_int 13) (const_int 5)
22633 (const_int 14) (const_int 6)
22634 (const_int 15) (const_int 7)]))
22635 (const_int 21845)))]
22636 "TARGET_SSE2"
22637 "punpcklbw\t{%2, %0|%0, %2}"
22638 [(set_attr "type" "ssecvt")
22639 (set_attr "mode" "TI")])
22640
22641 (define_insn "sse2_punpcklwd"
22642 [(set (match_operand:V8HI 0 "register_operand" "=x")
22643 (vec_merge:V8HI
22644 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22645 (parallel [(const_int 0) (const_int 4)
22646 (const_int 1) (const_int 5)
22647 (const_int 2) (const_int 6)
22648 (const_int 3) (const_int 7)]))
22649 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22650 (parallel [(const_int 4) (const_int 0)
22651 (const_int 5) (const_int 1)
22652 (const_int 6) (const_int 2)
22653 (const_int 7) (const_int 3)]))
22654 (const_int 85)))]
22655 "TARGET_SSE2"
22656 "punpcklwd\t{%2, %0|%0, %2}"
22657 [(set_attr "type" "ssecvt")
22658 (set_attr "mode" "TI")])
22659
22660 (define_insn "sse2_punpckldq"
22661 [(set (match_operand:V4SI 0 "register_operand" "=x")
22662 (vec_merge:V4SI
22663 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22664 (parallel [(const_int 0) (const_int 2)
22665 (const_int 1) (const_int 3)]))
22666 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22667 (parallel [(const_int 2) (const_int 0)
22668 (const_int 3) (const_int 1)]))
22669 (const_int 5)))]
22670 "TARGET_SSE2"
22671 "punpckldq\t{%2, %0|%0, %2}"
22672 [(set_attr "type" "ssecvt")
22673 (set_attr "mode" "TI")])
22674
22675 (define_insn "sse2_punpcklqdq"
22676 [(set (match_operand:V2DI 0 "register_operand" "=x")
22677 (vec_merge:V2DI
22678 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22679 (parallel [(const_int 1)
22680 (const_int 0)]))
22681 (match_operand:V2DI 1 "register_operand" "0")
22682 (const_int 1)))]
22683 "TARGET_SSE2"
22684 "punpcklqdq\t{%2, %0|%0, %2}"
22685 [(set_attr "type" "ssecvt")
22686 (set_attr "mode" "TI")])
22687
22688 (define_insn "sse2_punpckhqdq"
22689 [(set (match_operand:V2DI 0 "register_operand" "=x")
22690 (vec_merge:V2DI
22691 (match_operand:V2DI 1 "register_operand" "0")
22692 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22693 (parallel [(const_int 1)
22694 (const_int 0)]))
22695 (const_int 1)))]
22696 "TARGET_SSE2"
22697 "punpckhqdq\t{%2, %0|%0, %2}"
22698 [(set_attr "type" "ssecvt")
22699 (set_attr "mode" "TI")])
22700
22701 ;; SSE2 moves
22702
22703 (define_insn "sse2_movapd"
22704 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22705 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22706 UNSPEC_MOVA))]
22707 "TARGET_SSE2
22708 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22709 "movapd\t{%1, %0|%0, %1}"
22710 [(set_attr "type" "ssemov")
22711 (set_attr "mode" "V2DF")])
22712
22713 (define_insn "sse2_movupd"
22714 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22715 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22716 UNSPEC_MOVU))]
22717 "TARGET_SSE2
22718 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22719 "movupd\t{%1, %0|%0, %1}"
22720 [(set_attr "type" "ssecvt")
22721 (set_attr "mode" "V2DF")])
22722
22723 (define_insn "sse2_movdqa"
22724 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22725 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22726 UNSPEC_MOVA))]
22727 "TARGET_SSE2
22728 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22729 "movdqa\t{%1, %0|%0, %1}"
22730 [(set_attr "type" "ssemov")
22731 (set_attr "mode" "TI")])
22732
22733 (define_insn "sse2_movdqu"
22734 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22735 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22736 UNSPEC_MOVU))]
22737 "TARGET_SSE2
22738 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22739 "movdqu\t{%1, %0|%0, %1}"
22740 [(set_attr "type" "ssecvt")
22741 (set_attr "mode" "TI")])
22742
22743 (define_insn "sse2_movdq2q"
22744 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22745 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22746 (parallel [(const_int 0)])))]
22747 "TARGET_SSE2 && !TARGET_64BIT"
22748 "@
22749 movq\t{%1, %0|%0, %1}
22750 movdq2q\t{%1, %0|%0, %1}"
22751 [(set_attr "type" "ssecvt")
22752 (set_attr "mode" "TI")])
22753
22754 (define_insn "sse2_movdq2q_rex64"
22755 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22756 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22757 (parallel [(const_int 0)])))]
22758 "TARGET_SSE2 && TARGET_64BIT"
22759 "@
22760 movq\t{%1, %0|%0, %1}
22761 movdq2q\t{%1, %0|%0, %1}
22762 movd\t{%1, %0|%0, %1}"
22763 [(set_attr "type" "ssecvt")
22764 (set_attr "mode" "TI")])
22765
22766 (define_insn "sse2_movq2dq"
22767 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22768 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22769 (const_int 0)))]
22770 "TARGET_SSE2 && !TARGET_64BIT"
22771 "@
22772 movq\t{%1, %0|%0, %1}
22773 movq2dq\t{%1, %0|%0, %1}"
22774 [(set_attr "type" "ssecvt,ssemov")
22775 (set_attr "mode" "TI")])
22776
22777 (define_insn "sse2_movq2dq_rex64"
22778 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22779 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22780 (const_int 0)))]
22781 "TARGET_SSE2 && TARGET_64BIT"
22782 "@
22783 movq\t{%1, %0|%0, %1}
22784 movq2dq\t{%1, %0|%0, %1}
22785 movd\t{%1, %0|%0, %1}"
22786 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22787 (set_attr "mode" "TI")])
22788
22789 (define_insn "sse2_movq"
22790 [(set (match_operand:V2DI 0 "register_operand" "=x")
22791 (vec_concat:V2DI (vec_select:DI
22792 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22793 (parallel [(const_int 0)]))
22794 (const_int 0)))]
22795 "TARGET_SSE2"
22796 "movq\t{%1, %0|%0, %1}"
22797 [(set_attr "type" "ssemov")
22798 (set_attr "mode" "TI")])
22799
22800 (define_insn "sse2_loadd"
22801 [(set (match_operand:V4SI 0 "register_operand" "=x")
22802 (vec_merge:V4SI
22803 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22804 (const_vector:V4SI [(const_int 0)
22805 (const_int 0)
22806 (const_int 0)
22807 (const_int 0)])
22808 (const_int 1)))]
22809 "TARGET_SSE2"
22810 "movd\t{%1, %0|%0, %1}"
22811 [(set_attr "type" "ssemov")
22812 (set_attr "mode" "TI")])
22813
22814 (define_insn "sse2_stored"
22815 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22816 (vec_select:SI
22817 (match_operand:V4SI 1 "register_operand" "x")
22818 (parallel [(const_int 0)])))]
22819 "TARGET_SSE2"
22820 "movd\t{%1, %0|%0, %1}"
22821 [(set_attr "type" "ssemov")
22822 (set_attr "mode" "TI")])
22823
22824 (define_insn "sse2_movhpd"
22825 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22826 (vec_merge:V2DF
22827 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22828 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22829 (const_int 2)))]
22830 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22831 "movhpd\t{%2, %0|%0, %2}"
22832 [(set_attr "type" "ssecvt")
22833 (set_attr "mode" "V2DF")])
22834
22835 (define_expand "sse2_loadsd"
22836 [(match_operand:V2DF 0 "register_operand" "")
22837 (match_operand:DF 1 "memory_operand" "")]
22838 "TARGET_SSE2"
22839 {
22840 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22841 CONST0_RTX (V2DFmode)));
22842 DONE;
22843 })
22844
22845 (define_insn "sse2_loadsd_1"
22846 [(set (match_operand:V2DF 0 "register_operand" "=x")
22847 (vec_merge:V2DF
22848 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22849 (match_operand:V2DF 2 "const0_operand" "X")
22850 (const_int 1)))]
22851 "TARGET_SSE2"
22852 "movsd\t{%1, %0|%0, %1}"
22853 [(set_attr "type" "ssecvt")
22854 (set_attr "mode" "DF")])
22855
22856 (define_insn "sse2_movsd"
22857 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22858 (vec_merge:V2DF
22859 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22860 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22861 (const_int 1)))]
22862 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22863 "@movsd\t{%2, %0|%0, %2}
22864 movlpd\t{%2, %0|%0, %2}
22865 movlpd\t{%2, %0|%0, %2}"
22866 [(set_attr "type" "ssecvt")
22867 (set_attr "mode" "DF,V2DF,V2DF")])
22868
22869 (define_insn "sse2_storesd"
22870 [(set (match_operand:DF 0 "memory_operand" "=m")
22871 (vec_select:DF
22872 (match_operand:V2DF 1 "register_operand" "x")
22873 (parallel [(const_int 0)])))]
22874 "TARGET_SSE2"
22875 "movsd\t{%1, %0|%0, %1}"
22876 [(set_attr "type" "ssecvt")
22877 (set_attr "mode" "DF")])
22878
22879 (define_insn "sse2_shufpd"
22880 [(set (match_operand:V2DF 0 "register_operand" "=x")
22881 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22882 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22883 (match_operand:SI 3 "immediate_operand" "i")]
22884 UNSPEC_SHUFFLE))]
22885 "TARGET_SSE2"
22886 ;; @@@ check operand order for intel/nonintel syntax
22887 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22888 [(set_attr "type" "ssecvt")
22889 (set_attr "mode" "V2DF")])
22890
22891 (define_insn "sse2_clflush"
22892 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22893 UNSPECV_CLFLUSH)]
22894 "TARGET_SSE2"
22895 "clflush %0"
22896 [(set_attr "type" "sse")
22897 (set_attr "memory" "unknown")])
22898
22899 (define_expand "sse2_mfence"
22900 [(set (match_dup 0)
22901 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22902 "TARGET_SSE2"
22903 {
22904 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22905 MEM_VOLATILE_P (operands[0]) = 1;
22906 })
22907
22908 (define_insn "*mfence_insn"
22909 [(set (match_operand:BLK 0 "" "")
22910 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22911 "TARGET_SSE2"
22912 "mfence"
22913 [(set_attr "type" "sse")
22914 (set_attr "memory" "unknown")])
22915
22916 (define_expand "sse2_lfence"
22917 [(set (match_dup 0)
22918 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22919 "TARGET_SSE2"
22920 {
22921 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22922 MEM_VOLATILE_P (operands[0]) = 1;
22923 })
22924
22925 (define_insn "*lfence_insn"
22926 [(set (match_operand:BLK 0 "" "")
22927 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22928 "TARGET_SSE2"
22929 "lfence"
22930 [(set_attr "type" "sse")
22931 (set_attr "memory" "unknown")])
22932
22933 ;; SSE3
22934
22935 (define_insn "mwait"
22936 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22937 (match_operand:SI 1 "register_operand" "c")]
22938 UNSPECV_MWAIT)]
22939 "TARGET_SSE3"
22940 "mwait\t%0, %1"
22941 [(set_attr "length" "3")])
22942
22943 (define_insn "monitor"
22944 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22945 (match_operand:SI 1 "register_operand" "c")
22946 (match_operand:SI 2 "register_operand" "d")]
22947 UNSPECV_MONITOR)]
22948 "TARGET_SSE3"
22949 "monitor\t%0, %1, %2"
22950 [(set_attr "length" "3")])
22951
22952 ;; SSE3 arithmetic
22953
22954 (define_insn "addsubv4sf3"
22955 [(set (match_operand:V4SF 0 "register_operand" "=x")
22956 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22957 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22958 UNSPEC_ADDSUB))]
22959 "TARGET_SSE3"
22960 "addsubps\t{%2, %0|%0, %2}"
22961 [(set_attr "type" "sseadd")
22962 (set_attr "mode" "V4SF")])
22963
22964 (define_insn "addsubv2df3"
22965 [(set (match_operand:V2DF 0 "register_operand" "=x")
22966 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22967 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22968 UNSPEC_ADDSUB))]
22969 "TARGET_SSE3"
22970 "addsubpd\t{%2, %0|%0, %2}"
22971 [(set_attr "type" "sseadd")
22972 (set_attr "mode" "V2DF")])
22973
22974 (define_insn "haddv4sf3"
22975 [(set (match_operand:V4SF 0 "register_operand" "=x")
22976 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22977 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22978 UNSPEC_HADD))]
22979 "TARGET_SSE3"
22980 "haddps\t{%2, %0|%0, %2}"
22981 [(set_attr "type" "sseadd")
22982 (set_attr "mode" "V4SF")])
22983
22984 (define_insn "haddv2df3"
22985 [(set (match_operand:V2DF 0 "register_operand" "=x")
22986 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22987 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22988 UNSPEC_HADD))]
22989 "TARGET_SSE3"
22990 "haddpd\t{%2, %0|%0, %2}"
22991 [(set_attr "type" "sseadd")
22992 (set_attr "mode" "V2DF")])
22993
22994 (define_insn "hsubv4sf3"
22995 [(set (match_operand:V4SF 0 "register_operand" "=x")
22996 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22997 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22998 UNSPEC_HSUB))]
22999 "TARGET_SSE3"
23000 "hsubps\t{%2, %0|%0, %2}"
23001 [(set_attr "type" "sseadd")
23002 (set_attr "mode" "V4SF")])
23003
23004 (define_insn "hsubv2df3"
23005 [(set (match_operand:V2DF 0 "register_operand" "=x")
23006 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23007 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23008 UNSPEC_HSUB))]
23009 "TARGET_SSE3"
23010 "hsubpd\t{%2, %0|%0, %2}"
23011 [(set_attr "type" "sseadd")
23012 (set_attr "mode" "V2DF")])
23013
23014 (define_insn "movshdup"
23015 [(set (match_operand:V4SF 0 "register_operand" "=x")
23016 (unspec:V4SF
23017 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23018 "TARGET_SSE3"
23019 "movshdup\t{%1, %0|%0, %1}"
23020 [(set_attr "type" "sse")
23021 (set_attr "mode" "V4SF")])
23022
23023 (define_insn "movsldup"
23024 [(set (match_operand:V4SF 0 "register_operand" "=x")
23025 (unspec:V4SF
23026 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23027 "TARGET_SSE3"
23028 "movsldup\t{%1, %0|%0, %1}"
23029 [(set_attr "type" "sse")
23030 (set_attr "mode" "V4SF")])
23031
23032 (define_insn "lddqu"
23033 [(set (match_operand:V16QI 0 "register_operand" "=x")
23034 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23035 UNSPEC_LDQQU))]
23036 "TARGET_SSE3"
23037 "lddqu\t{%1, %0|%0, %1}"
23038 [(set_attr "type" "ssecvt")
23039 (set_attr "mode" "TI")])
23040
23041 (define_insn "loadddup"
23042 [(set (match_operand:V2DF 0 "register_operand" "=x")
23043 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23044 "TARGET_SSE3"
23045 "movddup\t{%1, %0|%0, %1}"
23046 [(set_attr "type" "ssecvt")
23047 (set_attr "mode" "DF")])
23048
23049 (define_insn "movddup"
23050 [(set (match_operand:V2DF 0 "register_operand" "=x")
23051 (vec_duplicate:V2DF
23052 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23053 (parallel [(const_int 0)]))))]
23054 "TARGET_SSE3"
23055 "movddup\t{%1, %0|%0, %1}"
23056 [(set_attr "type" "ssecvt")
23057 (set_attr "mode" "DF")])