doloop.c, [...]: Use const0_rtx instead of GEN_INT (0).
[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 (subreg:TI (match_dup 0) 0)
9661 (xor:TI (match_dup 1)
9662 (match_dup 2)))]
9663 {
9664 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9665 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 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 (subreg:TI (match_dup 0) 0)
9829 (xor:TI (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 (TImode, operands[1], DFmode, 0);
9834 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
9835 /* Avoid possible reformatting on the operands. */
9836 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9837 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9838 if (operands_match_p (operands[0], operands[2]))
9839 {
9840 rtx tmp;
9841 tmp = operands[1];
9842 operands[1] = operands[2];
9843 operands[2] = tmp;
9844 }
9845 })
9846
9847 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9848 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9849 ;; to itself.
9850 (define_insn "*negdf2_if"
9851 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9852 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9853 (clobber (reg:CC 17))]
9854 "!TARGET_64BIT && TARGET_80387
9855 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9856 "#")
9857
9858 ;; FIXME: We should to allow integer registers here. Problem is that
9859 ;; we need another scratch register to get constant from.
9860 ;; Forcing constant to mem if no register available in peep2 should be
9861 ;; safe even for PIC mode, because of RIP relative addressing.
9862 (define_insn "*negdf2_if_rex64"
9863 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9864 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9865 (clobber (reg:CC 17))]
9866 "TARGET_64BIT && TARGET_80387
9867 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9868 "#")
9869
9870 (define_split
9871 [(set (match_operand:DF 0 "fp_register_operand" "")
9872 (neg:DF (match_operand:DF 1 "register_operand" "")))
9873 (clobber (reg:CC 17))]
9874 "TARGET_80387 && reload_completed"
9875 [(set (match_dup 0)
9876 (neg:DF (match_dup 1)))]
9877 "")
9878
9879 (define_split
9880 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9881 (neg:DF (match_operand:DF 1 "register_operand" "")))
9882 (clobber (reg:CC 17))]
9883 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9884 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9885 (clobber (reg:CC 17))])]
9886 "operands[4] = gen_int_mode (0x80000000, SImode);
9887 split_di (operands+0, 1, operands+2, operands+3);")
9888
9889 (define_expand "negxf2"
9890 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9891 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9892 (clobber (reg:CC 17))])]
9893 "TARGET_80387"
9894 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9895
9896 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9897 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9898 ;; to itself.
9899 (define_insn "*negxf2_if"
9900 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9901 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9902 (clobber (reg:CC 17))]
9903 "TARGET_80387
9904 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9905 "#")
9906
9907 (define_split
9908 [(set (match_operand:XF 0 "fp_register_operand" "")
9909 (neg:XF (match_operand:XF 1 "register_operand" "")))
9910 (clobber (reg:CC 17))]
9911 "TARGET_80387 && reload_completed"
9912 [(set (match_dup 0)
9913 (neg:XF (match_dup 1)))]
9914 "")
9915
9916 (define_split
9917 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9918 (neg:XF (match_operand:XF 1 "register_operand" "")))
9919 (clobber (reg:CC 17))]
9920 "TARGET_80387 && reload_completed"
9921 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9922 (clobber (reg:CC 17))])]
9923 "operands[1] = GEN_INT (0x8000);
9924 operands[0] = gen_rtx_REG (SImode,
9925 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9926
9927 ;; Conditionalize these after reload. If they matches before reload, we
9928 ;; lose the clobber and ability to use integer instructions.
9929
9930 (define_insn "*negsf2_1"
9931 [(set (match_operand:SF 0 "register_operand" "=f")
9932 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9933 "TARGET_80387 && reload_completed"
9934 "fchs"
9935 [(set_attr "type" "fsgn")
9936 (set_attr "mode" "SF")
9937 (set_attr "ppro_uops" "few")])
9938
9939 (define_insn "*negdf2_1"
9940 [(set (match_operand:DF 0 "register_operand" "=f")
9941 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9942 "TARGET_80387 && reload_completed"
9943 "fchs"
9944 [(set_attr "type" "fsgn")
9945 (set_attr "mode" "DF")
9946 (set_attr "ppro_uops" "few")])
9947
9948 (define_insn "*negextendsfdf2"
9949 [(set (match_operand:DF 0 "register_operand" "=f")
9950 (neg:DF (float_extend:DF
9951 (match_operand:SF 1 "register_operand" "0"))))]
9952 "TARGET_80387"
9953 "fchs"
9954 [(set_attr "type" "fsgn")
9955 (set_attr "mode" "DF")
9956 (set_attr "ppro_uops" "few")])
9957
9958 (define_insn "*negxf2_1"
9959 [(set (match_operand:XF 0 "register_operand" "=f")
9960 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9961 "TARGET_80387 && reload_completed"
9962 "fchs"
9963 [(set_attr "type" "fsgn")
9964 (set_attr "mode" "XF")
9965 (set_attr "ppro_uops" "few")])
9966
9967 (define_insn "*negextenddfxf2"
9968 [(set (match_operand:XF 0 "register_operand" "=f")
9969 (neg:XF (float_extend:XF
9970 (match_operand:DF 1 "register_operand" "0"))))]
9971 "TARGET_80387"
9972 "fchs"
9973 [(set_attr "type" "fsgn")
9974 (set_attr "mode" "XF")
9975 (set_attr "ppro_uops" "few")])
9976
9977 (define_insn "*negextendsfxf2"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (float_extend:XF
9980 (match_operand:SF 1 "register_operand" "0"))))]
9981 "TARGET_80387"
9982 "fchs"
9983 [(set_attr "type" "fsgn")
9984 (set_attr "mode" "XF")
9985 (set_attr "ppro_uops" "few")])
9986 \f
9987 ;; Absolute value instructions
9988
9989 (define_expand "abssf2"
9990 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9991 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9992 (clobber (reg:CC 17))])]
9993 "TARGET_80387"
9994 "if (TARGET_SSE)
9995 {
9996 /* In case operand is in memory, we will not use SSE. */
9997 if (memory_operand (operands[0], VOIDmode)
9998 && rtx_equal_p (operands[0], operands[1]))
9999 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10000 else
10001 {
10002 /* Using SSE is tricky, since we need bitwise negation of -0
10003 in register. */
10004 rtx reg = gen_reg_rtx (V4SFmode);
10005 rtx dest = operands[0];
10006 rtx imm;
10007
10008 operands[1] = force_reg (SFmode, operands[1]);
10009 operands[0] = force_reg (SFmode, operands[0]);
10010 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10011 reg = force_reg (V4SFmode,
10012 gen_rtx_CONST_VECTOR (V4SFmode,
10013 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10014 CONST0_RTX (SFmode),
10015 CONST0_RTX (SFmode))));
10016 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10017 if (dest != operands[0])
10018 emit_move_insn (dest, operands[0]);
10019 }
10020 DONE;
10021 }
10022 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10023
10024 (define_insn "abssf2_memory"
10025 [(set (match_operand:SF 0 "memory_operand" "=m")
10026 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10027 (clobber (reg:CC 17))]
10028 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10029 "#")
10030
10031 (define_insn "abssf2_ifs"
10032 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10033 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10034 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10035 (clobber (reg:CC 17))]
10036 "TARGET_SSE
10037 && (reload_in_progress || reload_completed
10038 || (register_operand (operands[0], VOIDmode)
10039 && register_operand (operands[1], VOIDmode)))"
10040 "#")
10041
10042 (define_split
10043 [(set (match_operand:SF 0 "memory_operand" "")
10044 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10045 (use (match_operand:V4SF 2 "" ""))
10046 (clobber (reg:CC 17))]
10047 ""
10048 [(parallel [(set (match_dup 0)
10049 (abs:SF (match_dup 1)))
10050 (clobber (reg:CC 17))])])
10051
10052 (define_split
10053 [(set (match_operand:SF 0 "register_operand" "")
10054 (abs:SF (match_operand:SF 1 "register_operand" "")))
10055 (use (match_operand:V4SF 2 "" ""))
10056 (clobber (reg:CC 17))]
10057 "reload_completed && !SSE_REG_P (operands[0])"
10058 [(parallel [(set (match_dup 0)
10059 (abs:SF (match_dup 1)))
10060 (clobber (reg:CC 17))])])
10061
10062 (define_split
10063 [(set (match_operand:SF 0 "register_operand" "")
10064 (abs:SF (match_operand:SF 1 "register_operand" "")))
10065 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10066 (clobber (reg:CC 17))]
10067 "reload_completed && SSE_REG_P (operands[0])"
10068 [(set (subreg:TI (match_dup 0) 0)
10069 (and:TI (match_dup 1)
10070 (match_dup 2)))]
10071 {
10072 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10073 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10074 if (operands_match_p (operands[0], operands[2]))
10075 {
10076 rtx tmp;
10077 tmp = operands[1];
10078 operands[1] = operands[2];
10079 operands[2] = tmp;
10080 }
10081 })
10082
10083 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10084 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10085 ;; to itself.
10086 (define_insn "*abssf2_if"
10087 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10088 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10089 (clobber (reg:CC 17))]
10090 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10091 "#")
10092
10093 (define_split
10094 [(set (match_operand:SF 0 "fp_register_operand" "")
10095 (abs:SF (match_operand:SF 1 "register_operand" "")))
10096 (clobber (reg:CC 17))]
10097 "TARGET_80387 && reload_completed"
10098 [(set (match_dup 0)
10099 (abs:SF (match_dup 1)))]
10100 "")
10101
10102 (define_split
10103 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10104 (abs:SF (match_operand:SF 1 "register_operand" "")))
10105 (clobber (reg:CC 17))]
10106 "TARGET_80387 && reload_completed"
10107 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10108 (clobber (reg:CC 17))])]
10109 "operands[1] = gen_int_mode (~0x80000000, SImode);
10110 operands[0] = gen_lowpart (SImode, operands[0]);")
10111
10112 (define_split
10113 [(set (match_operand 0 "memory_operand" "")
10114 (abs (match_operand 1 "memory_operand" "")))
10115 (clobber (reg:CC 17))]
10116 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10117 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10118 (clobber (reg:CC 17))])]
10119 {
10120 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10121
10122 if (GET_MODE (operands[1]) == XFmode)
10123 size = 10;
10124 operands[0] = adjust_address (operands[0], QImode, size - 1);
10125 operands[1] = gen_int_mode (~0x80, QImode);
10126 })
10127
10128 (define_expand "absdf2"
10129 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10130 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10131 (clobber (reg:CC 17))])]
10132 "TARGET_80387"
10133 "if (TARGET_SSE2)
10134 {
10135 /* In case operand is in memory, we will not use SSE. */
10136 if (memory_operand (operands[0], VOIDmode)
10137 && rtx_equal_p (operands[0], operands[1]))
10138 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10139 else
10140 {
10141 /* Using SSE is tricky, since we need bitwise negation of -0
10142 in register. */
10143 rtx reg = gen_reg_rtx (V2DFmode);
10144 #if HOST_BITS_PER_WIDE_INT >= 64
10145 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10146 #else
10147 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10148 #endif
10149 rtx dest = operands[0];
10150
10151 operands[1] = force_reg (DFmode, operands[1]);
10152 operands[0] = force_reg (DFmode, operands[0]);
10153
10154 /* Produce LONG_DOUBLE with the proper immediate argument. */
10155 imm = gen_lowpart (DFmode, imm);
10156 reg = force_reg (V2DFmode,
10157 gen_rtx_CONST_VECTOR (V2DFmode,
10158 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10159 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10160 if (dest != operands[0])
10161 emit_move_insn (dest, operands[0]);
10162 }
10163 DONE;
10164 }
10165 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10166
10167 (define_insn "absdf2_memory"
10168 [(set (match_operand:DF 0 "memory_operand" "=m")
10169 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10170 (clobber (reg:CC 17))]
10171 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10172 "#")
10173
10174 (define_insn "absdf2_ifs"
10175 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10176 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10177 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10178 (clobber (reg:CC 17))]
10179 "!TARGET_64BIT && TARGET_SSE2
10180 && (reload_in_progress || reload_completed
10181 || (register_operand (operands[0], VOIDmode)
10182 && register_operand (operands[1], VOIDmode)))"
10183 "#")
10184
10185 (define_insn "*absdf2_ifs_rex64"
10186 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10187 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10188 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10189 (clobber (reg:CC 17))]
10190 "TARGET_64BIT && TARGET_SSE2
10191 && (reload_in_progress || reload_completed
10192 || (register_operand (operands[0], VOIDmode)
10193 && register_operand (operands[1], VOIDmode)))"
10194 "#")
10195
10196 (define_split
10197 [(set (match_operand:DF 0 "memory_operand" "")
10198 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10199 (use (match_operand:V2DF 2 "" ""))
10200 (clobber (reg:CC 17))]
10201 ""
10202 [(parallel [(set (match_dup 0)
10203 (abs:DF (match_dup 1)))
10204 (clobber (reg:CC 17))])])
10205
10206 (define_split
10207 [(set (match_operand:DF 0 "register_operand" "")
10208 (abs:DF (match_operand:DF 1 "register_operand" "")))
10209 (use (match_operand:V2DF 2 "" ""))
10210 (clobber (reg:CC 17))]
10211 "reload_completed && !SSE_REG_P (operands[0])"
10212 [(parallel [(set (match_dup 0)
10213 (abs:DF (match_dup 1)))
10214 (clobber (reg:CC 17))])])
10215
10216 (define_split
10217 [(set (match_operand:DF 0 "register_operand" "")
10218 (abs:DF (match_operand:DF 1 "register_operand" "")))
10219 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10220 (clobber (reg:CC 17))]
10221 "reload_completed && SSE_REG_P (operands[0])"
10222 [(set (subreg:TI (match_dup 0) 0)
10223 (and:TI (match_dup 1)
10224 (match_dup 2)))]
10225 {
10226 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10227 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10228 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10229 /* Avoid possible reformatting on the operands. */
10230 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10231 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10232 if (operands_match_p (operands[0], operands[2]))
10233 {
10234 rtx tmp;
10235 tmp = operands[1];
10236 operands[1] = operands[2];
10237 operands[2] = tmp;
10238 }
10239 })
10240
10241
10242 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10243 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10244 ;; to itself.
10245 (define_insn "*absdf2_if"
10246 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10247 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10248 (clobber (reg:CC 17))]
10249 "!TARGET_64BIT && TARGET_80387
10250 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10251 "#")
10252
10253 ;; FIXME: We should to allow integer registers here. Problem is that
10254 ;; we need another scratch register to get constant from.
10255 ;; Forcing constant to mem if no register available in peep2 should be
10256 ;; safe even for PIC mode, because of RIP relative addressing.
10257 (define_insn "*absdf2_if_rex64"
10258 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10259 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10260 (clobber (reg:CC 17))]
10261 "TARGET_64BIT && TARGET_80387
10262 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10263 "#")
10264
10265 (define_split
10266 [(set (match_operand:DF 0 "fp_register_operand" "")
10267 (abs:DF (match_operand:DF 1 "register_operand" "")))
10268 (clobber (reg:CC 17))]
10269 "TARGET_80387 && reload_completed"
10270 [(set (match_dup 0)
10271 (abs:DF (match_dup 1)))]
10272 "")
10273
10274 (define_split
10275 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10276 (abs:DF (match_operand:DF 1 "register_operand" "")))
10277 (clobber (reg:CC 17))]
10278 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10279 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10280 (clobber (reg:CC 17))])]
10281 "operands[4] = gen_int_mode (~0x80000000, SImode);
10282 split_di (operands+0, 1, operands+2, operands+3);")
10283
10284 (define_expand "absxf2"
10285 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10286 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10287 (clobber (reg:CC 17))])]
10288 "TARGET_80387"
10289 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10290
10291 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10292 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10293 ;; to itself.
10294 (define_insn "*absxf2_if"
10295 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10296 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10297 (clobber (reg:CC 17))]
10298 "TARGET_80387
10299 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10300 "#")
10301
10302 (define_split
10303 [(set (match_operand:XF 0 "fp_register_operand" "")
10304 (abs:XF (match_operand:XF 1 "register_operand" "")))
10305 (clobber (reg:CC 17))]
10306 "TARGET_80387 && reload_completed"
10307 [(set (match_dup 0)
10308 (abs:XF (match_dup 1)))]
10309 "")
10310
10311 (define_split
10312 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10313 (abs:XF (match_operand:XF 1 "register_operand" "")))
10314 (clobber (reg:CC 17))]
10315 "TARGET_80387 && reload_completed"
10316 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10317 (clobber (reg:CC 17))])]
10318 "operands[1] = GEN_INT (~0x8000);
10319 operands[0] = gen_rtx_REG (SImode,
10320 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10321
10322 (define_insn "*abssf2_1"
10323 [(set (match_operand:SF 0 "register_operand" "=f")
10324 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10325 "TARGET_80387 && reload_completed"
10326 "fabs"
10327 [(set_attr "type" "fsgn")
10328 (set_attr "mode" "SF")])
10329
10330 (define_insn "*absdf2_1"
10331 [(set (match_operand:DF 0 "register_operand" "=f")
10332 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10333 "TARGET_80387 && reload_completed"
10334 "fabs"
10335 [(set_attr "type" "fsgn")
10336 (set_attr "mode" "DF")])
10337
10338 (define_insn "*absextendsfdf2"
10339 [(set (match_operand:DF 0 "register_operand" "=f")
10340 (abs:DF (float_extend:DF
10341 (match_operand:SF 1 "register_operand" "0"))))]
10342 "TARGET_80387"
10343 "fabs"
10344 [(set_attr "type" "fsgn")
10345 (set_attr "mode" "DF")])
10346
10347 (define_insn "*absxf2_1"
10348 [(set (match_operand:XF 0 "register_operand" "=f")
10349 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10350 "TARGET_80387 && reload_completed"
10351 "fabs"
10352 [(set_attr "type" "fsgn")
10353 (set_attr "mode" "DF")])
10354
10355 (define_insn "*absextenddfxf2"
10356 [(set (match_operand:XF 0 "register_operand" "=f")
10357 (abs:XF (float_extend:XF
10358 (match_operand:DF 1 "register_operand" "0"))))]
10359 "TARGET_80387"
10360 "fabs"
10361 [(set_attr "type" "fsgn")
10362 (set_attr "mode" "XF")])
10363
10364 (define_insn "*absextendsfxf2"
10365 [(set (match_operand:XF 0 "register_operand" "=f")
10366 (abs:XF (float_extend:XF
10367 (match_operand:SF 1 "register_operand" "0"))))]
10368 "TARGET_80387"
10369 "fabs"
10370 [(set_attr "type" "fsgn")
10371 (set_attr "mode" "XF")])
10372 \f
10373 ;; One complement instructions
10374
10375 (define_expand "one_cmpldi2"
10376 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10377 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10378 "TARGET_64BIT"
10379 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10380
10381 (define_insn "*one_cmpldi2_1_rex64"
10382 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10383 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10384 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10385 "not{q}\t%0"
10386 [(set_attr "type" "negnot")
10387 (set_attr "mode" "DI")])
10388
10389 (define_insn "*one_cmpldi2_2_rex64"
10390 [(set (reg 17)
10391 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10392 (const_int 0)))
10393 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10394 (not:DI (match_dup 1)))]
10395 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10396 && ix86_unary_operator_ok (NOT, DImode, operands)"
10397 "#"
10398 [(set_attr "type" "alu1")
10399 (set_attr "mode" "DI")])
10400
10401 (define_split
10402 [(set (reg 17)
10403 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10404 (const_int 0)))
10405 (set (match_operand:DI 0 "nonimmediate_operand" "")
10406 (not:DI (match_dup 1)))]
10407 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10408 [(parallel [(set (reg:CCNO 17)
10409 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10410 (const_int 0)))
10411 (set (match_dup 0)
10412 (xor:DI (match_dup 1) (const_int -1)))])]
10413 "")
10414
10415 (define_expand "one_cmplsi2"
10416 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10417 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10418 ""
10419 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10420
10421 (define_insn "*one_cmplsi2_1"
10422 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10423 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10424 "ix86_unary_operator_ok (NOT, SImode, operands)"
10425 "not{l}\t%0"
10426 [(set_attr "type" "negnot")
10427 (set_attr "mode" "SI")])
10428
10429 ;; ??? Currently never generated - xor is used instead.
10430 (define_insn "*one_cmplsi2_1_zext"
10431 [(set (match_operand:DI 0 "register_operand" "=r")
10432 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10433 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10434 "not{l}\t%k0"
10435 [(set_attr "type" "negnot")
10436 (set_attr "mode" "SI")])
10437
10438 (define_insn "*one_cmplsi2_2"
10439 [(set (reg 17)
10440 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10441 (const_int 0)))
10442 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10443 (not:SI (match_dup 1)))]
10444 "ix86_match_ccmode (insn, CCNOmode)
10445 && ix86_unary_operator_ok (NOT, SImode, operands)"
10446 "#"
10447 [(set_attr "type" "alu1")
10448 (set_attr "mode" "SI")])
10449
10450 (define_split
10451 [(set (reg 17)
10452 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10453 (const_int 0)))
10454 (set (match_operand:SI 0 "nonimmediate_operand" "")
10455 (not:SI (match_dup 1)))]
10456 "ix86_match_ccmode (insn, CCNOmode)"
10457 [(parallel [(set (reg:CCNO 17)
10458 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10459 (const_int 0)))
10460 (set (match_dup 0)
10461 (xor:SI (match_dup 1) (const_int -1)))])]
10462 "")
10463
10464 ;; ??? Currently never generated - xor is used instead.
10465 (define_insn "*one_cmplsi2_2_zext"
10466 [(set (reg 17)
10467 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10468 (const_int 0)))
10469 (set (match_operand:DI 0 "register_operand" "=r")
10470 (zero_extend:DI (not:SI (match_dup 1))))]
10471 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10472 && ix86_unary_operator_ok (NOT, SImode, operands)"
10473 "#"
10474 [(set_attr "type" "alu1")
10475 (set_attr "mode" "SI")])
10476
10477 (define_split
10478 [(set (reg 17)
10479 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10480 (const_int 0)))
10481 (set (match_operand:DI 0 "register_operand" "")
10482 (zero_extend:DI (not:SI (match_dup 1))))]
10483 "ix86_match_ccmode (insn, CCNOmode)"
10484 [(parallel [(set (reg:CCNO 17)
10485 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10486 (const_int 0)))
10487 (set (match_dup 0)
10488 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10489 "")
10490
10491 (define_expand "one_cmplhi2"
10492 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10493 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10494 "TARGET_HIMODE_MATH"
10495 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10496
10497 (define_insn "*one_cmplhi2_1"
10498 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10499 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10500 "ix86_unary_operator_ok (NOT, HImode, operands)"
10501 "not{w}\t%0"
10502 [(set_attr "type" "negnot")
10503 (set_attr "mode" "HI")])
10504
10505 (define_insn "*one_cmplhi2_2"
10506 [(set (reg 17)
10507 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10508 (const_int 0)))
10509 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10510 (not:HI (match_dup 1)))]
10511 "ix86_match_ccmode (insn, CCNOmode)
10512 && ix86_unary_operator_ok (NEG, HImode, operands)"
10513 "#"
10514 [(set_attr "type" "alu1")
10515 (set_attr "mode" "HI")])
10516
10517 (define_split
10518 [(set (reg 17)
10519 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10520 (const_int 0)))
10521 (set (match_operand:HI 0 "nonimmediate_operand" "")
10522 (not:HI (match_dup 1)))]
10523 "ix86_match_ccmode (insn, CCNOmode)"
10524 [(parallel [(set (reg:CCNO 17)
10525 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10526 (const_int 0)))
10527 (set (match_dup 0)
10528 (xor:HI (match_dup 1) (const_int -1)))])]
10529 "")
10530
10531 ;; %%% Potential partial reg stall on alternative 1. What to do?
10532 (define_expand "one_cmplqi2"
10533 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10534 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10535 "TARGET_QIMODE_MATH"
10536 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10537
10538 (define_insn "*one_cmplqi2_1"
10539 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10540 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10541 "ix86_unary_operator_ok (NOT, QImode, operands)"
10542 "@
10543 not{b}\t%0
10544 not{l}\t%k0"
10545 [(set_attr "type" "negnot")
10546 (set_attr "mode" "QI,SI")])
10547
10548 (define_insn "*one_cmplqi2_2"
10549 [(set (reg 17)
10550 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10551 (const_int 0)))
10552 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10553 (not:QI (match_dup 1)))]
10554 "ix86_match_ccmode (insn, CCNOmode)
10555 && ix86_unary_operator_ok (NOT, QImode, operands)"
10556 "#"
10557 [(set_attr "type" "alu1")
10558 (set_attr "mode" "QI")])
10559
10560 (define_split
10561 [(set (reg 17)
10562 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10563 (const_int 0)))
10564 (set (match_operand:QI 0 "nonimmediate_operand" "")
10565 (not:QI (match_dup 1)))]
10566 "ix86_match_ccmode (insn, CCNOmode)"
10567 [(parallel [(set (reg:CCNO 17)
10568 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10569 (const_int 0)))
10570 (set (match_dup 0)
10571 (xor:QI (match_dup 1) (const_int -1)))])]
10572 "")
10573 \f
10574 ;; Arithmetic shift instructions
10575
10576 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10577 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10578 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10579 ;; from the assembler input.
10580 ;;
10581 ;; This instruction shifts the target reg/mem as usual, but instead of
10582 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10583 ;; is a left shift double, bits are taken from the high order bits of
10584 ;; reg, else if the insn is a shift right double, bits are taken from the
10585 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10586 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10587 ;;
10588 ;; Since sh[lr]d does not change the `reg' operand, that is done
10589 ;; separately, making all shifts emit pairs of shift double and normal
10590 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10591 ;; support a 63 bit shift, each shift where the count is in a reg expands
10592 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10593 ;;
10594 ;; If the shift count is a constant, we need never emit more than one
10595 ;; shift pair, instead using moves and sign extension for counts greater
10596 ;; than 31.
10597
10598 (define_expand "ashldi3"
10599 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10600 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10601 (match_operand:QI 2 "nonmemory_operand" "")))
10602 (clobber (reg:CC 17))])]
10603 ""
10604 {
10605 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
10606 {
10607 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
10608 DONE;
10609 }
10610 ix86_expand_binary_operator (ASHIFT, DImode, operands);
10611 DONE;
10612 })
10613
10614 (define_insn "*ashldi3_1_rex64"
10615 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10616 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10617 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10618 (clobber (reg:CC 17))]
10619 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10620 {
10621 switch (get_attr_type (insn))
10622 {
10623 case TYPE_ALU:
10624 if (operands[2] != const1_rtx)
10625 abort ();
10626 if (!rtx_equal_p (operands[0], operands[1]))
10627 abort ();
10628 return "add{q}\t{%0, %0|%0, %0}";
10629
10630 case TYPE_LEA:
10631 if (GET_CODE (operands[2]) != CONST_INT
10632 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10633 abort ();
10634 operands[1] = gen_rtx_MULT (DImode, operands[1],
10635 GEN_INT (1 << INTVAL (operands[2])));
10636 return "lea{q}\t{%a1, %0|%0, %a1}";
10637
10638 default:
10639 if (REG_P (operands[2]))
10640 return "sal{q}\t{%b2, %0|%0, %b2}";
10641 else if (operands[2] == const1_rtx
10642 && (TARGET_SHIFT1 || optimize_size))
10643 return "sal{q}\t%0";
10644 else
10645 return "sal{q}\t{%2, %0|%0, %2}";
10646 }
10647 }
10648 [(set (attr "type")
10649 (cond [(eq_attr "alternative" "1")
10650 (const_string "lea")
10651 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10652 (const_int 0))
10653 (match_operand 0 "register_operand" ""))
10654 (match_operand 2 "const1_operand" ""))
10655 (const_string "alu")
10656 ]
10657 (const_string "ishift")))
10658 (set_attr "mode" "DI")])
10659
10660 ;; Convert lea to the lea pattern to avoid flags dependency.
10661 (define_split
10662 [(set (match_operand:DI 0 "register_operand" "")
10663 (ashift:DI (match_operand:DI 1 "register_operand" "")
10664 (match_operand:QI 2 "immediate_operand" "")))
10665 (clobber (reg:CC 17))]
10666 "TARGET_64BIT && reload_completed
10667 && true_regnum (operands[0]) != true_regnum (operands[1])"
10668 [(set (match_dup 0)
10669 (mult:DI (match_dup 1)
10670 (match_dup 2)))]
10671 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10672
10673 ;; This pattern can't accept a variable shift count, since shifts by
10674 ;; zero don't affect the flags. We assume that shifts by constant
10675 ;; zero are optimized away.
10676 (define_insn "*ashldi3_cmp_rex64"
10677 [(set (reg 17)
10678 (compare
10679 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10680 (match_operand:QI 2 "immediate_operand" "e"))
10681 (const_int 0)))
10682 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10683 (ashift:DI (match_dup 1) (match_dup 2)))]
10684 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10685 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10686 {
10687 switch (get_attr_type (insn))
10688 {
10689 case TYPE_ALU:
10690 if (operands[2] != const1_rtx)
10691 abort ();
10692 return "add{q}\t{%0, %0|%0, %0}";
10693
10694 default:
10695 if (REG_P (operands[2]))
10696 return "sal{q}\t{%b2, %0|%0, %b2}";
10697 else if (operands[2] == const1_rtx
10698 && (TARGET_SHIFT1 || optimize_size))
10699 return "sal{q}\t%0";
10700 else
10701 return "sal{q}\t{%2, %0|%0, %2}";
10702 }
10703 }
10704 [(set (attr "type")
10705 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10706 (const_int 0))
10707 (match_operand 0 "register_operand" ""))
10708 (match_operand 2 "const1_operand" ""))
10709 (const_string "alu")
10710 ]
10711 (const_string "ishift")))
10712 (set_attr "mode" "DI")])
10713
10714 (define_insn "ashldi3_1"
10715 [(set (match_operand:DI 0 "register_operand" "=r")
10716 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10717 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10718 (clobber (match_scratch:SI 3 "=&r"))
10719 (clobber (reg:CC 17))]
10720 "!TARGET_64BIT && TARGET_CMOVE"
10721 "#"
10722 [(set_attr "type" "multi")])
10723
10724 (define_insn "*ashldi3_2"
10725 [(set (match_operand:DI 0 "register_operand" "=r")
10726 (ashift:DI (match_operand:DI 1 "register_operand" "0")
10727 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10728 (clobber (reg:CC 17))]
10729 "!TARGET_64BIT"
10730 "#"
10731 [(set_attr "type" "multi")])
10732
10733 (define_split
10734 [(set (match_operand:DI 0 "register_operand" "")
10735 (ashift:DI (match_operand:DI 1 "register_operand" "")
10736 (match_operand:QI 2 "nonmemory_operand" "")))
10737 (clobber (match_scratch:SI 3 ""))
10738 (clobber (reg:CC 17))]
10739 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
10740 [(const_int 0)]
10741 "ix86_split_ashldi (operands, operands[3]); DONE;")
10742
10743 (define_split
10744 [(set (match_operand:DI 0 "register_operand" "")
10745 (ashift:DI (match_operand:DI 1 "register_operand" "")
10746 (match_operand:QI 2 "nonmemory_operand" "")))
10747 (clobber (reg:CC 17))]
10748 "!TARGET_64BIT && reload_completed"
10749 [(const_int 0)]
10750 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10751
10752 (define_insn "x86_shld_1"
10753 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10754 (ior:SI (ashift:SI (match_dup 0)
10755 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10756 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10757 (minus:QI (const_int 32) (match_dup 2)))))
10758 (clobber (reg:CC 17))]
10759 ""
10760 "@
10761 shld{l}\t{%2, %1, %0|%0, %1, %2}
10762 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10763 [(set_attr "type" "ishift")
10764 (set_attr "prefix_0f" "1")
10765 (set_attr "mode" "SI")
10766 (set_attr "pent_pair" "np")
10767 (set_attr "athlon_decode" "vector")
10768 (set_attr "ppro_uops" "few")])
10769
10770 (define_expand "x86_shift_adj_1"
10771 [(set (reg:CCZ 17)
10772 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10773 (const_int 32))
10774 (const_int 0)))
10775 (set (match_operand:SI 0 "register_operand" "")
10776 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10777 (match_operand:SI 1 "register_operand" "")
10778 (match_dup 0)))
10779 (set (match_dup 1)
10780 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
10781 (match_operand:SI 3 "register_operand" "r")
10782 (match_dup 1)))]
10783 "TARGET_CMOVE"
10784 "")
10785
10786 (define_expand "x86_shift_adj_2"
10787 [(use (match_operand:SI 0 "register_operand" ""))
10788 (use (match_operand:SI 1 "register_operand" ""))
10789 (use (match_operand:QI 2 "register_operand" ""))]
10790 ""
10791 {
10792 rtx label = gen_label_rtx ();
10793 rtx tmp;
10794
10795 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10796
10797 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10798 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10799 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10800 gen_rtx_LABEL_REF (VOIDmode, label),
10801 pc_rtx);
10802 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10803 JUMP_LABEL (tmp) = label;
10804
10805 emit_move_insn (operands[0], operands[1]);
10806 emit_move_insn (operands[1], const0_rtx);
10807
10808 emit_label (label);
10809 LABEL_NUSES (label) = 1;
10810
10811 DONE;
10812 })
10813
10814 (define_expand "ashlsi3"
10815 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10816 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10817 (match_operand:QI 2 "nonmemory_operand" "")))
10818 (clobber (reg:CC 17))]
10819 ""
10820 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10821
10822 (define_insn "*ashlsi3_1"
10823 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10824 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10825 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10826 (clobber (reg:CC 17))]
10827 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10828 {
10829 switch (get_attr_type (insn))
10830 {
10831 case TYPE_ALU:
10832 if (operands[2] != const1_rtx)
10833 abort ();
10834 if (!rtx_equal_p (operands[0], operands[1]))
10835 abort ();
10836 return "add{l}\t{%0, %0|%0, %0}";
10837
10838 case TYPE_LEA:
10839 return "#";
10840
10841 default:
10842 if (REG_P (operands[2]))
10843 return "sal{l}\t{%b2, %0|%0, %b2}";
10844 else if (operands[2] == const1_rtx
10845 && (TARGET_SHIFT1 || optimize_size))
10846 return "sal{l}\t%0";
10847 else
10848 return "sal{l}\t{%2, %0|%0, %2}";
10849 }
10850 }
10851 [(set (attr "type")
10852 (cond [(eq_attr "alternative" "1")
10853 (const_string "lea")
10854 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10855 (const_int 0))
10856 (match_operand 0 "register_operand" ""))
10857 (match_operand 2 "const1_operand" ""))
10858 (const_string "alu")
10859 ]
10860 (const_string "ishift")))
10861 (set_attr "mode" "SI")])
10862
10863 ;; Convert lea to the lea pattern to avoid flags dependency.
10864 (define_split
10865 [(set (match_operand 0 "register_operand" "")
10866 (ashift (match_operand 1 "index_register_operand" "")
10867 (match_operand:QI 2 "const_int_operand" "")))
10868 (clobber (reg:CC 17))]
10869 "reload_completed
10870 && true_regnum (operands[0]) != true_regnum (operands[1])"
10871 [(const_int 0)]
10872 {
10873 rtx pat;
10874 operands[0] = gen_lowpart (SImode, operands[0]);
10875 operands[1] = gen_lowpart (Pmode, operands[1]);
10876 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10877 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10878 if (Pmode != SImode)
10879 pat = gen_rtx_SUBREG (SImode, pat, 0);
10880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10881 DONE;
10882 })
10883
10884 ;; Rare case of shifting RSP is handled by generating move and shift
10885 (define_split
10886 [(set (match_operand 0 "register_operand" "")
10887 (ashift (match_operand 1 "register_operand" "")
10888 (match_operand:QI 2 "const_int_operand" "")))
10889 (clobber (reg:CC 17))]
10890 "reload_completed
10891 && true_regnum (operands[0]) != true_regnum (operands[1])"
10892 [(const_int 0)]
10893 {
10894 rtx pat, clob;
10895 emit_move_insn (operands[1], operands[0]);
10896 pat = gen_rtx_SET (VOIDmode, operands[0],
10897 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10898 operands[0], operands[2]));
10899 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10900 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10901 DONE;
10902 })
10903
10904 (define_insn "*ashlsi3_1_zext"
10905 [(set (match_operand:DI 0 "register_operand" "=r,r")
10906 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10907 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10908 (clobber (reg:CC 17))]
10909 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10910 {
10911 switch (get_attr_type (insn))
10912 {
10913 case TYPE_ALU:
10914 if (operands[2] != const1_rtx)
10915 abort ();
10916 return "add{l}\t{%k0, %k0|%k0, %k0}";
10917
10918 case TYPE_LEA:
10919 return "#";
10920
10921 default:
10922 if (REG_P (operands[2]))
10923 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10924 else if (operands[2] == const1_rtx
10925 && (TARGET_SHIFT1 || optimize_size))
10926 return "sal{l}\t%k0";
10927 else
10928 return "sal{l}\t{%2, %k0|%k0, %2}";
10929 }
10930 }
10931 [(set (attr "type")
10932 (cond [(eq_attr "alternative" "1")
10933 (const_string "lea")
10934 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935 (const_int 0))
10936 (match_operand 2 "const1_operand" ""))
10937 (const_string "alu")
10938 ]
10939 (const_string "ishift")))
10940 (set_attr "mode" "SI")])
10941
10942 ;; Convert lea to the lea pattern to avoid flags dependency.
10943 (define_split
10944 [(set (match_operand:DI 0 "register_operand" "")
10945 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10946 (match_operand:QI 2 "const_int_operand" ""))))
10947 (clobber (reg:CC 17))]
10948 "TARGET_64BIT && reload_completed
10949 && true_regnum (operands[0]) != true_regnum (operands[1])"
10950 [(set (match_dup 0) (zero_extend:DI
10951 (subreg:SI (mult:SI (match_dup 1)
10952 (match_dup 2)) 0)))]
10953 {
10954 operands[1] = gen_lowpart (Pmode, operands[1]);
10955 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10956 })
10957
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags. We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashlsi3_cmp"
10962 [(set (reg 17)
10963 (compare
10964 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10965 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10966 (const_int 0)))
10967 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10968 (ashift:SI (match_dup 1) (match_dup 2)))]
10969 "ix86_match_ccmode (insn, CCGOCmode)
10970 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10971 {
10972 switch (get_attr_type (insn))
10973 {
10974 case TYPE_ALU:
10975 if (operands[2] != const1_rtx)
10976 abort ();
10977 return "add{l}\t{%0, %0|%0, %0}";
10978
10979 default:
10980 if (REG_P (operands[2]))
10981 return "sal{l}\t{%b2, %0|%0, %b2}";
10982 else if (operands[2] == const1_rtx
10983 && (TARGET_SHIFT1 || optimize_size))
10984 return "sal{l}\t%0";
10985 else
10986 return "sal{l}\t{%2, %0|%0, %2}";
10987 }
10988 }
10989 [(set (attr "type")
10990 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10991 (const_int 0))
10992 (match_operand 0 "register_operand" ""))
10993 (match_operand 2 "const1_operand" ""))
10994 (const_string "alu")
10995 ]
10996 (const_string "ishift")))
10997 (set_attr "mode" "SI")])
10998
10999 (define_insn "*ashlsi3_cmp_zext"
11000 [(set (reg 17)
11001 (compare
11002 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11003 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11004 (const_int 0)))
11005 (set (match_operand:DI 0 "register_operand" "=r")
11006 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11007 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11008 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11009 {
11010 switch (get_attr_type (insn))
11011 {
11012 case TYPE_ALU:
11013 if (operands[2] != const1_rtx)
11014 abort ();
11015 return "add{l}\t{%k0, %k0|%k0, %k0}";
11016
11017 default:
11018 if (REG_P (operands[2]))
11019 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11020 else if (operands[2] == const1_rtx
11021 && (TARGET_SHIFT1 || optimize_size))
11022 return "sal{l}\t%k0";
11023 else
11024 return "sal{l}\t{%2, %k0|%k0, %2}";
11025 }
11026 }
11027 [(set (attr "type")
11028 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11029 (const_int 0))
11030 (match_operand 2 "const1_operand" ""))
11031 (const_string "alu")
11032 ]
11033 (const_string "ishift")))
11034 (set_attr "mode" "SI")])
11035
11036 (define_expand "ashlhi3"
11037 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11038 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11039 (match_operand:QI 2 "nonmemory_operand" "")))
11040 (clobber (reg:CC 17))]
11041 "TARGET_HIMODE_MATH"
11042 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11043
11044 (define_insn "*ashlhi3_1_lea"
11045 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11046 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11047 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11048 (clobber (reg:CC 17))]
11049 "!TARGET_PARTIAL_REG_STALL
11050 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11051 {
11052 switch (get_attr_type (insn))
11053 {
11054 case TYPE_LEA:
11055 return "#";
11056 case TYPE_ALU:
11057 if (operands[2] != const1_rtx)
11058 abort ();
11059 return "add{w}\t{%0, %0|%0, %0}";
11060
11061 default:
11062 if (REG_P (operands[2]))
11063 return "sal{w}\t{%b2, %0|%0, %b2}";
11064 else if (operands[2] == const1_rtx
11065 && (TARGET_SHIFT1 || optimize_size))
11066 return "sal{w}\t%0";
11067 else
11068 return "sal{w}\t{%2, %0|%0, %2}";
11069 }
11070 }
11071 [(set (attr "type")
11072 (cond [(eq_attr "alternative" "1")
11073 (const_string "lea")
11074 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11075 (const_int 0))
11076 (match_operand 0 "register_operand" ""))
11077 (match_operand 2 "const1_operand" ""))
11078 (const_string "alu")
11079 ]
11080 (const_string "ishift")))
11081 (set_attr "mode" "HI,SI")])
11082
11083 (define_insn "*ashlhi3_1"
11084 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11085 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11086 (match_operand:QI 2 "nonmemory_operand" "cI")))
11087 (clobber (reg:CC 17))]
11088 "TARGET_PARTIAL_REG_STALL
11089 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11090 {
11091 switch (get_attr_type (insn))
11092 {
11093 case TYPE_ALU:
11094 if (operands[2] != const1_rtx)
11095 abort ();
11096 return "add{w}\t{%0, %0|%0, %0}";
11097
11098 default:
11099 if (REG_P (operands[2]))
11100 return "sal{w}\t{%b2, %0|%0, %b2}";
11101 else if (operands[2] == const1_rtx
11102 && (TARGET_SHIFT1 || optimize_size))
11103 return "sal{w}\t%0";
11104 else
11105 return "sal{w}\t{%2, %0|%0, %2}";
11106 }
11107 }
11108 [(set (attr "type")
11109 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11110 (const_int 0))
11111 (match_operand 0 "register_operand" ""))
11112 (match_operand 2 "const1_operand" ""))
11113 (const_string "alu")
11114 ]
11115 (const_string "ishift")))
11116 (set_attr "mode" "HI")])
11117
11118 ;; This pattern can't accept a variable shift count, since shifts by
11119 ;; zero don't affect the flags. We assume that shifts by constant
11120 ;; zero are optimized away.
11121 (define_insn "*ashlhi3_cmp"
11122 [(set (reg 17)
11123 (compare
11124 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11125 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11126 (const_int 0)))
11127 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11128 (ashift:HI (match_dup 1) (match_dup 2)))]
11129 "ix86_match_ccmode (insn, CCGOCmode)
11130 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11131 {
11132 switch (get_attr_type (insn))
11133 {
11134 case TYPE_ALU:
11135 if (operands[2] != const1_rtx)
11136 abort ();
11137 return "add{w}\t{%0, %0|%0, %0}";
11138
11139 default:
11140 if (REG_P (operands[2]))
11141 return "sal{w}\t{%b2, %0|%0, %b2}";
11142 else if (operands[2] == const1_rtx
11143 && (TARGET_SHIFT1 || optimize_size))
11144 return "sal{w}\t%0";
11145 else
11146 return "sal{w}\t{%2, %0|%0, %2}";
11147 }
11148 }
11149 [(set (attr "type")
11150 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11151 (const_int 0))
11152 (match_operand 0 "register_operand" ""))
11153 (match_operand 2 "const1_operand" ""))
11154 (const_string "alu")
11155 ]
11156 (const_string "ishift")))
11157 (set_attr "mode" "HI")])
11158
11159 (define_expand "ashlqi3"
11160 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11161 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11162 (match_operand:QI 2 "nonmemory_operand" "")))
11163 (clobber (reg:CC 17))]
11164 "TARGET_QIMODE_MATH"
11165 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11166
11167 ;; %%% Potential partial reg stall on alternative 2. What to do?
11168
11169 (define_insn "*ashlqi3_1_lea"
11170 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11171 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11172 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11173 (clobber (reg:CC 17))]
11174 "!TARGET_PARTIAL_REG_STALL
11175 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11176 {
11177 switch (get_attr_type (insn))
11178 {
11179 case TYPE_LEA:
11180 return "#";
11181 case TYPE_ALU:
11182 if (operands[2] != const1_rtx)
11183 abort ();
11184 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11185 return "add{l}\t{%k0, %k0|%k0, %k0}";
11186 else
11187 return "add{b}\t{%0, %0|%0, %0}";
11188
11189 default:
11190 if (REG_P (operands[2]))
11191 {
11192 if (get_attr_mode (insn) == MODE_SI)
11193 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11194 else
11195 return "sal{b}\t{%b2, %0|%0, %b2}";
11196 }
11197 else if (operands[2] == const1_rtx
11198 && (TARGET_SHIFT1 || optimize_size))
11199 {
11200 if (get_attr_mode (insn) == MODE_SI)
11201 return "sal{l}\t%0";
11202 else
11203 return "sal{b}\t%0";
11204 }
11205 else
11206 {
11207 if (get_attr_mode (insn) == MODE_SI)
11208 return "sal{l}\t{%2, %k0|%k0, %2}";
11209 else
11210 return "sal{b}\t{%2, %0|%0, %2}";
11211 }
11212 }
11213 }
11214 [(set (attr "type")
11215 (cond [(eq_attr "alternative" "2")
11216 (const_string "lea")
11217 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218 (const_int 0))
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11222 ]
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI,SI,SI")])
11225
11226 (define_insn "*ashlqi3_1"
11227 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11228 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11229 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11230 (clobber (reg:CC 17))]
11231 "TARGET_PARTIAL_REG_STALL
11232 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11233 {
11234 switch (get_attr_type (insn))
11235 {
11236 case TYPE_ALU:
11237 if (operands[2] != const1_rtx)
11238 abort ();
11239 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11240 return "add{l}\t{%k0, %k0|%k0, %k0}";
11241 else
11242 return "add{b}\t{%0, %0|%0, %0}";
11243
11244 default:
11245 if (REG_P (operands[2]))
11246 {
11247 if (get_attr_mode (insn) == MODE_SI)
11248 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11249 else
11250 return "sal{b}\t{%b2, %0|%0, %b2}";
11251 }
11252 else if (operands[2] == const1_rtx
11253 && (TARGET_SHIFT1 || optimize_size))
11254 {
11255 if (get_attr_mode (insn) == MODE_SI)
11256 return "sal{l}\t%0";
11257 else
11258 return "sal{b}\t%0";
11259 }
11260 else
11261 {
11262 if (get_attr_mode (insn) == MODE_SI)
11263 return "sal{l}\t{%2, %k0|%k0, %2}";
11264 else
11265 return "sal{b}\t{%2, %0|%0, %2}";
11266 }
11267 }
11268 }
11269 [(set (attr "type")
11270 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11271 (const_int 0))
11272 (match_operand 0 "register_operand" ""))
11273 (match_operand 2 "const1_operand" ""))
11274 (const_string "alu")
11275 ]
11276 (const_string "ishift")))
11277 (set_attr "mode" "QI,SI")])
11278
11279 ;; This pattern can't accept a variable shift count, since shifts by
11280 ;; zero don't affect the flags. We assume that shifts by constant
11281 ;; zero are optimized away.
11282 (define_insn "*ashlqi3_cmp"
11283 [(set (reg 17)
11284 (compare
11285 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11286 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11287 (const_int 0)))
11288 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11289 (ashift:QI (match_dup 1) (match_dup 2)))]
11290 "ix86_match_ccmode (insn, CCGOCmode)
11291 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11292 {
11293 switch (get_attr_type (insn))
11294 {
11295 case TYPE_ALU:
11296 if (operands[2] != const1_rtx)
11297 abort ();
11298 return "add{b}\t{%0, %0|%0, %0}";
11299
11300 default:
11301 if (REG_P (operands[2]))
11302 return "sal{b}\t{%b2, %0|%0, %b2}";
11303 else if (operands[2] == const1_rtx
11304 && (TARGET_SHIFT1 || optimize_size))
11305 return "sal{b}\t%0";
11306 else
11307 return "sal{b}\t{%2, %0|%0, %2}";
11308 }
11309 }
11310 [(set (attr "type")
11311 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11312 (const_int 0))
11313 (match_operand 0 "register_operand" ""))
11314 (match_operand 2 "const1_operand" ""))
11315 (const_string "alu")
11316 ]
11317 (const_string "ishift")))
11318 (set_attr "mode" "QI")])
11319
11320 ;; See comment above `ashldi3' about how this works.
11321
11322 (define_expand "ashrdi3"
11323 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11324 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11325 (match_operand:QI 2 "nonmemory_operand" "")))
11326 (clobber (reg:CC 17))])]
11327 ""
11328 {
11329 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11330 {
11331 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11332 DONE;
11333 }
11334 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11335 DONE;
11336 })
11337
11338 (define_insn "ashrdi3_63_rex64"
11339 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11340 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11341 (match_operand:DI 2 "const_int_operand" "i,i")))
11342 (clobber (reg:CC 17))]
11343 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11344 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11345 "@
11346 {cqto|cqo}
11347 sar{q}\t{%2, %0|%0, %2}"
11348 [(set_attr "type" "imovx,ishift")
11349 (set_attr "prefix_0f" "0,*")
11350 (set_attr "length_immediate" "0,*")
11351 (set_attr "modrm" "0,1")
11352 (set_attr "mode" "DI")])
11353
11354 (define_insn "*ashrdi3_1_one_bit_rex64"
11355 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11356 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11357 (match_operand:QI 2 "const1_operand" "")))
11358 (clobber (reg:CC 17))]
11359 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11360 && (TARGET_SHIFT1 || optimize_size)"
11361 "sar{q}\t%0"
11362 [(set_attr "type" "ishift")
11363 (set (attr "length")
11364 (if_then_else (match_operand:DI 0 "register_operand" "")
11365 (const_string "2")
11366 (const_string "*")))])
11367
11368 (define_insn "*ashrdi3_1_rex64"
11369 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11370 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11371 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11372 (clobber (reg:CC 17))]
11373 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11374 "@
11375 sar{q}\t{%2, %0|%0, %2}
11376 sar{q}\t{%b2, %0|%0, %b2}"
11377 [(set_attr "type" "ishift")
11378 (set_attr "mode" "DI")])
11379
11380 ;; This pattern can't accept a variable shift count, since shifts by
11381 ;; zero don't affect the flags. We assume that shifts by constant
11382 ;; zero are optimized away.
11383 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11384 [(set (reg 17)
11385 (compare
11386 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11387 (match_operand:QI 2 "const1_operand" ""))
11388 (const_int 0)))
11389 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11391 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11392 && (TARGET_SHIFT1 || optimize_size)
11393 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11394 "sar{q}\t%0"
11395 [(set_attr "type" "ishift")
11396 (set (attr "length")
11397 (if_then_else (match_operand:DI 0 "register_operand" "")
11398 (const_string "2")
11399 (const_string "*")))])
11400
11401 ;; This pattern can't accept a variable shift count, since shifts by
11402 ;; zero don't affect the flags. We assume that shifts by constant
11403 ;; zero are optimized away.
11404 (define_insn "*ashrdi3_cmp_rex64"
11405 [(set (reg 17)
11406 (compare
11407 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11408 (match_operand:QI 2 "const_int_operand" "n"))
11409 (const_int 0)))
11410 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11412 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11413 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11414 "sar{q}\t{%2, %0|%0, %2}"
11415 [(set_attr "type" "ishift")
11416 (set_attr "mode" "DI")])
11417
11418
11419 (define_insn "ashrdi3_1"
11420 [(set (match_operand:DI 0 "register_operand" "=r")
11421 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11422 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11423 (clobber (match_scratch:SI 3 "=&r"))
11424 (clobber (reg:CC 17))]
11425 "!TARGET_64BIT && TARGET_CMOVE"
11426 "#"
11427 [(set_attr "type" "multi")])
11428
11429 (define_insn "*ashrdi3_2"
11430 [(set (match_operand:DI 0 "register_operand" "=r")
11431 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11432 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11433 (clobber (reg:CC 17))]
11434 "!TARGET_64BIT"
11435 "#"
11436 [(set_attr "type" "multi")])
11437
11438 (define_split
11439 [(set (match_operand:DI 0 "register_operand" "")
11440 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11441 (match_operand:QI 2 "nonmemory_operand" "")))
11442 (clobber (match_scratch:SI 3 ""))
11443 (clobber (reg:CC 17))]
11444 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11445 [(const_int 0)]
11446 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11447
11448 (define_split
11449 [(set (match_operand:DI 0 "register_operand" "")
11450 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11451 (match_operand:QI 2 "nonmemory_operand" "")))
11452 (clobber (reg:CC 17))]
11453 "!TARGET_64BIT && reload_completed"
11454 [(const_int 0)]
11455 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11456
11457 (define_insn "x86_shrd_1"
11458 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11459 (ior:SI (ashiftrt:SI (match_dup 0)
11460 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11461 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11462 (minus:QI (const_int 32) (match_dup 2)))))
11463 (clobber (reg:CC 17))]
11464 ""
11465 "@
11466 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11467 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11468 [(set_attr "type" "ishift")
11469 (set_attr "prefix_0f" "1")
11470 (set_attr "pent_pair" "np")
11471 (set_attr "ppro_uops" "few")
11472 (set_attr "mode" "SI")])
11473
11474 (define_expand "x86_shift_adj_3"
11475 [(use (match_operand:SI 0 "register_operand" ""))
11476 (use (match_operand:SI 1 "register_operand" ""))
11477 (use (match_operand:QI 2 "register_operand" ""))]
11478 ""
11479 {
11480 rtx label = gen_label_rtx ();
11481 rtx tmp;
11482
11483 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11484
11485 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11486 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11487 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11488 gen_rtx_LABEL_REF (VOIDmode, label),
11489 pc_rtx);
11490 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11491 JUMP_LABEL (tmp) = label;
11492
11493 emit_move_insn (operands[0], operands[1]);
11494 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11495
11496 emit_label (label);
11497 LABEL_NUSES (label) = 1;
11498
11499 DONE;
11500 })
11501
11502 (define_insn "ashrsi3_31"
11503 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11504 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11505 (match_operand:SI 2 "const_int_operand" "i,i")))
11506 (clobber (reg:CC 17))]
11507 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11508 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11509 "@
11510 {cltd|cdq}
11511 sar{l}\t{%2, %0|%0, %2}"
11512 [(set_attr "type" "imovx,ishift")
11513 (set_attr "prefix_0f" "0,*")
11514 (set_attr "length_immediate" "0,*")
11515 (set_attr "modrm" "0,1")
11516 (set_attr "mode" "SI")])
11517
11518 (define_insn "*ashrsi3_31_zext"
11519 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11520 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11521 (match_operand:SI 2 "const_int_operand" "i,i"))))
11522 (clobber (reg:CC 17))]
11523 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11524 && INTVAL (operands[2]) == 31
11525 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11526 "@
11527 {cltd|cdq}
11528 sar{l}\t{%2, %k0|%k0, %2}"
11529 [(set_attr "type" "imovx,ishift")
11530 (set_attr "prefix_0f" "0,*")
11531 (set_attr "length_immediate" "0,*")
11532 (set_attr "modrm" "0,1")
11533 (set_attr "mode" "SI")])
11534
11535 (define_expand "ashrsi3"
11536 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11537 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11538 (match_operand:QI 2 "nonmemory_operand" "")))
11539 (clobber (reg:CC 17))]
11540 ""
11541 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11542
11543 (define_insn "*ashrsi3_1_one_bit"
11544 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11545 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11546 (match_operand:QI 2 "const1_operand" "")))
11547 (clobber (reg:CC 17))]
11548 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11549 && (TARGET_SHIFT1 || optimize_size)"
11550 "sar{l}\t%0"
11551 [(set_attr "type" "ishift")
11552 (set (attr "length")
11553 (if_then_else (match_operand:SI 0 "register_operand" "")
11554 (const_string "2")
11555 (const_string "*")))])
11556
11557 (define_insn "*ashrsi3_1_one_bit_zext"
11558 [(set (match_operand:DI 0 "register_operand" "=r")
11559 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11560 (match_operand:QI 2 "const1_operand" ""))))
11561 (clobber (reg:CC 17))]
11562 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11563 && (TARGET_SHIFT1 || optimize_size)"
11564 "sar{l}\t%k0"
11565 [(set_attr "type" "ishift")
11566 (set_attr "length" "2")])
11567
11568 (define_insn "*ashrsi3_1"
11569 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11570 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11571 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11572 (clobber (reg:CC 17))]
11573 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11574 "@
11575 sar{l}\t{%2, %0|%0, %2}
11576 sar{l}\t{%b2, %0|%0, %b2}"
11577 [(set_attr "type" "ishift")
11578 (set_attr "mode" "SI")])
11579
11580 (define_insn "*ashrsi3_1_zext"
11581 [(set (match_operand:DI 0 "register_operand" "=r,r")
11582 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11583 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11584 (clobber (reg:CC 17))]
11585 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586 "@
11587 sar{l}\t{%2, %k0|%k0, %2}
11588 sar{l}\t{%b2, %k0|%k0, %b2}"
11589 [(set_attr "type" "ishift")
11590 (set_attr "mode" "SI")])
11591
11592 ;; This pattern can't accept a variable shift count, since shifts by
11593 ;; zero don't affect the flags. We assume that shifts by constant
11594 ;; zero are optimized away.
11595 (define_insn "*ashrsi3_one_bit_cmp"
11596 [(set (reg 17)
11597 (compare
11598 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11599 (match_operand:QI 2 "const1_operand" ""))
11600 (const_int 0)))
11601 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11602 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11603 "ix86_match_ccmode (insn, CCGOCmode)
11604 && (TARGET_SHIFT1 || optimize_size)
11605 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606 "sar{l}\t%0"
11607 [(set_attr "type" "ishift")
11608 (set (attr "length")
11609 (if_then_else (match_operand:SI 0 "register_operand" "")
11610 (const_string "2")
11611 (const_string "*")))])
11612
11613 (define_insn "*ashrsi3_one_bit_cmp_zext"
11614 [(set (reg 17)
11615 (compare
11616 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11617 (match_operand:QI 2 "const1_operand" ""))
11618 (const_int 0)))
11619 (set (match_operand:DI 0 "register_operand" "=r")
11620 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11621 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11622 && (TARGET_SHIFT1 || optimize_size)
11623 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11624 "sar{l}\t%k0"
11625 [(set_attr "type" "ishift")
11626 (set_attr "length" "2")])
11627
11628 ;; This pattern can't accept a variable shift count, since shifts by
11629 ;; zero don't affect the flags. We assume that shifts by constant
11630 ;; zero are optimized away.
11631 (define_insn "*ashrsi3_cmp"
11632 [(set (reg 17)
11633 (compare
11634 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11635 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11636 (const_int 0)))
11637 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11638 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11639 "ix86_match_ccmode (insn, CCGOCmode)
11640 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11641 "sar{l}\t{%2, %0|%0, %2}"
11642 [(set_attr "type" "ishift")
11643 (set_attr "mode" "SI")])
11644
11645 (define_insn "*ashrsi3_cmp_zext"
11646 [(set (reg 17)
11647 (compare
11648 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11649 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11650 (const_int 0)))
11651 (set (match_operand:DI 0 "register_operand" "=r")
11652 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11653 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655 "sar{l}\t{%2, %k0|%k0, %2}"
11656 [(set_attr "type" "ishift")
11657 (set_attr "mode" "SI")])
11658
11659 (define_expand "ashrhi3"
11660 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11661 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11662 (match_operand:QI 2 "nonmemory_operand" "")))
11663 (clobber (reg:CC 17))]
11664 "TARGET_HIMODE_MATH"
11665 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11666
11667 (define_insn "*ashrhi3_1_one_bit"
11668 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11669 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11670 (match_operand:QI 2 "const1_operand" "")))
11671 (clobber (reg:CC 17))]
11672 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11673 && (TARGET_SHIFT1 || optimize_size)"
11674 "sar{w}\t%0"
11675 [(set_attr "type" "ishift")
11676 (set (attr "length")
11677 (if_then_else (match_operand 0 "register_operand" "")
11678 (const_string "2")
11679 (const_string "*")))])
11680
11681 (define_insn "*ashrhi3_1"
11682 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11683 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11684 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11685 (clobber (reg:CC 17))]
11686 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11687 "@
11688 sar{w}\t{%2, %0|%0, %2}
11689 sar{w}\t{%b2, %0|%0, %b2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "HI")])
11692
11693 ;; This pattern can't accept a variable shift count, since shifts by
11694 ;; zero don't affect the flags. We assume that shifts by constant
11695 ;; zero are optimized away.
11696 (define_insn "*ashrhi3_one_bit_cmp"
11697 [(set (reg 17)
11698 (compare
11699 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11700 (match_operand:QI 2 "const1_operand" ""))
11701 (const_int 0)))
11702 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11703 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11704 "ix86_match_ccmode (insn, CCGOCmode)
11705 && (TARGET_SHIFT1 || optimize_size)
11706 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11707 "sar{w}\t%0"
11708 [(set_attr "type" "ishift")
11709 (set (attr "length")
11710 (if_then_else (match_operand 0 "register_operand" "")
11711 (const_string "2")
11712 (const_string "*")))])
11713
11714 ;; This pattern can't accept a variable shift count, since shifts by
11715 ;; zero don't affect the flags. We assume that shifts by constant
11716 ;; zero are optimized away.
11717 (define_insn "*ashrhi3_cmp"
11718 [(set (reg 17)
11719 (compare
11720 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11721 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11722 (const_int 0)))
11723 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11724 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11725 "ix86_match_ccmode (insn, CCGOCmode)
11726 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11727 "sar{w}\t{%2, %0|%0, %2}"
11728 [(set_attr "type" "ishift")
11729 (set_attr "mode" "HI")])
11730
11731 (define_expand "ashrqi3"
11732 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11733 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11734 (match_operand:QI 2 "nonmemory_operand" "")))
11735 (clobber (reg:CC 17))]
11736 "TARGET_QIMODE_MATH"
11737 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11738
11739 (define_insn "*ashrqi3_1_one_bit"
11740 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11741 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11742 (match_operand:QI 2 "const1_operand" "")))
11743 (clobber (reg:CC 17))]
11744 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11745 && (TARGET_SHIFT1 || optimize_size)"
11746 "sar{b}\t%0"
11747 [(set_attr "type" "ishift")
11748 (set (attr "length")
11749 (if_then_else (match_operand 0 "register_operand" "")
11750 (const_string "2")
11751 (const_string "*")))])
11752
11753 (define_insn "*ashrqi3_1_one_bit_slp"
11754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11755 (ashiftrt:QI (match_dup 0)
11756 (match_operand:QI 1 "const1_operand" "")))
11757 (clobber (reg:CC 17))]
11758 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11759 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11760 && (TARGET_SHIFT1 || optimize_size)"
11761 "sar{b}\t%0"
11762 [(set_attr "type" "ishift1")
11763 (set (attr "length")
11764 (if_then_else (match_operand 0 "register_operand" "")
11765 (const_string "2")
11766 (const_string "*")))])
11767
11768 (define_insn "*ashrqi3_1"
11769 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11770 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11771 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11772 (clobber (reg:CC 17))]
11773 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11774 "@
11775 sar{b}\t{%2, %0|%0, %2}
11776 sar{b}\t{%b2, %0|%0, %b2}"
11777 [(set_attr "type" "ishift")
11778 (set_attr "mode" "QI")])
11779
11780 (define_insn "*ashrqi3_1_slp"
11781 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11782 (ashiftrt:QI (match_dup 0)
11783 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11784 (clobber (reg:CC 17))]
11785 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11786 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11787 "@
11788 sar{b}\t{%1, %0|%0, %1}
11789 sar{b}\t{%b1, %0|%0, %b1}"
11790 [(set_attr "type" "ishift1")
11791 (set_attr "mode" "QI")])
11792
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags. We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrqi3_one_bit_cmp"
11797 [(set (reg 17)
11798 (compare
11799 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const1_operand" "I"))
11801 (const_int 0)))
11802 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11804 "ix86_match_ccmode (insn, CCGOCmode)
11805 && (TARGET_SHIFT1 || optimize_size)
11806 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11807 "sar{b}\t%0"
11808 [(set_attr "type" "ishift")
11809 (set (attr "length")
11810 (if_then_else (match_operand 0 "register_operand" "")
11811 (const_string "2")
11812 (const_string "*")))])
11813
11814 ;; This pattern can't accept a variable shift count, since shifts by
11815 ;; zero don't affect the flags. We assume that shifts by constant
11816 ;; zero are optimized away.
11817 (define_insn "*ashrqi3_cmp"
11818 [(set (reg 17)
11819 (compare
11820 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11821 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11822 (const_int 0)))
11823 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11824 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11825 "ix86_match_ccmode (insn, CCGOCmode)
11826 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11827 "sar{b}\t{%2, %0|%0, %2}"
11828 [(set_attr "type" "ishift")
11829 (set_attr "mode" "QI")])
11830 \f
11831 ;; Logical shift instructions
11832
11833 ;; See comment above `ashldi3' about how this works.
11834
11835 (define_expand "lshrdi3"
11836 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11837 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11838 (match_operand:QI 2 "nonmemory_operand" "")))
11839 (clobber (reg:CC 17))])]
11840 ""
11841 {
11842 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11843 {
11844 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
11845 DONE;
11846 }
11847 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
11848 DONE;
11849 })
11850
11851 (define_insn "*lshrdi3_1_one_bit_rex64"
11852 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11853 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11854 (match_operand:QI 2 "const1_operand" "")))
11855 (clobber (reg:CC 17))]
11856 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11857 && (TARGET_SHIFT1 || optimize_size)"
11858 "shr{q}\t%0"
11859 [(set_attr "type" "ishift")
11860 (set (attr "length")
11861 (if_then_else (match_operand:DI 0 "register_operand" "")
11862 (const_string "2")
11863 (const_string "*")))])
11864
11865 (define_insn "*lshrdi3_1_rex64"
11866 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11867 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11868 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11869 (clobber (reg:CC 17))]
11870 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871 "@
11872 shr{q}\t{%2, %0|%0, %2}
11873 shr{q}\t{%b2, %0|%0, %b2}"
11874 [(set_attr "type" "ishift")
11875 (set_attr "mode" "DI")])
11876
11877 ;; This pattern can't accept a variable shift count, since shifts by
11878 ;; zero don't affect the flags. We assume that shifts by constant
11879 ;; zero are optimized away.
11880 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11881 [(set (reg 17)
11882 (compare
11883 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11884 (match_operand:QI 2 "const1_operand" ""))
11885 (const_int 0)))
11886 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11887 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11888 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11889 && (TARGET_SHIFT1 || optimize_size)
11890 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11891 "shr{q}\t%0"
11892 [(set_attr "type" "ishift")
11893 (set (attr "length")
11894 (if_then_else (match_operand:DI 0 "register_operand" "")
11895 (const_string "2")
11896 (const_string "*")))])
11897
11898 ;; This pattern can't accept a variable shift count, since shifts by
11899 ;; zero don't affect the flags. We assume that shifts by constant
11900 ;; zero are optimized away.
11901 (define_insn "*lshrdi3_cmp_rex64"
11902 [(set (reg 17)
11903 (compare
11904 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11905 (match_operand:QI 2 "const_int_operand" "e"))
11906 (const_int 0)))
11907 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11908 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11909 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11910 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11911 "shr{q}\t{%2, %0|%0, %2}"
11912 [(set_attr "type" "ishift")
11913 (set_attr "mode" "DI")])
11914
11915 (define_insn "lshrdi3_1"
11916 [(set (match_operand:DI 0 "register_operand" "=r")
11917 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11918 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11919 (clobber (match_scratch:SI 3 "=&r"))
11920 (clobber (reg:CC 17))]
11921 "!TARGET_64BIT && TARGET_CMOVE"
11922 "#"
11923 [(set_attr "type" "multi")])
11924
11925 (define_insn "*lshrdi3_2"
11926 [(set (match_operand:DI 0 "register_operand" "=r")
11927 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11928 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11929 (clobber (reg:CC 17))]
11930 "!TARGET_64BIT"
11931 "#"
11932 [(set_attr "type" "multi")])
11933
11934 (define_split
11935 [(set (match_operand:DI 0 "register_operand" "")
11936 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11937 (match_operand:QI 2 "nonmemory_operand" "")))
11938 (clobber (match_scratch:SI 3 ""))
11939 (clobber (reg:CC 17))]
11940 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11941 [(const_int 0)]
11942 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11943
11944 (define_split
11945 [(set (match_operand:DI 0 "register_operand" "")
11946 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11947 (match_operand:QI 2 "nonmemory_operand" "")))
11948 (clobber (reg:CC 17))]
11949 "!TARGET_64BIT && reload_completed"
11950 [(const_int 0)]
11951 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11952
11953 (define_expand "lshrsi3"
11954 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11955 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11956 (match_operand:QI 2 "nonmemory_operand" "")))
11957 (clobber (reg:CC 17))]
11958 ""
11959 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11960
11961 (define_insn "*lshrsi3_1_one_bit"
11962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11963 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11964 (match_operand:QI 2 "const1_operand" "")))
11965 (clobber (reg:CC 17))]
11966 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11967 && (TARGET_SHIFT1 || optimize_size)"
11968 "shr{l}\t%0"
11969 [(set_attr "type" "ishift")
11970 (set (attr "length")
11971 (if_then_else (match_operand:SI 0 "register_operand" "")
11972 (const_string "2")
11973 (const_string "*")))])
11974
11975 (define_insn "*lshrsi3_1_one_bit_zext"
11976 [(set (match_operand:DI 0 "register_operand" "=r")
11977 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11978 (match_operand:QI 2 "const1_operand" "")))
11979 (clobber (reg:CC 17))]
11980 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11981 && (TARGET_SHIFT1 || optimize_size)"
11982 "shr{l}\t%k0"
11983 [(set_attr "type" "ishift")
11984 (set_attr "length" "2")])
11985
11986 (define_insn "*lshrsi3_1"
11987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11988 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990 (clobber (reg:CC 17))]
11991 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11992 "@
11993 shr{l}\t{%2, %0|%0, %2}
11994 shr{l}\t{%b2, %0|%0, %b2}"
11995 [(set_attr "type" "ishift")
11996 (set_attr "mode" "SI")])
11997
11998 (define_insn "*lshrsi3_1_zext"
11999 [(set (match_operand:DI 0 "register_operand" "=r,r")
12000 (zero_extend:DI
12001 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12002 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12003 (clobber (reg:CC 17))]
12004 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12005 "@
12006 shr{l}\t{%2, %k0|%k0, %2}
12007 shr{l}\t{%b2, %k0|%k0, %b2}"
12008 [(set_attr "type" "ishift")
12009 (set_attr "mode" "SI")])
12010
12011 ;; This pattern can't accept a variable shift count, since shifts by
12012 ;; zero don't affect the flags. We assume that shifts by constant
12013 ;; zero are optimized away.
12014 (define_insn "*lshrsi3_one_bit_cmp"
12015 [(set (reg 17)
12016 (compare
12017 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12018 (match_operand:QI 2 "const1_operand" ""))
12019 (const_int 0)))
12020 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12021 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12022 "ix86_match_ccmode (insn, CCGOCmode)
12023 && (TARGET_SHIFT1 || optimize_size)
12024 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12025 "shr{l}\t%0"
12026 [(set_attr "type" "ishift")
12027 (set (attr "length")
12028 (if_then_else (match_operand:SI 0 "register_operand" "")
12029 (const_string "2")
12030 (const_string "*")))])
12031
12032 (define_insn "*lshrsi3_cmp_one_bit_zext"
12033 [(set (reg 17)
12034 (compare
12035 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12036 (match_operand:QI 2 "const1_operand" ""))
12037 (const_int 0)))
12038 (set (match_operand:DI 0 "register_operand" "=r")
12039 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12040 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12041 && (TARGET_SHIFT1 || optimize_size)
12042 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12043 "shr{l}\t%k0"
12044 [(set_attr "type" "ishift")
12045 (set_attr "length" "2")])
12046
12047 ;; This pattern can't accept a variable shift count, since shifts by
12048 ;; zero don't affect the flags. We assume that shifts by constant
12049 ;; zero are optimized away.
12050 (define_insn "*lshrsi3_cmp"
12051 [(set (reg 17)
12052 (compare
12053 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12054 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12055 (const_int 0)))
12056 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12057 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12058 "ix86_match_ccmode (insn, CCGOCmode)
12059 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12060 "shr{l}\t{%2, %0|%0, %2}"
12061 [(set_attr "type" "ishift")
12062 (set_attr "mode" "SI")])
12063
12064 (define_insn "*lshrsi3_cmp_zext"
12065 [(set (reg 17)
12066 (compare
12067 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12068 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12069 (const_int 0)))
12070 (set (match_operand:DI 0 "register_operand" "=r")
12071 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12072 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12073 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12074 "shr{l}\t{%2, %k0|%k0, %2}"
12075 [(set_attr "type" "ishift")
12076 (set_attr "mode" "SI")])
12077
12078 (define_expand "lshrhi3"
12079 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12080 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12081 (match_operand:QI 2 "nonmemory_operand" "")))
12082 (clobber (reg:CC 17))]
12083 "TARGET_HIMODE_MATH"
12084 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12085
12086 (define_insn "*lshrhi3_1_one_bit"
12087 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12089 (match_operand:QI 2 "const1_operand" "")))
12090 (clobber (reg:CC 17))]
12091 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12092 && (TARGET_SHIFT1 || optimize_size)"
12093 "shr{w}\t%0"
12094 [(set_attr "type" "ishift")
12095 (set (attr "length")
12096 (if_then_else (match_operand 0 "register_operand" "")
12097 (const_string "2")
12098 (const_string "*")))])
12099
12100 (define_insn "*lshrhi3_1"
12101 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12102 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12103 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12104 (clobber (reg:CC 17))]
12105 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12106 "@
12107 shr{w}\t{%2, %0|%0, %2}
12108 shr{w}\t{%b2, %0|%0, %b2}"
12109 [(set_attr "type" "ishift")
12110 (set_attr "mode" "HI")])
12111
12112 ;; This pattern can't accept a variable shift count, since shifts by
12113 ;; zero don't affect the flags. We assume that shifts by constant
12114 ;; zero are optimized away.
12115 (define_insn "*lshrhi3_one_bit_cmp"
12116 [(set (reg 17)
12117 (compare
12118 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12119 (match_operand:QI 2 "const1_operand" ""))
12120 (const_int 0)))
12121 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12122 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12123 "ix86_match_ccmode (insn, CCGOCmode)
12124 && (TARGET_SHIFT1 || optimize_size)
12125 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12126 "shr{w}\t%0"
12127 [(set_attr "type" "ishift")
12128 (set (attr "length")
12129 (if_then_else (match_operand:SI 0 "register_operand" "")
12130 (const_string "2")
12131 (const_string "*")))])
12132
12133 ;; This pattern can't accept a variable shift count, since shifts by
12134 ;; zero don't affect the flags. We assume that shifts by constant
12135 ;; zero are optimized away.
12136 (define_insn "*lshrhi3_cmp"
12137 [(set (reg 17)
12138 (compare
12139 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12140 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12141 (const_int 0)))
12142 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12143 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12144 "ix86_match_ccmode (insn, CCGOCmode)
12145 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12146 "shr{w}\t{%2, %0|%0, %2}"
12147 [(set_attr "type" "ishift")
12148 (set_attr "mode" "HI")])
12149
12150 (define_expand "lshrqi3"
12151 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12152 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC 17))]
12155 "TARGET_QIMODE_MATH"
12156 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12157
12158 (define_insn "*lshrqi3_1_one_bit"
12159 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12160 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12161 (match_operand:QI 2 "const1_operand" "")))
12162 (clobber (reg:CC 17))]
12163 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12164 && (TARGET_SHIFT1 || optimize_size)"
12165 "shr{b}\t%0"
12166 [(set_attr "type" "ishift")
12167 (set (attr "length")
12168 (if_then_else (match_operand 0 "register_operand" "")
12169 (const_string "2")
12170 (const_string "*")))])
12171
12172 (define_insn "*lshrqi3_1_one_bit_slp"
12173 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12174 (lshiftrt:QI (match_dup 0)
12175 (match_operand:QI 1 "const1_operand" "")))
12176 (clobber (reg:CC 17))]
12177 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12178 && (TARGET_SHIFT1 || optimize_size)"
12179 "shr{b}\t%0"
12180 [(set_attr "type" "ishift1")
12181 (set (attr "length")
12182 (if_then_else (match_operand 0 "register_operand" "")
12183 (const_string "2")
12184 (const_string "*")))])
12185
12186 (define_insn "*lshrqi3_1"
12187 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC 17))]
12191 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12192 "@
12193 shr{b}\t{%2, %0|%0, %2}
12194 shr{b}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "ishift")
12196 (set_attr "mode" "QI")])
12197
12198 (define_insn "*lshrqi3_1_slp"
12199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12200 (lshiftrt:QI (match_dup 0)
12201 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12202 (clobber (reg:CC 17))]
12203 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12205 "@
12206 shr{b}\t{%1, %0|%0, %1}
12207 shr{b}\t{%b1, %0|%0, %b1}"
12208 [(set_attr "type" "ishift1")
12209 (set_attr "mode" "QI")])
12210
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags. We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrqi2_one_bit_cmp"
12215 [(set (reg 17)
12216 (compare
12217 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const1_operand" ""))
12219 (const_int 0)))
12220 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12221 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && (TARGET_SHIFT1 || optimize_size)
12224 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12225 "shr{b}\t%0"
12226 [(set_attr "type" "ishift")
12227 (set (attr "length")
12228 (if_then_else (match_operand:SI 0 "register_operand" "")
12229 (const_string "2")
12230 (const_string "*")))])
12231
12232 ;; This pattern can't accept a variable shift count, since shifts by
12233 ;; zero don't affect the flags. We assume that shifts by constant
12234 ;; zero are optimized away.
12235 (define_insn "*lshrqi2_cmp"
12236 [(set (reg 17)
12237 (compare
12238 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12239 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12240 (const_int 0)))
12241 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12242 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12245 "shr{b}\t{%2, %0|%0, %2}"
12246 [(set_attr "type" "ishift")
12247 (set_attr "mode" "QI")])
12248 \f
12249 ;; Rotate instructions
12250
12251 (define_expand "rotldi3"
12252 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12253 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12254 (match_operand:QI 2 "nonmemory_operand" "")))
12255 (clobber (reg:CC 17))]
12256 "TARGET_64BIT"
12257 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12258
12259 (define_insn "*rotlsi3_1_one_bit_rex64"
12260 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12261 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12262 (match_operand:QI 2 "const1_operand" "")))
12263 (clobber (reg:CC 17))]
12264 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12265 && (TARGET_SHIFT1 || optimize_size)"
12266 "rol{q}\t%0"
12267 [(set_attr "type" "rotate")
12268 (set (attr "length")
12269 (if_then_else (match_operand:DI 0 "register_operand" "")
12270 (const_string "2")
12271 (const_string "*")))])
12272
12273 (define_insn "*rotldi3_1_rex64"
12274 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12275 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12276 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12277 (clobber (reg:CC 17))]
12278 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12279 "@
12280 rol{q}\t{%2, %0|%0, %2}
12281 rol{q}\t{%b2, %0|%0, %b2}"
12282 [(set_attr "type" "rotate")
12283 (set_attr "mode" "DI")])
12284
12285 (define_expand "rotlsi3"
12286 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12287 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12288 (match_operand:QI 2 "nonmemory_operand" "")))
12289 (clobber (reg:CC 17))]
12290 ""
12291 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12292
12293 (define_insn "*rotlsi3_1_one_bit"
12294 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12295 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12296 (match_operand:QI 2 "const1_operand" "")))
12297 (clobber (reg:CC 17))]
12298 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12299 && (TARGET_SHIFT1 || optimize_size)"
12300 "rol{l}\t%0"
12301 [(set_attr "type" "rotate")
12302 (set (attr "length")
12303 (if_then_else (match_operand:SI 0 "register_operand" "")
12304 (const_string "2")
12305 (const_string "*")))])
12306
12307 (define_insn "*rotlsi3_1_one_bit_zext"
12308 [(set (match_operand:DI 0 "register_operand" "=r")
12309 (zero_extend:DI
12310 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12311 (match_operand:QI 2 "const1_operand" ""))))
12312 (clobber (reg:CC 17))]
12313 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12314 && (TARGET_SHIFT1 || optimize_size)"
12315 "rol{l}\t%k0"
12316 [(set_attr "type" "rotate")
12317 (set_attr "length" "2")])
12318
12319 (define_insn "*rotlsi3_1"
12320 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12321 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12322 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12323 (clobber (reg:CC 17))]
12324 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12325 "@
12326 rol{l}\t{%2, %0|%0, %2}
12327 rol{l}\t{%b2, %0|%0, %b2}"
12328 [(set_attr "type" "rotate")
12329 (set_attr "mode" "SI")])
12330
12331 (define_insn "*rotlsi3_1_zext"
12332 [(set (match_operand:DI 0 "register_operand" "=r,r")
12333 (zero_extend:DI
12334 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12335 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12336 (clobber (reg:CC 17))]
12337 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12338 "@
12339 rol{l}\t{%2, %k0|%k0, %2}
12340 rol{l}\t{%b2, %k0|%k0, %b2}"
12341 [(set_attr "type" "rotate")
12342 (set_attr "mode" "SI")])
12343
12344 (define_expand "rotlhi3"
12345 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12346 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12347 (match_operand:QI 2 "nonmemory_operand" "")))
12348 (clobber (reg:CC 17))]
12349 "TARGET_HIMODE_MATH"
12350 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12351
12352 (define_insn "*rotlhi3_1_one_bit"
12353 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12355 (match_operand:QI 2 "const1_operand" "")))
12356 (clobber (reg:CC 17))]
12357 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12358 && (TARGET_SHIFT1 || optimize_size)"
12359 "rol{w}\t%0"
12360 [(set_attr "type" "rotate")
12361 (set (attr "length")
12362 (if_then_else (match_operand 0 "register_operand" "")
12363 (const_string "2")
12364 (const_string "*")))])
12365
12366 (define_insn "*rotlhi3_1"
12367 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12368 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12369 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12370 (clobber (reg:CC 17))]
12371 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12372 "@
12373 rol{w}\t{%2, %0|%0, %2}
12374 rol{w}\t{%b2, %0|%0, %b2}"
12375 [(set_attr "type" "rotate")
12376 (set_attr "mode" "HI")])
12377
12378 (define_expand "rotlqi3"
12379 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12380 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12381 (match_operand:QI 2 "nonmemory_operand" "")))
12382 (clobber (reg:CC 17))]
12383 "TARGET_QIMODE_MATH"
12384 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12385
12386 (define_insn "*rotlqi3_1_one_bit_slp"
12387 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388 (rotate:QI (match_dup 0)
12389 (match_operand:QI 1 "const1_operand" "")))
12390 (clobber (reg:CC 17))]
12391 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392 && (TARGET_SHIFT1 || optimize_size)"
12393 "rol{b}\t%0"
12394 [(set_attr "type" "rotate1")
12395 (set (attr "length")
12396 (if_then_else (match_operand 0 "register_operand" "")
12397 (const_string "2")
12398 (const_string "*")))])
12399
12400 (define_insn "*rotlqi3_1_one_bit"
12401 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12402 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12403 (match_operand:QI 2 "const1_operand" "")))
12404 (clobber (reg:CC 17))]
12405 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12406 && (TARGET_SHIFT1 || optimize_size)"
12407 "rol{b}\t%0"
12408 [(set_attr "type" "rotate")
12409 (set (attr "length")
12410 (if_then_else (match_operand 0 "register_operand" "")
12411 (const_string "2")
12412 (const_string "*")))])
12413
12414 (define_insn "*rotlqi3_1_slp"
12415 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12416 (rotate:QI (match_dup 0)
12417 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12418 (clobber (reg:CC 17))]
12419 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12420 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12421 "@
12422 rol{b}\t{%1, %0|%0, %1}
12423 rol{b}\t{%b1, %0|%0, %b1}"
12424 [(set_attr "type" "rotate1")
12425 (set_attr "mode" "QI")])
12426
12427 (define_insn "*rotlqi3_1"
12428 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12429 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12430 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431 (clobber (reg:CC 17))]
12432 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12433 "@
12434 rol{b}\t{%2, %0|%0, %2}
12435 rol{b}\t{%b2, %0|%0, %b2}"
12436 [(set_attr "type" "rotate")
12437 (set_attr "mode" "QI")])
12438
12439 (define_expand "rotrdi3"
12440 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12441 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12442 (match_operand:QI 2 "nonmemory_operand" "")))
12443 (clobber (reg:CC 17))]
12444 "TARGET_64BIT"
12445 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12446
12447 (define_insn "*rotrdi3_1_one_bit_rex64"
12448 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12449 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" "")))
12451 (clobber (reg:CC 17))]
12452 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12453 && (TARGET_SHIFT1 || optimize_size)"
12454 "ror{q}\t%0"
12455 [(set_attr "type" "rotate")
12456 (set (attr "length")
12457 (if_then_else (match_operand:DI 0 "register_operand" "")
12458 (const_string "2")
12459 (const_string "*")))])
12460
12461 (define_insn "*rotrdi3_1_rex64"
12462 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12463 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12464 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12465 (clobber (reg:CC 17))]
12466 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12467 "@
12468 ror{q}\t{%2, %0|%0, %2}
12469 ror{q}\t{%b2, %0|%0, %b2}"
12470 [(set_attr "type" "rotate")
12471 (set_attr "mode" "DI")])
12472
12473 (define_expand "rotrsi3"
12474 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12475 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12476 (match_operand:QI 2 "nonmemory_operand" "")))
12477 (clobber (reg:CC 17))]
12478 ""
12479 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12480
12481 (define_insn "*rotrsi3_1_one_bit"
12482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12483 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12484 (match_operand:QI 2 "const1_operand" "")))
12485 (clobber (reg:CC 17))]
12486 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12487 && (TARGET_SHIFT1 || optimize_size)"
12488 "ror{l}\t%0"
12489 [(set_attr "type" "rotate")
12490 (set (attr "length")
12491 (if_then_else (match_operand:SI 0 "register_operand" "")
12492 (const_string "2")
12493 (const_string "*")))])
12494
12495 (define_insn "*rotrsi3_1_one_bit_zext"
12496 [(set (match_operand:DI 0 "register_operand" "=r")
12497 (zero_extend:DI
12498 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12499 (match_operand:QI 2 "const1_operand" ""))))
12500 (clobber (reg:CC 17))]
12501 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12502 && (TARGET_SHIFT1 || optimize_size)"
12503 "ror{l}\t%k0"
12504 [(set_attr "type" "rotate")
12505 (set (attr "length")
12506 (if_then_else (match_operand:SI 0 "register_operand" "")
12507 (const_string "2")
12508 (const_string "*")))])
12509
12510 (define_insn "*rotrsi3_1"
12511 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12512 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12513 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12514 (clobber (reg:CC 17))]
12515 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12516 "@
12517 ror{l}\t{%2, %0|%0, %2}
12518 ror{l}\t{%b2, %0|%0, %b2}"
12519 [(set_attr "type" "rotate")
12520 (set_attr "mode" "SI")])
12521
12522 (define_insn "*rotrsi3_1_zext"
12523 [(set (match_operand:DI 0 "register_operand" "=r,r")
12524 (zero_extend:DI
12525 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12526 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12527 (clobber (reg:CC 17))]
12528 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12529 "@
12530 ror{l}\t{%2, %k0|%k0, %2}
12531 ror{l}\t{%b2, %k0|%k0, %b2}"
12532 [(set_attr "type" "rotate")
12533 (set_attr "mode" "SI")])
12534
12535 (define_expand "rotrhi3"
12536 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12537 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12538 (match_operand:QI 2 "nonmemory_operand" "")))
12539 (clobber (reg:CC 17))]
12540 "TARGET_HIMODE_MATH"
12541 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12542
12543 (define_insn "*rotrhi3_one_bit"
12544 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12545 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12546 (match_operand:QI 2 "const1_operand" "")))
12547 (clobber (reg:CC 17))]
12548 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12549 && (TARGET_SHIFT1 || optimize_size)"
12550 "ror{w}\t%0"
12551 [(set_attr "type" "rotate")
12552 (set (attr "length")
12553 (if_then_else (match_operand 0 "register_operand" "")
12554 (const_string "2")
12555 (const_string "*")))])
12556
12557 (define_insn "*rotrhi3"
12558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12559 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561 (clobber (reg:CC 17))]
12562 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12563 "@
12564 ror{w}\t{%2, %0|%0, %2}
12565 ror{w}\t{%b2, %0|%0, %b2}"
12566 [(set_attr "type" "rotate")
12567 (set_attr "mode" "HI")])
12568
12569 (define_expand "rotrqi3"
12570 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12571 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12572 (match_operand:QI 2 "nonmemory_operand" "")))
12573 (clobber (reg:CC 17))]
12574 "TARGET_QIMODE_MATH"
12575 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12576
12577 (define_insn "*rotrqi3_1_one_bit"
12578 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12579 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12580 (match_operand:QI 2 "const1_operand" "")))
12581 (clobber (reg:CC 17))]
12582 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12583 && (TARGET_SHIFT1 || optimize_size)"
12584 "ror{b}\t%0"
12585 [(set_attr "type" "rotate")
12586 (set (attr "length")
12587 (if_then_else (match_operand 0 "register_operand" "")
12588 (const_string "2")
12589 (const_string "*")))])
12590
12591 (define_insn "*rotrqi3_1_one_bit_slp"
12592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12593 (rotatert:QI (match_dup 0)
12594 (match_operand:QI 1 "const1_operand" "")))
12595 (clobber (reg:CC 17))]
12596 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12597 && (TARGET_SHIFT1 || optimize_size)"
12598 "ror{b}\t%0"
12599 [(set_attr "type" "rotate1")
12600 (set (attr "length")
12601 (if_then_else (match_operand 0 "register_operand" "")
12602 (const_string "2")
12603 (const_string "*")))])
12604
12605 (define_insn "*rotrqi3_1"
12606 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12607 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12608 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12609 (clobber (reg:CC 17))]
12610 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12611 "@
12612 ror{b}\t{%2, %0|%0, %2}
12613 ror{b}\t{%b2, %0|%0, %b2}"
12614 [(set_attr "type" "rotate")
12615 (set_attr "mode" "QI")])
12616
12617 (define_insn "*rotrqi3_1_slp"
12618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12619 (rotatert:QI (match_dup 0)
12620 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12621 (clobber (reg:CC 17))]
12622 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12623 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12624 "@
12625 ror{b}\t{%1, %0|%0, %1}
12626 ror{b}\t{%b1, %0|%0, %b1}"
12627 [(set_attr "type" "rotate1")
12628 (set_attr "mode" "QI")])
12629 \f
12630 ;; Bit set / bit test instructions
12631
12632 (define_expand "extv"
12633 [(set (match_operand:SI 0 "register_operand" "")
12634 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12635 (match_operand:SI 2 "immediate_operand" "")
12636 (match_operand:SI 3 "immediate_operand" "")))]
12637 ""
12638 {
12639 /* Handle extractions from %ah et al. */
12640 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12641 FAIL;
12642
12643 /* From mips.md: extract_bit_field doesn't verify that our source
12644 matches the predicate, so check it again here. */
12645 if (! register_operand (operands[1], VOIDmode))
12646 FAIL;
12647 })
12648
12649 (define_expand "extzv"
12650 [(set (match_operand:SI 0 "register_operand" "")
12651 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12652 (match_operand:SI 2 "immediate_operand" "")
12653 (match_operand:SI 3 "immediate_operand" "")))]
12654 ""
12655 {
12656 /* Handle extractions from %ah et al. */
12657 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12658 FAIL;
12659
12660 /* From mips.md: extract_bit_field doesn't verify that our source
12661 matches the predicate, so check it again here. */
12662 if (! register_operand (operands[1], VOIDmode))
12663 FAIL;
12664 })
12665
12666 (define_expand "insv"
12667 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
12668 (match_operand:SI 1 "immediate_operand" "")
12669 (match_operand:SI 2 "immediate_operand" ""))
12670 (match_operand:SI 3 "register_operand" ""))]
12671 ""
12672 {
12673 /* Handle extractions from %ah et al. */
12674 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12675 FAIL;
12676
12677 /* From mips.md: insert_bit_field doesn't verify that our source
12678 matches the predicate, so check it again here. */
12679 if (! register_operand (operands[0], VOIDmode))
12680 FAIL;
12681 })
12682
12683 ;; %%% bts, btr, btc, bt.
12684 \f
12685 ;; Store-flag instructions.
12686
12687 ;; For all sCOND expanders, also expand the compare or test insn that
12688 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12689
12690 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12691 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12692 ;; way, which can later delete the movzx if only QImode is needed.
12693
12694 (define_expand "seq"
12695 [(set (match_operand:QI 0 "register_operand" "")
12696 (eq:QI (reg:CC 17) (const_int 0)))]
12697 ""
12698 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12699
12700 (define_expand "sne"
12701 [(set (match_operand:QI 0 "register_operand" "")
12702 (ne:QI (reg:CC 17) (const_int 0)))]
12703 ""
12704 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12705
12706 (define_expand "sgt"
12707 [(set (match_operand:QI 0 "register_operand" "")
12708 (gt:QI (reg:CC 17) (const_int 0)))]
12709 ""
12710 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12711
12712 (define_expand "sgtu"
12713 [(set (match_operand:QI 0 "register_operand" "")
12714 (gtu:QI (reg:CC 17) (const_int 0)))]
12715 ""
12716 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12717
12718 (define_expand "slt"
12719 [(set (match_operand:QI 0 "register_operand" "")
12720 (lt:QI (reg:CC 17) (const_int 0)))]
12721 ""
12722 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12723
12724 (define_expand "sltu"
12725 [(set (match_operand:QI 0 "register_operand" "")
12726 (ltu:QI (reg:CC 17) (const_int 0)))]
12727 ""
12728 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12729
12730 (define_expand "sge"
12731 [(set (match_operand:QI 0 "register_operand" "")
12732 (ge:QI (reg:CC 17) (const_int 0)))]
12733 ""
12734 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12735
12736 (define_expand "sgeu"
12737 [(set (match_operand:QI 0 "register_operand" "")
12738 (geu:QI (reg:CC 17) (const_int 0)))]
12739 ""
12740 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12741
12742 (define_expand "sle"
12743 [(set (match_operand:QI 0 "register_operand" "")
12744 (le:QI (reg:CC 17) (const_int 0)))]
12745 ""
12746 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12747
12748 (define_expand "sleu"
12749 [(set (match_operand:QI 0 "register_operand" "")
12750 (leu:QI (reg:CC 17) (const_int 0)))]
12751 ""
12752 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12753
12754 (define_expand "sunordered"
12755 [(set (match_operand:QI 0 "register_operand" "")
12756 (unordered:QI (reg:CC 17) (const_int 0)))]
12757 "TARGET_80387 || TARGET_SSE"
12758 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12759
12760 (define_expand "sordered"
12761 [(set (match_operand:QI 0 "register_operand" "")
12762 (ordered:QI (reg:CC 17) (const_int 0)))]
12763 "TARGET_80387"
12764 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12765
12766 (define_expand "suneq"
12767 [(set (match_operand:QI 0 "register_operand" "")
12768 (uneq:QI (reg:CC 17) (const_int 0)))]
12769 "TARGET_80387 || TARGET_SSE"
12770 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12771
12772 (define_expand "sunge"
12773 [(set (match_operand:QI 0 "register_operand" "")
12774 (unge:QI (reg:CC 17) (const_int 0)))]
12775 "TARGET_80387 || TARGET_SSE"
12776 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12777
12778 (define_expand "sungt"
12779 [(set (match_operand:QI 0 "register_operand" "")
12780 (ungt:QI (reg:CC 17) (const_int 0)))]
12781 "TARGET_80387 || TARGET_SSE"
12782 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12783
12784 (define_expand "sunle"
12785 [(set (match_operand:QI 0 "register_operand" "")
12786 (unle:QI (reg:CC 17) (const_int 0)))]
12787 "TARGET_80387 || TARGET_SSE"
12788 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12789
12790 (define_expand "sunlt"
12791 [(set (match_operand:QI 0 "register_operand" "")
12792 (unlt:QI (reg:CC 17) (const_int 0)))]
12793 "TARGET_80387 || TARGET_SSE"
12794 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12795
12796 (define_expand "sltgt"
12797 [(set (match_operand:QI 0 "register_operand" "")
12798 (ltgt:QI (reg:CC 17) (const_int 0)))]
12799 "TARGET_80387 || TARGET_SSE"
12800 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12801
12802 (define_insn "*setcc_1"
12803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12804 (match_operator:QI 1 "ix86_comparison_operator"
12805 [(reg 17) (const_int 0)]))]
12806 ""
12807 "set%C1\t%0"
12808 [(set_attr "type" "setcc")
12809 (set_attr "mode" "QI")])
12810
12811 (define_insn "setcc_2"
12812 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12813 (match_operator:QI 1 "ix86_comparison_operator"
12814 [(reg 17) (const_int 0)]))]
12815 ""
12816 "set%C1\t%0"
12817 [(set_attr "type" "setcc")
12818 (set_attr "mode" "QI")])
12819
12820 ;; In general it is not safe to assume too much about CCmode registers,
12821 ;; so simplify-rtx stops when it sees a second one. Under certain
12822 ;; conditions this is safe on x86, so help combine not create
12823 ;;
12824 ;; seta %al
12825 ;; testb %al, %al
12826 ;; sete %al
12827
12828 (define_split
12829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12830 (ne:QI (match_operator 1 "ix86_comparison_operator"
12831 [(reg 17) (const_int 0)])
12832 (const_int 0)))]
12833 ""
12834 [(set (match_dup 0) (match_dup 1))]
12835 {
12836 PUT_MODE (operands[1], QImode);
12837 })
12838
12839 (define_split
12840 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12841 (ne:QI (match_operator 1 "ix86_comparison_operator"
12842 [(reg 17) (const_int 0)])
12843 (const_int 0)))]
12844 ""
12845 [(set (match_dup 0) (match_dup 1))]
12846 {
12847 PUT_MODE (operands[1], QImode);
12848 })
12849
12850 (define_split
12851 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12852 (eq:QI (match_operator 1 "ix86_comparison_operator"
12853 [(reg 17) (const_int 0)])
12854 (const_int 0)))]
12855 ""
12856 [(set (match_dup 0) (match_dup 1))]
12857 {
12858 rtx new_op1 = copy_rtx (operands[1]);
12859 operands[1] = new_op1;
12860 PUT_MODE (new_op1, QImode);
12861 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12862 GET_MODE (XEXP (new_op1, 0))));
12863
12864 /* Make sure that (a) the CCmode we have for the flags is strong
12865 enough for the reversed compare or (b) we have a valid FP compare. */
12866 if (! ix86_comparison_operator (new_op1, VOIDmode))
12867 FAIL;
12868 })
12869
12870 (define_split
12871 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12872 (eq:QI (match_operator 1 "ix86_comparison_operator"
12873 [(reg 17) (const_int 0)])
12874 (const_int 0)))]
12875 ""
12876 [(set (match_dup 0) (match_dup 1))]
12877 {
12878 rtx new_op1 = copy_rtx (operands[1]);
12879 operands[1] = new_op1;
12880 PUT_MODE (new_op1, QImode);
12881 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
12882 GET_MODE (XEXP (new_op1, 0))));
12883
12884 /* Make sure that (a) the CCmode we have for the flags is strong
12885 enough for the reversed compare or (b) we have a valid FP compare. */
12886 if (! ix86_comparison_operator (new_op1, VOIDmode))
12887 FAIL;
12888 })
12889
12890 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12891 ;; subsequent logical operations are used to imitate conditional moves.
12892 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12893 ;; it directly. Further holding this value in pseudo register might bring
12894 ;; problem in implicit normalization in spill code.
12895 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12896 ;; instructions after reload by splitting the conditional move patterns.
12897
12898 (define_insn "*sse_setccsf"
12899 [(set (match_operand:SF 0 "register_operand" "=x")
12900 (match_operator:SF 1 "sse_comparison_operator"
12901 [(match_operand:SF 2 "register_operand" "0")
12902 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12903 "TARGET_SSE && reload_completed"
12904 "cmp%D1ss\t{%3, %0|%0, %3}"
12905 [(set_attr "type" "ssecmp")
12906 (set_attr "mode" "SF")])
12907
12908 (define_insn "*sse_setccdf"
12909 [(set (match_operand:DF 0 "register_operand" "=Y")
12910 (match_operator:DF 1 "sse_comparison_operator"
12911 [(match_operand:DF 2 "register_operand" "0")
12912 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12913 "TARGET_SSE2 && reload_completed"
12914 "cmp%D1sd\t{%3, %0|%0, %3}"
12915 [(set_attr "type" "ssecmp")
12916 (set_attr "mode" "DF")])
12917 \f
12918 ;; Basic conditional jump instructions.
12919 ;; We ignore the overflow flag for signed branch instructions.
12920
12921 ;; For all bCOND expanders, also expand the compare or test insn that
12922 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12923
12924 (define_expand "beq"
12925 [(set (pc)
12926 (if_then_else (match_dup 1)
12927 (label_ref (match_operand 0 "" ""))
12928 (pc)))]
12929 ""
12930 "ix86_expand_branch (EQ, operands[0]); DONE;")
12931
12932 (define_expand "bne"
12933 [(set (pc)
12934 (if_then_else (match_dup 1)
12935 (label_ref (match_operand 0 "" ""))
12936 (pc)))]
12937 ""
12938 "ix86_expand_branch (NE, operands[0]); DONE;")
12939
12940 (define_expand "bgt"
12941 [(set (pc)
12942 (if_then_else (match_dup 1)
12943 (label_ref (match_operand 0 "" ""))
12944 (pc)))]
12945 ""
12946 "ix86_expand_branch (GT, operands[0]); DONE;")
12947
12948 (define_expand "bgtu"
12949 [(set (pc)
12950 (if_then_else (match_dup 1)
12951 (label_ref (match_operand 0 "" ""))
12952 (pc)))]
12953 ""
12954 "ix86_expand_branch (GTU, operands[0]); DONE;")
12955
12956 (define_expand "blt"
12957 [(set (pc)
12958 (if_then_else (match_dup 1)
12959 (label_ref (match_operand 0 "" ""))
12960 (pc)))]
12961 ""
12962 "ix86_expand_branch (LT, operands[0]); DONE;")
12963
12964 (define_expand "bltu"
12965 [(set (pc)
12966 (if_then_else (match_dup 1)
12967 (label_ref (match_operand 0 "" ""))
12968 (pc)))]
12969 ""
12970 "ix86_expand_branch (LTU, operands[0]); DONE;")
12971
12972 (define_expand "bge"
12973 [(set (pc)
12974 (if_then_else (match_dup 1)
12975 (label_ref (match_operand 0 "" ""))
12976 (pc)))]
12977 ""
12978 "ix86_expand_branch (GE, operands[0]); DONE;")
12979
12980 (define_expand "bgeu"
12981 [(set (pc)
12982 (if_then_else (match_dup 1)
12983 (label_ref (match_operand 0 "" ""))
12984 (pc)))]
12985 ""
12986 "ix86_expand_branch (GEU, operands[0]); DONE;")
12987
12988 (define_expand "ble"
12989 [(set (pc)
12990 (if_then_else (match_dup 1)
12991 (label_ref (match_operand 0 "" ""))
12992 (pc)))]
12993 ""
12994 "ix86_expand_branch (LE, operands[0]); DONE;")
12995
12996 (define_expand "bleu"
12997 [(set (pc)
12998 (if_then_else (match_dup 1)
12999 (label_ref (match_operand 0 "" ""))
13000 (pc)))]
13001 ""
13002 "ix86_expand_branch (LEU, operands[0]); DONE;")
13003
13004 (define_expand "bunordered"
13005 [(set (pc)
13006 (if_then_else (match_dup 1)
13007 (label_ref (match_operand 0 "" ""))
13008 (pc)))]
13009 "TARGET_80387 || TARGET_SSE"
13010 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13011
13012 (define_expand "bordered"
13013 [(set (pc)
13014 (if_then_else (match_dup 1)
13015 (label_ref (match_operand 0 "" ""))
13016 (pc)))]
13017 "TARGET_80387 || TARGET_SSE"
13018 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13019
13020 (define_expand "buneq"
13021 [(set (pc)
13022 (if_then_else (match_dup 1)
13023 (label_ref (match_operand 0 "" ""))
13024 (pc)))]
13025 "TARGET_80387 || TARGET_SSE"
13026 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13027
13028 (define_expand "bunge"
13029 [(set (pc)
13030 (if_then_else (match_dup 1)
13031 (label_ref (match_operand 0 "" ""))
13032 (pc)))]
13033 "TARGET_80387 || TARGET_SSE"
13034 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13035
13036 (define_expand "bungt"
13037 [(set (pc)
13038 (if_then_else (match_dup 1)
13039 (label_ref (match_operand 0 "" ""))
13040 (pc)))]
13041 "TARGET_80387 || TARGET_SSE"
13042 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13043
13044 (define_expand "bunle"
13045 [(set (pc)
13046 (if_then_else (match_dup 1)
13047 (label_ref (match_operand 0 "" ""))
13048 (pc)))]
13049 "TARGET_80387 || TARGET_SSE"
13050 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13051
13052 (define_expand "bunlt"
13053 [(set (pc)
13054 (if_then_else (match_dup 1)
13055 (label_ref (match_operand 0 "" ""))
13056 (pc)))]
13057 "TARGET_80387 || TARGET_SSE"
13058 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13059
13060 (define_expand "bltgt"
13061 [(set (pc)
13062 (if_then_else (match_dup 1)
13063 (label_ref (match_operand 0 "" ""))
13064 (pc)))]
13065 "TARGET_80387 || TARGET_SSE"
13066 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13067
13068 (define_insn "*jcc_1"
13069 [(set (pc)
13070 (if_then_else (match_operator 1 "ix86_comparison_operator"
13071 [(reg 17) (const_int 0)])
13072 (label_ref (match_operand 0 "" ""))
13073 (pc)))]
13074 ""
13075 "%+j%C1\t%l0"
13076 [(set_attr "type" "ibr")
13077 (set_attr "modrm" "0")
13078 (set (attr "length")
13079 (if_then_else (and (ge (minus (match_dup 0) (pc))
13080 (const_int -126))
13081 (lt (minus (match_dup 0) (pc))
13082 (const_int 128)))
13083 (const_int 2)
13084 (const_int 6)))])
13085
13086 (define_insn "*jcc_2"
13087 [(set (pc)
13088 (if_then_else (match_operator 1 "ix86_comparison_operator"
13089 [(reg 17) (const_int 0)])
13090 (pc)
13091 (label_ref (match_operand 0 "" ""))))]
13092 ""
13093 "%+j%c1\t%l0"
13094 [(set_attr "type" "ibr")
13095 (set_attr "modrm" "0")
13096 (set (attr "length")
13097 (if_then_else (and (ge (minus (match_dup 0) (pc))
13098 (const_int -126))
13099 (lt (minus (match_dup 0) (pc))
13100 (const_int 128)))
13101 (const_int 2)
13102 (const_int 6)))])
13103
13104 ;; In general it is not safe to assume too much about CCmode registers,
13105 ;; so simplify-rtx stops when it sees a second one. Under certain
13106 ;; conditions this is safe on x86, so help combine not create
13107 ;;
13108 ;; seta %al
13109 ;; testb %al, %al
13110 ;; je Lfoo
13111
13112 (define_split
13113 [(set (pc)
13114 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13115 [(reg 17) (const_int 0)])
13116 (const_int 0))
13117 (label_ref (match_operand 1 "" ""))
13118 (pc)))]
13119 ""
13120 [(set (pc)
13121 (if_then_else (match_dup 0)
13122 (label_ref (match_dup 1))
13123 (pc)))]
13124 {
13125 PUT_MODE (operands[0], VOIDmode);
13126 })
13127
13128 (define_split
13129 [(set (pc)
13130 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13131 [(reg 17) (const_int 0)])
13132 (const_int 0))
13133 (label_ref (match_operand 1 "" ""))
13134 (pc)))]
13135 ""
13136 [(set (pc)
13137 (if_then_else (match_dup 0)
13138 (label_ref (match_dup 1))
13139 (pc)))]
13140 {
13141 rtx new_op0 = copy_rtx (operands[0]);
13142 operands[0] = new_op0;
13143 PUT_MODE (new_op0, VOIDmode);
13144 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13145 GET_MODE (XEXP (new_op0, 0))));
13146
13147 /* Make sure that (a) the CCmode we have for the flags is strong
13148 enough for the reversed compare or (b) we have a valid FP compare. */
13149 if (! ix86_comparison_operator (new_op0, VOIDmode))
13150 FAIL;
13151 })
13152
13153 ;; Define combination compare-and-branch fp compare instructions to use
13154 ;; during early optimization. Splitting the operation apart early makes
13155 ;; for bad code when we want to reverse the operation.
13156
13157 (define_insn "*fp_jcc_1"
13158 [(set (pc)
13159 (if_then_else (match_operator 0 "comparison_operator"
13160 [(match_operand 1 "register_operand" "f")
13161 (match_operand 2 "register_operand" "f")])
13162 (label_ref (match_operand 3 "" ""))
13163 (pc)))
13164 (clobber (reg:CCFP 18))
13165 (clobber (reg:CCFP 17))]
13166 "TARGET_CMOVE && TARGET_80387
13167 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13168 && FLOAT_MODE_P (GET_MODE (operands[1]))
13169 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13170 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13171 "#")
13172
13173 (define_insn "*fp_jcc_1_sse"
13174 [(set (pc)
13175 (if_then_else (match_operator 0 "comparison_operator"
13176 [(match_operand 1 "register_operand" "f#x,x#f")
13177 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13178 (label_ref (match_operand 3 "" ""))
13179 (pc)))
13180 (clobber (reg:CCFP 18))
13181 (clobber (reg:CCFP 17))]
13182 "TARGET_80387
13183 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13184 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13185 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186 "#")
13187
13188 (define_insn "*fp_jcc_1_sse_only"
13189 [(set (pc)
13190 (if_then_else (match_operator 0 "comparison_operator"
13191 [(match_operand 1 "register_operand" "x")
13192 (match_operand 2 "nonimmediate_operand" "xm")])
13193 (label_ref (match_operand 3 "" ""))
13194 (pc)))
13195 (clobber (reg:CCFP 18))
13196 (clobber (reg:CCFP 17))]
13197 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13198 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13200 "#")
13201
13202 (define_insn "*fp_jcc_2"
13203 [(set (pc)
13204 (if_then_else (match_operator 0 "comparison_operator"
13205 [(match_operand 1 "register_operand" "f")
13206 (match_operand 2 "register_operand" "f")])
13207 (pc)
13208 (label_ref (match_operand 3 "" ""))))
13209 (clobber (reg:CCFP 18))
13210 (clobber (reg:CCFP 17))]
13211 "TARGET_CMOVE && TARGET_80387
13212 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13213 && FLOAT_MODE_P (GET_MODE (operands[1]))
13214 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13215 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13216 "#")
13217
13218 (define_insn "*fp_jcc_2_sse"
13219 [(set (pc)
13220 (if_then_else (match_operator 0 "comparison_operator"
13221 [(match_operand 1 "register_operand" "f#x,x#f")
13222 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13223 (pc)
13224 (label_ref (match_operand 3 "" ""))))
13225 (clobber (reg:CCFP 18))
13226 (clobber (reg:CCFP 17))]
13227 "TARGET_80387
13228 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13229 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13230 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13231 "#")
13232
13233 (define_insn "*fp_jcc_2_sse_only"
13234 [(set (pc)
13235 (if_then_else (match_operator 0 "comparison_operator"
13236 [(match_operand 1 "register_operand" "x")
13237 (match_operand 2 "nonimmediate_operand" "xm")])
13238 (pc)
13239 (label_ref (match_operand 3 "" ""))))
13240 (clobber (reg:CCFP 18))
13241 (clobber (reg:CCFP 17))]
13242 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13243 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13244 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13245 "#")
13246
13247 (define_insn "*fp_jcc_3"
13248 [(set (pc)
13249 (if_then_else (match_operator 0 "comparison_operator"
13250 [(match_operand 1 "register_operand" "f")
13251 (match_operand 2 "nonimmediate_operand" "fm")])
13252 (label_ref (match_operand 3 "" ""))
13253 (pc)))
13254 (clobber (reg:CCFP 18))
13255 (clobber (reg:CCFP 17))
13256 (clobber (match_scratch:HI 4 "=a"))]
13257 "TARGET_80387
13258 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13259 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13260 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13261 && SELECT_CC_MODE (GET_CODE (operands[0]),
13262 operands[1], operands[2]) == CCFPmode
13263 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13264 "#")
13265
13266 (define_insn "*fp_jcc_4"
13267 [(set (pc)
13268 (if_then_else (match_operator 0 "comparison_operator"
13269 [(match_operand 1 "register_operand" "f")
13270 (match_operand 2 "nonimmediate_operand" "fm")])
13271 (pc)
13272 (label_ref (match_operand 3 "" ""))))
13273 (clobber (reg:CCFP 18))
13274 (clobber (reg:CCFP 17))
13275 (clobber (match_scratch:HI 4 "=a"))]
13276 "TARGET_80387
13277 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13278 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13279 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13280 && SELECT_CC_MODE (GET_CODE (operands[0]),
13281 operands[1], operands[2]) == CCFPmode
13282 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13283 "#")
13284
13285 (define_insn "*fp_jcc_5"
13286 [(set (pc)
13287 (if_then_else (match_operator 0 "comparison_operator"
13288 [(match_operand 1 "register_operand" "f")
13289 (match_operand 2 "register_operand" "f")])
13290 (label_ref (match_operand 3 "" ""))
13291 (pc)))
13292 (clobber (reg:CCFP 18))
13293 (clobber (reg:CCFP 17))
13294 (clobber (match_scratch:HI 4 "=a"))]
13295 "TARGET_80387
13296 && FLOAT_MODE_P (GET_MODE (operands[1]))
13297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299 "#")
13300
13301 (define_insn "*fp_jcc_6"
13302 [(set (pc)
13303 (if_then_else (match_operator 0 "comparison_operator"
13304 [(match_operand 1 "register_operand" "f")
13305 (match_operand 2 "register_operand" "f")])
13306 (pc)
13307 (label_ref (match_operand 3 "" ""))))
13308 (clobber (reg:CCFP 18))
13309 (clobber (reg:CCFP 17))
13310 (clobber (match_scratch:HI 4 "=a"))]
13311 "TARGET_80387
13312 && FLOAT_MODE_P (GET_MODE (operands[1]))
13313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13315 "#")
13316
13317 (define_split
13318 [(set (pc)
13319 (if_then_else (match_operator 0 "comparison_operator"
13320 [(match_operand 1 "register_operand" "")
13321 (match_operand 2 "nonimmediate_operand" "")])
13322 (match_operand 3 "" "")
13323 (match_operand 4 "" "")))
13324 (clobber (reg:CCFP 18))
13325 (clobber (reg:CCFP 17))]
13326 "reload_completed"
13327 [(const_int 0)]
13328 {
13329 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13330 operands[3], operands[4], NULL_RTX);
13331 DONE;
13332 })
13333
13334 (define_split
13335 [(set (pc)
13336 (if_then_else (match_operator 0 "comparison_operator"
13337 [(match_operand 1 "register_operand" "")
13338 (match_operand 2 "nonimmediate_operand" "")])
13339 (match_operand 3 "" "")
13340 (match_operand 4 "" "")))
13341 (clobber (reg:CCFP 18))
13342 (clobber (reg:CCFP 17))
13343 (clobber (match_scratch:HI 5 "=a"))]
13344 "reload_completed"
13345 [(set (pc)
13346 (if_then_else (match_dup 6)
13347 (match_dup 3)
13348 (match_dup 4)))]
13349 {
13350 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13351 operands[3], operands[4], operands[5]);
13352 DONE;
13353 })
13354 \f
13355 ;; Unconditional and other jump instructions
13356
13357 (define_insn "jump"
13358 [(set (pc)
13359 (label_ref (match_operand 0 "" "")))]
13360 ""
13361 "jmp\t%l0"
13362 [(set_attr "type" "ibr")
13363 (set (attr "length")
13364 (if_then_else (and (ge (minus (match_dup 0) (pc))
13365 (const_int -126))
13366 (lt (minus (match_dup 0) (pc))
13367 (const_int 128)))
13368 (const_int 2)
13369 (const_int 5)))
13370 (set_attr "modrm" "0")])
13371
13372 (define_expand "indirect_jump"
13373 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13374 ""
13375 "")
13376
13377 (define_insn "*indirect_jump"
13378 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13379 "!TARGET_64BIT"
13380 "jmp\t%A0"
13381 [(set_attr "type" "ibr")
13382 (set_attr "length_immediate" "0")])
13383
13384 (define_insn "*indirect_jump_rtx64"
13385 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13386 "TARGET_64BIT"
13387 "jmp\t%A0"
13388 [(set_attr "type" "ibr")
13389 (set_attr "length_immediate" "0")])
13390
13391 (define_expand "tablejump"
13392 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13393 (use (label_ref (match_operand 1 "" "")))])]
13394 ""
13395 {
13396 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13397 relative. Convert the relative address to an absolute address. */
13398 if (flag_pic)
13399 {
13400 rtx op0, op1;
13401 enum rtx_code code;
13402
13403 if (TARGET_64BIT)
13404 {
13405 code = PLUS;
13406 op0 = operands[0];
13407 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13408 }
13409 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13410 {
13411 code = PLUS;
13412 op0 = operands[0];
13413 op1 = pic_offset_table_rtx;
13414 }
13415 else
13416 {
13417 code = MINUS;
13418 op0 = pic_offset_table_rtx;
13419 op1 = operands[0];
13420 }
13421
13422 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13423 OPTAB_DIRECT);
13424 }
13425 })
13426
13427 (define_insn "*tablejump_1"
13428 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13429 (use (label_ref (match_operand 1 "" "")))]
13430 "!TARGET_64BIT"
13431 "jmp\t%A0"
13432 [(set_attr "type" "ibr")
13433 (set_attr "length_immediate" "0")])
13434
13435 (define_insn "*tablejump_1_rtx64"
13436 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13437 (use (label_ref (match_operand 1 "" "")))]
13438 "TARGET_64BIT"
13439 "jmp\t%A0"
13440 [(set_attr "type" "ibr")
13441 (set_attr "length_immediate" "0")])
13442 \f
13443 ;; Loop instruction
13444 ;;
13445 ;; This is all complicated by the fact that since this is a jump insn
13446 ;; we must handle our own reloads.
13447
13448 (define_expand "doloop_end"
13449 [(use (match_operand 0 "" "")) ; loop pseudo
13450 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13451 (use (match_operand 2 "" "")) ; max iterations
13452 (use (match_operand 3 "" "")) ; loop level
13453 (use (match_operand 4 "" ""))] ; label
13454 "!TARGET_64BIT && TARGET_USE_LOOP"
13455 "
13456 {
13457 /* Only use cloop on innermost loops. */
13458 if (INTVAL (operands[3]) > 1)
13459 FAIL;
13460 if (GET_MODE (operands[0]) != SImode)
13461 FAIL;
13462 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13463 operands[0]));
13464 DONE;
13465 }")
13466
13467 (define_insn "doloop_end_internal"
13468 [(set (pc)
13469 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13470 (const_int 1))
13471 (label_ref (match_operand 0 "" ""))
13472 (pc)))
13473 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13474 (plus:SI (match_dup 1)
13475 (const_int -1)))
13476 (clobber (match_scratch:SI 3 "=X,X,r"))
13477 (clobber (reg:CC 17))]
13478 "!TARGET_64BIT && TARGET_USE_LOOP"
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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14352 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14353 "* return output_387_binary_op (insn, operands);"
14354 [(set (attr "type")
14355 (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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
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 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
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_insn "*fscale_sfxf3"
15158 [(set (match_operand:SF 0 "register_operand" "=f")
15159 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15160 (match_operand:XF 1 "register_operand" "u")]
15161 UNSPEC_FSCALE))
15162 (clobber (match_scratch:SF 3 "=1"))]
15163 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15164 && flag_unsafe_math_optimizations"
15165 "fscale\;fstp\t%y1"
15166 [(set_attr "type" "fpspc")
15167 (set_attr "mode" "SF")])
15168
15169 (define_insn "*fscale_dfxf3"
15170 [(set (match_operand:DF 0 "register_operand" "=f")
15171 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15172 (match_operand:XF 1 "register_operand" "u")]
15173 UNSPEC_FSCALE))
15174 (clobber (match_scratch:DF 3 "=1"))]
15175 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15176 && flag_unsafe_math_optimizations"
15177 "fscale\;fstp\t%y1"
15178 [(set_attr "type" "fpspc")
15179 (set_attr "mode" "DF")])
15180
15181 (define_insn "*fscale_xf3"
15182 [(set (match_operand:XF 0 "register_operand" "=f")
15183 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15184 (match_operand:XF 1 "register_operand" "u")]
15185 UNSPEC_FSCALE))
15186 (clobber (match_scratch:XF 3 "=1"))]
15187 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15188 && flag_unsafe_math_optimizations"
15189 "fscale\;fstp\t%y1"
15190 [(set_attr "type" "fpspc")
15191 (set_attr "mode" "XF")])
15192
15193 (define_insn "*frndintxf2"
15194 [(set (match_operand:XF 0 "register_operand" "=f")
15195 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15196 UNSPEC_FRNDINT))]
15197 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15198 && flag_unsafe_math_optimizations"
15199 "frndint"
15200 [(set_attr "type" "fpspc")
15201 (set_attr "mode" "XF")])
15202
15203 (define_insn "*f2xm1xf2"
15204 [(set (match_operand:XF 0 "register_operand" "=f")
15205 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15206 UNSPEC_F2XM1))]
15207 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15208 && flag_unsafe_math_optimizations"
15209 "f2xm1"
15210 [(set_attr "type" "fpspc")
15211 (set_attr "mode" "XF")])
15212
15213 (define_expand "expsf2"
15214 [(set (match_dup 2)
15215 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15216 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15217 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15218 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15219 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15220 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15221 (parallel [(set (match_operand:SF 0 "register_operand" "")
15222 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15223 (clobber (match_scratch:SF 5 ""))])]
15224 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15225 && flag_unsafe_math_optimizations"
15226 {
15227 rtx temp;
15228 int i;
15229
15230 for (i=2; i<10; i++)
15231 operands[i] = gen_reg_rtx (XFmode);
15232 temp = standard_80387_constant_rtx (5); /* fldl2e */
15233 emit_move_insn (operands[3], temp);
15234 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15235 })
15236
15237 (define_expand "expdf2"
15238 [(set (match_dup 2)
15239 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15240 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15241 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15242 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15243 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15244 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15245 (parallel [(set (match_operand:DF 0 "register_operand" "")
15246 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15247 (clobber (match_scratch:DF 5 ""))])]
15248 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15249 && flag_unsafe_math_optimizations"
15250 {
15251 rtx temp;
15252 int i;
15253
15254 for (i=2; i<10; i++)
15255 operands[i] = gen_reg_rtx (XFmode);
15256 temp = standard_80387_constant_rtx (5); /* fldl2e */
15257 emit_move_insn (operands[3], temp);
15258 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15259 })
15260
15261 (define_expand "expxf2"
15262 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15263 (match_dup 2)))
15264 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15265 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15266 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15267 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15268 (parallel [(set (match_operand:XF 0 "register_operand" "")
15269 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15270 (clobber (match_scratch:XF 5 ""))])]
15271 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15272 && flag_unsafe_math_optimizations"
15273 {
15274 rtx temp;
15275 int i;
15276
15277 for (i=2; i<9; i++)
15278 operands[i] = gen_reg_rtx (XFmode);
15279 temp = standard_80387_constant_rtx (5); /* fldl2e */
15280 emit_move_insn (operands[2], temp);
15281 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15282 })
15283
15284 (define_expand "atansf2"
15285 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15286 (unspec:SF [(match_dup 2)
15287 (match_operand:SF 1 "register_operand" "")]
15288 UNSPEC_FPATAN))
15289 (clobber (match_scratch:SF 3 ""))])]
15290 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15291 && flag_unsafe_math_optimizations"
15292 {
15293 operands[2] = gen_reg_rtx (SFmode);
15294 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15295 })
15296
15297 (define_expand "atandf2"
15298 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15299 (unspec:DF [(match_dup 2)
15300 (match_operand:DF 1 "register_operand" "")]
15301 UNSPEC_FPATAN))
15302 (clobber (match_scratch:DF 3 ""))])]
15303 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15304 && flag_unsafe_math_optimizations"
15305 {
15306 operands[2] = gen_reg_rtx (DFmode);
15307 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15308 })
15309
15310 (define_expand "atanxf2"
15311 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15312 (unspec:XF [(match_dup 2)
15313 (match_operand:XF 1 "register_operand" "")]
15314 UNSPEC_FPATAN))
15315 (clobber (match_scratch:XF 3 ""))])]
15316 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15317 && flag_unsafe_math_optimizations"
15318 {
15319 operands[2] = gen_reg_rtx (XFmode);
15320 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15321 })
15322 \f
15323 ;; Block operation instructions
15324
15325 (define_insn "cld"
15326 [(set (reg:SI 19) (const_int 0))]
15327 ""
15328 "cld"
15329 [(set_attr "type" "cld")])
15330
15331 (define_expand "movstrsi"
15332 [(use (match_operand:BLK 0 "memory_operand" ""))
15333 (use (match_operand:BLK 1 "memory_operand" ""))
15334 (use (match_operand:SI 2 "nonmemory_operand" ""))
15335 (use (match_operand:SI 3 "const_int_operand" ""))]
15336 "! optimize_size"
15337 {
15338 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15339 DONE;
15340 else
15341 FAIL;
15342 })
15343
15344 (define_expand "movstrdi"
15345 [(use (match_operand:BLK 0 "memory_operand" ""))
15346 (use (match_operand:BLK 1 "memory_operand" ""))
15347 (use (match_operand:DI 2 "nonmemory_operand" ""))
15348 (use (match_operand:DI 3 "const_int_operand" ""))]
15349 "TARGET_64BIT"
15350 {
15351 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15352 DONE;
15353 else
15354 FAIL;
15355 })
15356
15357 ;; Most CPUs don't like single string operations
15358 ;; Handle this case here to simplify previous expander.
15359
15360 (define_expand "strmov"
15361 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15362 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15363 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15364 (clobber (reg:CC 17))])
15365 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15366 (clobber (reg:CC 17))])]
15367 ""
15368 {
15369 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15370
15371 /* If .md ever supports :P for Pmode, these can be directly
15372 in the pattern above. */
15373 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15374 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15375
15376 if (TARGET_SINGLE_STRINGOP || optimize_size)
15377 {
15378 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15379 operands[2], operands[3],
15380 operands[5], operands[6]));
15381 DONE;
15382 }
15383
15384 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15385 })
15386
15387 (define_expand "strmov_singleop"
15388 [(parallel [(set (match_operand 1 "memory_operand" "")
15389 (match_operand 3 "memory_operand" ""))
15390 (set (match_operand 0 "register_operand" "")
15391 (match_operand 4 "" ""))
15392 (set (match_operand 2 "register_operand" "")
15393 (match_operand 5 "" ""))
15394 (use (reg:SI 19))])]
15395 "TARGET_SINGLE_STRINGOP || optimize_size"
15396 "")
15397
15398 (define_insn "*strmovdi_rex_1"
15399 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15400 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15401 (set (match_operand:DI 0 "register_operand" "=D")
15402 (plus:DI (match_dup 2)
15403 (const_int 8)))
15404 (set (match_operand:DI 1 "register_operand" "=S")
15405 (plus:DI (match_dup 3)
15406 (const_int 8)))
15407 (use (reg:SI 19))]
15408 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15409 "movsq"
15410 [(set_attr "type" "str")
15411 (set_attr "mode" "DI")
15412 (set_attr "memory" "both")])
15413
15414 (define_insn "*strmovsi_1"
15415 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15416 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15417 (set (match_operand:SI 0 "register_operand" "=D")
15418 (plus:SI (match_dup 2)
15419 (const_int 4)))
15420 (set (match_operand:SI 1 "register_operand" "=S")
15421 (plus:SI (match_dup 3)
15422 (const_int 4)))
15423 (use (reg:SI 19))]
15424 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15425 "{movsl|movsd}"
15426 [(set_attr "type" "str")
15427 (set_attr "mode" "SI")
15428 (set_attr "memory" "both")])
15429
15430 (define_insn "*strmovsi_rex_1"
15431 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15432 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15433 (set (match_operand:DI 0 "register_operand" "=D")
15434 (plus:DI (match_dup 2)
15435 (const_int 4)))
15436 (set (match_operand:DI 1 "register_operand" "=S")
15437 (plus:DI (match_dup 3)
15438 (const_int 4)))
15439 (use (reg:SI 19))]
15440 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15441 "{movsl|movsd}"
15442 [(set_attr "type" "str")
15443 (set_attr "mode" "SI")
15444 (set_attr "memory" "both")])
15445
15446 (define_insn "*strmovhi_1"
15447 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15448 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15449 (set (match_operand:SI 0 "register_operand" "=D")
15450 (plus:SI (match_dup 2)
15451 (const_int 2)))
15452 (set (match_operand:SI 1 "register_operand" "=S")
15453 (plus:SI (match_dup 3)
15454 (const_int 2)))
15455 (use (reg:SI 19))]
15456 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15457 "movsw"
15458 [(set_attr "type" "str")
15459 (set_attr "memory" "both")
15460 (set_attr "mode" "HI")])
15461
15462 (define_insn "*strmovhi_rex_1"
15463 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15464 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15465 (set (match_operand:DI 0 "register_operand" "=D")
15466 (plus:DI (match_dup 2)
15467 (const_int 2)))
15468 (set (match_operand:DI 1 "register_operand" "=S")
15469 (plus:DI (match_dup 3)
15470 (const_int 2)))
15471 (use (reg:SI 19))]
15472 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15473 "movsw"
15474 [(set_attr "type" "str")
15475 (set_attr "memory" "both")
15476 (set_attr "mode" "HI")])
15477
15478 (define_insn "*strmovqi_1"
15479 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15480 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15481 (set (match_operand:SI 0 "register_operand" "=D")
15482 (plus:SI (match_dup 2)
15483 (const_int 1)))
15484 (set (match_operand:SI 1 "register_operand" "=S")
15485 (plus:SI (match_dup 3)
15486 (const_int 1)))
15487 (use (reg:SI 19))]
15488 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15489 "movsb"
15490 [(set_attr "type" "str")
15491 (set_attr "memory" "both")
15492 (set_attr "mode" "QI")])
15493
15494 (define_insn "*strmovqi_rex_1"
15495 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15496 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15497 (set (match_operand:DI 0 "register_operand" "=D")
15498 (plus:DI (match_dup 2)
15499 (const_int 1)))
15500 (set (match_operand:DI 1 "register_operand" "=S")
15501 (plus:DI (match_dup 3)
15502 (const_int 1)))
15503 (use (reg:SI 19))]
15504 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15505 "movsb"
15506 [(set_attr "type" "str")
15507 (set_attr "memory" "both")
15508 (set_attr "mode" "QI")])
15509
15510 (define_expand "rep_mov"
15511 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15512 (set (match_operand 0 "register_operand" "")
15513 (match_operand 5 "" ""))
15514 (set (match_operand 2 "register_operand" "")
15515 (match_operand 6 "" ""))
15516 (set (match_operand 1 "memory_operand" "")
15517 (match_operand 3 "memory_operand" ""))
15518 (use (match_dup 4))
15519 (use (reg:SI 19))])]
15520 ""
15521 "")
15522
15523 (define_insn "*rep_movdi_rex64"
15524 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15525 (set (match_operand:DI 0 "register_operand" "=D")
15526 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15527 (const_int 3))
15528 (match_operand:DI 3 "register_operand" "0")))
15529 (set (match_operand:DI 1 "register_operand" "=S")
15530 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15531 (match_operand:DI 4 "register_operand" "1")))
15532 (set (mem:BLK (match_dup 3))
15533 (mem:BLK (match_dup 4)))
15534 (use (match_dup 5))
15535 (use (reg:SI 19))]
15536 "TARGET_64BIT"
15537 "{rep\;movsq|rep movsq}"
15538 [(set_attr "type" "str")
15539 (set_attr "prefix_rep" "1")
15540 (set_attr "memory" "both")
15541 (set_attr "mode" "DI")])
15542
15543 (define_insn "*rep_movsi"
15544 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15545 (set (match_operand:SI 0 "register_operand" "=D")
15546 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15547 (const_int 2))
15548 (match_operand:SI 3 "register_operand" "0")))
15549 (set (match_operand:SI 1 "register_operand" "=S")
15550 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15551 (match_operand:SI 4 "register_operand" "1")))
15552 (set (mem:BLK (match_dup 3))
15553 (mem:BLK (match_dup 4)))
15554 (use (match_dup 5))
15555 (use (reg:SI 19))]
15556 "!TARGET_64BIT"
15557 "{rep\;movsl|rep movsd}"
15558 [(set_attr "type" "str")
15559 (set_attr "prefix_rep" "1")
15560 (set_attr "memory" "both")
15561 (set_attr "mode" "SI")])
15562
15563 (define_insn "*rep_movsi_rex64"
15564 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15565 (set (match_operand:DI 0 "register_operand" "=D")
15566 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15567 (const_int 2))
15568 (match_operand:DI 3 "register_operand" "0")))
15569 (set (match_operand:DI 1 "register_operand" "=S")
15570 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15571 (match_operand:DI 4 "register_operand" "1")))
15572 (set (mem:BLK (match_dup 3))
15573 (mem:BLK (match_dup 4)))
15574 (use (match_dup 5))
15575 (use (reg:SI 19))]
15576 "TARGET_64BIT"
15577 "{rep\;movsl|rep movsd}"
15578 [(set_attr "type" "str")
15579 (set_attr "prefix_rep" "1")
15580 (set_attr "memory" "both")
15581 (set_attr "mode" "SI")])
15582
15583 (define_insn "*rep_movqi"
15584 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15585 (set (match_operand:SI 0 "register_operand" "=D")
15586 (plus:SI (match_operand:SI 3 "register_operand" "0")
15587 (match_operand:SI 5 "register_operand" "2")))
15588 (set (match_operand:SI 1 "register_operand" "=S")
15589 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15590 (set (mem:BLK (match_dup 3))
15591 (mem:BLK (match_dup 4)))
15592 (use (match_dup 5))
15593 (use (reg:SI 19))]
15594 "!TARGET_64BIT"
15595 "{rep\;movsb|rep movsb}"
15596 [(set_attr "type" "str")
15597 (set_attr "prefix_rep" "1")
15598 (set_attr "memory" "both")
15599 (set_attr "mode" "SI")])
15600
15601 (define_insn "*rep_movqi_rex64"
15602 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15603 (set (match_operand:DI 0 "register_operand" "=D")
15604 (plus:DI (match_operand:DI 3 "register_operand" "0")
15605 (match_operand:DI 5 "register_operand" "2")))
15606 (set (match_operand:DI 1 "register_operand" "=S")
15607 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15608 (set (mem:BLK (match_dup 3))
15609 (mem:BLK (match_dup 4)))
15610 (use (match_dup 5))
15611 (use (reg:SI 19))]
15612 "TARGET_64BIT"
15613 "{rep\;movsb|rep movsb}"
15614 [(set_attr "type" "str")
15615 (set_attr "prefix_rep" "1")
15616 (set_attr "memory" "both")
15617 (set_attr "mode" "SI")])
15618
15619 (define_expand "clrstrsi"
15620 [(use (match_operand:BLK 0 "memory_operand" ""))
15621 (use (match_operand:SI 1 "nonmemory_operand" ""))
15622 (use (match_operand 2 "const_int_operand" ""))]
15623 ""
15624 {
15625 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15626 DONE;
15627 else
15628 FAIL;
15629 })
15630
15631 (define_expand "clrstrdi"
15632 [(use (match_operand:BLK 0 "memory_operand" ""))
15633 (use (match_operand:DI 1 "nonmemory_operand" ""))
15634 (use (match_operand 2 "const_int_operand" ""))]
15635 "TARGET_64BIT"
15636 {
15637 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
15638 DONE;
15639 else
15640 FAIL;
15641 })
15642
15643 ;; Most CPUs don't like single string operations
15644 ;; Handle this case here to simplify previous expander.
15645
15646 (define_expand "strset"
15647 [(set (match_operand 1 "memory_operand" "")
15648 (match_operand 2 "register_operand" ""))
15649 (parallel [(set (match_operand 0 "register_operand" "")
15650 (match_dup 3))
15651 (clobber (reg:CC 17))])]
15652 ""
15653 {
15654 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15655 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15656
15657 /* If .md ever supports :P for Pmode, this can be directly
15658 in the pattern above. */
15659 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15660 GEN_INT (GET_MODE_SIZE (GET_MODE
15661 (operands[2]))));
15662 if (TARGET_SINGLE_STRINGOP || optimize_size)
15663 {
15664 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15665 operands[3]));
15666 DONE;
15667 }
15668 })
15669
15670 (define_expand "strset_singleop"
15671 [(parallel [(set (match_operand 1 "memory_operand" "")
15672 (match_operand 2 "register_operand" ""))
15673 (set (match_operand 0 "register_operand" "")
15674 (match_operand 3 "" ""))
15675 (use (reg:SI 19))])]
15676 "TARGET_SINGLE_STRINGOP || optimize_size"
15677 "")
15678
15679 (define_insn "*strsetdi_rex_1"
15680 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15681 (match_operand:SI 2 "register_operand" "a"))
15682 (set (match_operand:DI 0 "register_operand" "=D")
15683 (plus:DI (match_dup 1)
15684 (const_int 8)))
15685 (use (reg:SI 19))]
15686 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15687 "stosq"
15688 [(set_attr "type" "str")
15689 (set_attr "memory" "store")
15690 (set_attr "mode" "DI")])
15691
15692 (define_insn "*strsetsi_1"
15693 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15694 (match_operand:SI 2 "register_operand" "a"))
15695 (set (match_operand:SI 0 "register_operand" "=D")
15696 (plus:SI (match_dup 1)
15697 (const_int 4)))
15698 (use (reg:SI 19))]
15699 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15700 "{stosl|stosd}"
15701 [(set_attr "type" "str")
15702 (set_attr "memory" "store")
15703 (set_attr "mode" "SI")])
15704
15705 (define_insn "*strsetsi_rex_1"
15706 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15707 (match_operand:SI 2 "register_operand" "a"))
15708 (set (match_operand:DI 0 "register_operand" "=D")
15709 (plus:DI (match_dup 1)
15710 (const_int 4)))
15711 (use (reg:SI 19))]
15712 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15713 "{stosl|stosd}"
15714 [(set_attr "type" "str")
15715 (set_attr "memory" "store")
15716 (set_attr "mode" "SI")])
15717
15718 (define_insn "*strsethi_1"
15719 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15720 (match_operand:HI 2 "register_operand" "a"))
15721 (set (match_operand:SI 0 "register_operand" "=D")
15722 (plus:SI (match_dup 1)
15723 (const_int 2)))
15724 (use (reg:SI 19))]
15725 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15726 "stosw"
15727 [(set_attr "type" "str")
15728 (set_attr "memory" "store")
15729 (set_attr "mode" "HI")])
15730
15731 (define_insn "*strsethi_rex_1"
15732 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15733 (match_operand:HI 2 "register_operand" "a"))
15734 (set (match_operand:DI 0 "register_operand" "=D")
15735 (plus:DI (match_dup 1)
15736 (const_int 2)))
15737 (use (reg:SI 19))]
15738 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15739 "stosw"
15740 [(set_attr "type" "str")
15741 (set_attr "memory" "store")
15742 (set_attr "mode" "HI")])
15743
15744 (define_insn "*strsetqi_1"
15745 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15746 (match_operand:QI 2 "register_operand" "a"))
15747 (set (match_operand:SI 0 "register_operand" "=D")
15748 (plus:SI (match_dup 1)
15749 (const_int 1)))
15750 (use (reg:SI 19))]
15751 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15752 "stosb"
15753 [(set_attr "type" "str")
15754 (set_attr "memory" "store")
15755 (set_attr "mode" "QI")])
15756
15757 (define_insn "*strsetqi_rex_1"
15758 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15759 (match_operand:QI 2 "register_operand" "a"))
15760 (set (match_operand:DI 0 "register_operand" "=D")
15761 (plus:DI (match_dup 1)
15762 (const_int 1)))
15763 (use (reg:SI 19))]
15764 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15765 "stosb"
15766 [(set_attr "type" "str")
15767 (set_attr "memory" "store")
15768 (set_attr "mode" "QI")])
15769
15770 (define_expand "rep_stos"
15771 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15772 (set (match_operand 0 "register_operand" "")
15773 (match_operand 4 "" ""))
15774 (set (match_operand 2 "memory_operand" "") (const_int 0))
15775 (use (match_operand 3 "register_operand" ""))
15776 (use (match_dup 1))
15777 (use (reg:SI 19))])]
15778 ""
15779 "")
15780
15781 (define_insn "*rep_stosdi_rex64"
15782 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15783 (set (match_operand:DI 0 "register_operand" "=D")
15784 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15785 (const_int 3))
15786 (match_operand:DI 3 "register_operand" "0")))
15787 (set (mem:BLK (match_dup 3))
15788 (const_int 0))
15789 (use (match_operand:DI 2 "register_operand" "a"))
15790 (use (match_dup 4))
15791 (use (reg:SI 19))]
15792 "TARGET_64BIT"
15793 "{rep\;stosq|rep stosq}"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "store")
15797 (set_attr "mode" "DI")])
15798
15799 (define_insn "*rep_stossi"
15800 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:SI 0 "register_operand" "=D")
15802 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15803 (const_int 2))
15804 (match_operand:SI 3 "register_operand" "0")))
15805 (set (mem:BLK (match_dup 3))
15806 (const_int 0))
15807 (use (match_operand:SI 2 "register_operand" "a"))
15808 (use (match_dup 4))
15809 (use (reg:SI 19))]
15810 "!TARGET_64BIT"
15811 "{rep\;stosl|rep stosd}"
15812 [(set_attr "type" "str")
15813 (set_attr "prefix_rep" "1")
15814 (set_attr "memory" "store")
15815 (set_attr "mode" "SI")])
15816
15817 (define_insn "*rep_stossi_rex64"
15818 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15819 (set (match_operand:DI 0 "register_operand" "=D")
15820 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15821 (const_int 2))
15822 (match_operand:DI 3 "register_operand" "0")))
15823 (set (mem:BLK (match_dup 3))
15824 (const_int 0))
15825 (use (match_operand:SI 2 "register_operand" "a"))
15826 (use (match_dup 4))
15827 (use (reg:SI 19))]
15828 "TARGET_64BIT"
15829 "{rep\;stosl|rep stosd}"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "store")
15833 (set_attr "mode" "SI")])
15834
15835 (define_insn "*rep_stosqi"
15836 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15837 (set (match_operand:SI 0 "register_operand" "=D")
15838 (plus:SI (match_operand:SI 3 "register_operand" "0")
15839 (match_operand:SI 4 "register_operand" "1")))
15840 (set (mem:BLK (match_dup 3))
15841 (const_int 0))
15842 (use (match_operand:QI 2 "register_operand" "a"))
15843 (use (match_dup 4))
15844 (use (reg:SI 19))]
15845 "!TARGET_64BIT"
15846 "{rep\;stosb|rep stosb}"
15847 [(set_attr "type" "str")
15848 (set_attr "prefix_rep" "1")
15849 (set_attr "memory" "store")
15850 (set_attr "mode" "QI")])
15851
15852 (define_insn "*rep_stosqi_rex64"
15853 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15854 (set (match_operand:DI 0 "register_operand" "=D")
15855 (plus:DI (match_operand:DI 3 "register_operand" "0")
15856 (match_operand:DI 4 "register_operand" "1")))
15857 (set (mem:BLK (match_dup 3))
15858 (const_int 0))
15859 (use (match_operand:QI 2 "register_operand" "a"))
15860 (use (match_dup 4))
15861 (use (reg:SI 19))]
15862 "TARGET_64BIT"
15863 "{rep\;stosb|rep stosb}"
15864 [(set_attr "type" "str")
15865 (set_attr "prefix_rep" "1")
15866 (set_attr "memory" "store")
15867 (set_attr "mode" "QI")])
15868
15869 (define_expand "cmpstrsi"
15870 [(set (match_operand:SI 0 "register_operand" "")
15871 (compare:SI (match_operand:BLK 1 "general_operand" "")
15872 (match_operand:BLK 2 "general_operand" "")))
15873 (use (match_operand 3 "general_operand" ""))
15874 (use (match_operand 4 "immediate_operand" ""))]
15875 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
15876 {
15877 rtx addr1, addr2, out, outlow, count, countreg, align;
15878
15879 /* Can't use this if the user has appropriated esi or edi. */
15880 if (global_regs[4] || global_regs[5])
15881 FAIL;
15882
15883 out = operands[0];
15884 if (GET_CODE (out) != REG)
15885 out = gen_reg_rtx (SImode);
15886
15887 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15888 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15889 if (addr1 != XEXP (operands[1], 0))
15890 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15891 if (addr2 != XEXP (operands[2], 0))
15892 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15893
15894 count = operands[3];
15895 countreg = ix86_zero_extend_to_Pmode (count);
15896
15897 /* %%% Iff we are testing strict equality, we can use known alignment
15898 to good advantage. This may be possible with combine, particularly
15899 once cc0 is dead. */
15900 align = operands[4];
15901
15902 emit_insn (gen_cld ());
15903 if (GET_CODE (count) == CONST_INT)
15904 {
15905 if (INTVAL (count) == 0)
15906 {
15907 emit_move_insn (operands[0], const0_rtx);
15908 DONE;
15909 }
15910 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
15911 operands[1], operands[2]));
15912 }
15913 else
15914 {
15915 if (TARGET_64BIT)
15916 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
15917 else
15918 emit_insn (gen_cmpsi_1 (countreg, countreg));
15919 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
15920 operands[1], operands[2]));
15921 }
15922
15923 outlow = gen_lowpart (QImode, out);
15924 emit_insn (gen_cmpintqi (outlow));
15925 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15926
15927 if (operands[0] != out)
15928 emit_move_insn (operands[0], out);
15929
15930 DONE;
15931 })
15932
15933 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15934
15935 (define_expand "cmpintqi"
15936 [(set (match_dup 1)
15937 (gtu:QI (reg:CC 17) (const_int 0)))
15938 (set (match_dup 2)
15939 (ltu:QI (reg:CC 17) (const_int 0)))
15940 (parallel [(set (match_operand:QI 0 "register_operand" "")
15941 (minus:QI (match_dup 1)
15942 (match_dup 2)))
15943 (clobber (reg:CC 17))])]
15944 ""
15945 "operands[1] = gen_reg_rtx (QImode);
15946 operands[2] = gen_reg_rtx (QImode);")
15947
15948 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15949 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15950
15951 (define_expand "cmpstrqi_nz_1"
15952 [(parallel [(set (reg:CC 17)
15953 (compare:CC (match_operand 4 "memory_operand" "")
15954 (match_operand 5 "memory_operand" "")))
15955 (use (match_operand 2 "register_operand" ""))
15956 (use (match_operand:SI 3 "immediate_operand" ""))
15957 (use (reg:SI 19))
15958 (clobber (match_operand 0 "register_operand" ""))
15959 (clobber (match_operand 1 "register_operand" ""))
15960 (clobber (match_dup 2))])]
15961 ""
15962 "")
15963
15964 (define_insn "*cmpstrqi_nz_1"
15965 [(set (reg:CC 17)
15966 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15967 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15968 (use (match_operand:SI 6 "register_operand" "2"))
15969 (use (match_operand:SI 3 "immediate_operand" "i"))
15970 (use (reg:SI 19))
15971 (clobber (match_operand:SI 0 "register_operand" "=S"))
15972 (clobber (match_operand:SI 1 "register_operand" "=D"))
15973 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15974 "!TARGET_64BIT"
15975 "repz{\;| }cmpsb"
15976 [(set_attr "type" "str")
15977 (set_attr "mode" "QI")
15978 (set_attr "prefix_rep" "1")])
15979
15980 (define_insn "*cmpstrqi_nz_rex_1"
15981 [(set (reg:CC 17)
15982 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15983 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15984 (use (match_operand:DI 6 "register_operand" "2"))
15985 (use (match_operand:SI 3 "immediate_operand" "i"))
15986 (use (reg:SI 19))
15987 (clobber (match_operand:DI 0 "register_operand" "=S"))
15988 (clobber (match_operand:DI 1 "register_operand" "=D"))
15989 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15990 "TARGET_64BIT"
15991 "repz{\;| }cmpsb"
15992 [(set_attr "type" "str")
15993 (set_attr "mode" "QI")
15994 (set_attr "prefix_rep" "1")])
15995
15996 ;; The same, but the count is not known to not be zero.
15997
15998 (define_expand "cmpstrqi_1"
15999 [(parallel [(set (reg:CC 17)
16000 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16001 (const_int 0))
16002 (compare:CC (match_operand 4 "memory_operand" "")
16003 (match_operand 5 "memory_operand" ""))
16004 (const_int 0)))
16005 (use (match_operand:SI 3 "immediate_operand" ""))
16006 (use (reg:CC 17))
16007 (use (reg:SI 19))
16008 (clobber (match_operand 0 "register_operand" ""))
16009 (clobber (match_operand 1 "register_operand" ""))
16010 (clobber (match_dup 2))])]
16011 ""
16012 "")
16013
16014 (define_insn "*cmpstrqi_1"
16015 [(set (reg:CC 17)
16016 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16017 (const_int 0))
16018 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16019 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16020 (const_int 0)))
16021 (use (match_operand:SI 3 "immediate_operand" "i"))
16022 (use (reg:CC 17))
16023 (use (reg:SI 19))
16024 (clobber (match_operand:SI 0 "register_operand" "=S"))
16025 (clobber (match_operand:SI 1 "register_operand" "=D"))
16026 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16027 "!TARGET_64BIT"
16028 "repz{\;| }cmpsb"
16029 [(set_attr "type" "str")
16030 (set_attr "mode" "QI")
16031 (set_attr "prefix_rep" "1")])
16032
16033 (define_insn "*cmpstrqi_rex_1"
16034 [(set (reg:CC 17)
16035 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16036 (const_int 0))
16037 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16038 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16039 (const_int 0)))
16040 (use (match_operand:SI 3 "immediate_operand" "i"))
16041 (use (reg:CC 17))
16042 (use (reg:SI 19))
16043 (clobber (match_operand:DI 0 "register_operand" "=S"))
16044 (clobber (match_operand:DI 1 "register_operand" "=D"))
16045 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16046 "TARGET_64BIT"
16047 "repz{\;| }cmpsb"
16048 [(set_attr "type" "str")
16049 (set_attr "mode" "QI")
16050 (set_attr "prefix_rep" "1")])
16051
16052 (define_expand "strlensi"
16053 [(set (match_operand:SI 0 "register_operand" "")
16054 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16055 (match_operand:QI 2 "immediate_operand" "")
16056 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16057 ""
16058 {
16059 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16060 DONE;
16061 else
16062 FAIL;
16063 })
16064
16065 (define_expand "strlendi"
16066 [(set (match_operand:DI 0 "register_operand" "")
16067 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16068 (match_operand:QI 2 "immediate_operand" "")
16069 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16070 ""
16071 {
16072 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16073 DONE;
16074 else
16075 FAIL;
16076 })
16077
16078 (define_expand "strlenqi_1"
16079 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16080 (use (reg:SI 19))
16081 (clobber (match_operand 1 "register_operand" ""))
16082 (clobber (reg:CC 17))])]
16083 ""
16084 "")
16085
16086 (define_insn "*strlenqi_1"
16087 [(set (match_operand:SI 0 "register_operand" "=&c")
16088 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16089 (match_operand:QI 2 "register_operand" "a")
16090 (match_operand:SI 3 "immediate_operand" "i")
16091 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16092 (use (reg:SI 19))
16093 (clobber (match_operand:SI 1 "register_operand" "=D"))
16094 (clobber (reg:CC 17))]
16095 "!TARGET_64BIT"
16096 "repnz{\;| }scasb"
16097 [(set_attr "type" "str")
16098 (set_attr "mode" "QI")
16099 (set_attr "prefix_rep" "1")])
16100
16101 (define_insn "*strlenqi_rex_1"
16102 [(set (match_operand:DI 0 "register_operand" "=&c")
16103 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16104 (match_operand:QI 2 "register_operand" "a")
16105 (match_operand:DI 3 "immediate_operand" "i")
16106 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16107 (use (reg:SI 19))
16108 (clobber (match_operand:DI 1 "register_operand" "=D"))
16109 (clobber (reg:CC 17))]
16110 "TARGET_64BIT"
16111 "repnz{\;| }scasb"
16112 [(set_attr "type" "str")
16113 (set_attr "mode" "QI")
16114 (set_attr "prefix_rep" "1")])
16115
16116 ;; Peephole optimizations to clean up after cmpstr*. This should be
16117 ;; handled in combine, but it is not currently up to the task.
16118 ;; When used for their truth value, the cmpstr* expanders generate
16119 ;; code like this:
16120 ;;
16121 ;; repz cmpsb
16122 ;; seta %al
16123 ;; setb %dl
16124 ;; cmpb %al, %dl
16125 ;; jcc label
16126 ;;
16127 ;; The intermediate three instructions are unnecessary.
16128
16129 ;; This one handles cmpstr*_nz_1...
16130 (define_peephole2
16131 [(parallel[
16132 (set (reg:CC 17)
16133 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16134 (mem:BLK (match_operand 5 "register_operand" ""))))
16135 (use (match_operand 6 "register_operand" ""))
16136 (use (match_operand:SI 3 "immediate_operand" ""))
16137 (use (reg:SI 19))
16138 (clobber (match_operand 0 "register_operand" ""))
16139 (clobber (match_operand 1 "register_operand" ""))
16140 (clobber (match_operand 2 "register_operand" ""))])
16141 (set (match_operand:QI 7 "register_operand" "")
16142 (gtu:QI (reg:CC 17) (const_int 0)))
16143 (set (match_operand:QI 8 "register_operand" "")
16144 (ltu:QI (reg:CC 17) (const_int 0)))
16145 (set (reg 17)
16146 (compare (match_dup 7) (match_dup 8)))
16147 ]
16148 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16149 [(parallel[
16150 (set (reg:CC 17)
16151 (compare:CC (mem:BLK (match_dup 4))
16152 (mem:BLK (match_dup 5))))
16153 (use (match_dup 6))
16154 (use (match_dup 3))
16155 (use (reg:SI 19))
16156 (clobber (match_dup 0))
16157 (clobber (match_dup 1))
16158 (clobber (match_dup 2))])]
16159 "")
16160
16161 ;; ...and this one handles cmpstr*_1.
16162 (define_peephole2
16163 [(parallel[
16164 (set (reg:CC 17)
16165 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16166 (const_int 0))
16167 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16168 (mem:BLK (match_operand 5 "register_operand" "")))
16169 (const_int 0)))
16170 (use (match_operand:SI 3 "immediate_operand" ""))
16171 (use (reg:CC 17))
16172 (use (reg:SI 19))
16173 (clobber (match_operand 0 "register_operand" ""))
16174 (clobber (match_operand 1 "register_operand" ""))
16175 (clobber (match_operand 2 "register_operand" ""))])
16176 (set (match_operand:QI 7 "register_operand" "")
16177 (gtu:QI (reg:CC 17) (const_int 0)))
16178 (set (match_operand:QI 8 "register_operand" "")
16179 (ltu:QI (reg:CC 17) (const_int 0)))
16180 (set (reg 17)
16181 (compare (match_dup 7) (match_dup 8)))
16182 ]
16183 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16184 [(parallel[
16185 (set (reg:CC 17)
16186 (if_then_else:CC (ne (match_dup 6)
16187 (const_int 0))
16188 (compare:CC (mem:BLK (match_dup 4))
16189 (mem:BLK (match_dup 5)))
16190 (const_int 0)))
16191 (use (match_dup 3))
16192 (use (reg:CC 17))
16193 (use (reg:SI 19))
16194 (clobber (match_dup 0))
16195 (clobber (match_dup 1))
16196 (clobber (match_dup 2))])]
16197 "")
16198
16199
16200 \f
16201 ;; Conditional move instructions.
16202
16203 (define_expand "movdicc"
16204 [(set (match_operand:DI 0 "register_operand" "")
16205 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16206 (match_operand:DI 2 "general_operand" "")
16207 (match_operand:DI 3 "general_operand" "")))]
16208 "TARGET_64BIT"
16209 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16210
16211 (define_insn "x86_movdicc_0_m1_rex64"
16212 [(set (match_operand:DI 0 "register_operand" "=r")
16213 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16214 (const_int -1)
16215 (const_int 0)))
16216 (clobber (reg:CC 17))]
16217 "TARGET_64BIT"
16218 "sbb{q}\t%0, %0"
16219 ; Since we don't have the proper number of operands for an alu insn,
16220 ; fill in all the blanks.
16221 [(set_attr "type" "alu")
16222 (set_attr "pent_pair" "pu")
16223 (set_attr "memory" "none")
16224 (set_attr "imm_disp" "false")
16225 (set_attr "mode" "DI")
16226 (set_attr "length_immediate" "0")])
16227
16228 (define_insn "movdicc_c_rex64"
16229 [(set (match_operand:DI 0 "register_operand" "=r,r")
16230 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16231 [(reg 17) (const_int 0)])
16232 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16233 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16234 "TARGET_64BIT && TARGET_CMOVE
16235 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16236 "@
16237 cmov%O2%C1\t{%2, %0|%0, %2}
16238 cmov%O2%c1\t{%3, %0|%0, %3}"
16239 [(set_attr "type" "icmov")
16240 (set_attr "mode" "DI")])
16241
16242 (define_expand "movsicc"
16243 [(set (match_operand:SI 0 "register_operand" "")
16244 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16245 (match_operand:SI 2 "general_operand" "")
16246 (match_operand:SI 3 "general_operand" "")))]
16247 ""
16248 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16249
16250 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16251 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16252 ;; So just document what we're doing explicitly.
16253
16254 (define_insn "x86_movsicc_0_m1"
16255 [(set (match_operand:SI 0 "register_operand" "=r")
16256 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16257 (const_int -1)
16258 (const_int 0)))
16259 (clobber (reg:CC 17))]
16260 ""
16261 "sbb{l}\t%0, %0"
16262 ; Since we don't have the proper number of operands for an alu insn,
16263 ; fill in all the blanks.
16264 [(set_attr "type" "alu")
16265 (set_attr "pent_pair" "pu")
16266 (set_attr "memory" "none")
16267 (set_attr "imm_disp" "false")
16268 (set_attr "mode" "SI")
16269 (set_attr "length_immediate" "0")])
16270
16271 (define_insn "*movsicc_noc"
16272 [(set (match_operand:SI 0 "register_operand" "=r,r")
16273 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
16274 [(reg 17) (const_int 0)])
16275 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16276 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16277 "TARGET_CMOVE
16278 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16279 "@
16280 cmov%O2%C1\t{%2, %0|%0, %2}
16281 cmov%O2%c1\t{%3, %0|%0, %3}"
16282 [(set_attr "type" "icmov")
16283 (set_attr "mode" "SI")])
16284
16285 (define_expand "movhicc"
16286 [(set (match_operand:HI 0 "register_operand" "")
16287 (if_then_else:HI (match_operand 1 "comparison_operator" "")
16288 (match_operand:HI 2 "general_operand" "")
16289 (match_operand:HI 3 "general_operand" "")))]
16290 "TARGET_HIMODE_MATH"
16291 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16292
16293 (define_insn "*movhicc_noc"
16294 [(set (match_operand:HI 0 "register_operand" "=r,r")
16295 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
16296 [(reg 17) (const_int 0)])
16297 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16298 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16299 "TARGET_CMOVE
16300 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16301 "@
16302 cmov%O2%C1\t{%2, %0|%0, %2}
16303 cmov%O2%c1\t{%3, %0|%0, %3}"
16304 [(set_attr "type" "icmov")
16305 (set_attr "mode" "HI")])
16306
16307 (define_expand "movqicc"
16308 [(set (match_operand:QI 0 "register_operand" "")
16309 (if_then_else:QI (match_operand 1 "comparison_operator" "")
16310 (match_operand:QI 2 "general_operand" "")
16311 (match_operand:QI 3 "general_operand" "")))]
16312 "TARGET_QIMODE_MATH"
16313 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16314
16315 (define_insn_and_split "*movqicc_noc"
16316 [(set (match_operand:QI 0 "register_operand" "=r,r")
16317 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16318 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16319 (match_operand:QI 2 "register_operand" "r,0")
16320 (match_operand:QI 3 "register_operand" "0,r")))]
16321 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16322 "#"
16323 "&& reload_completed"
16324 [(set (match_dup 0)
16325 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16326 (match_dup 2)
16327 (match_dup 3)))]
16328 "operands[0] = gen_lowpart (SImode, operands[0]);
16329 operands[2] = gen_lowpart (SImode, operands[2]);
16330 operands[3] = gen_lowpart (SImode, operands[3]);"
16331 [(set_attr "type" "icmov")
16332 (set_attr "mode" "SI")])
16333
16334 (define_expand "movsfcc"
16335 [(set (match_operand:SF 0 "register_operand" "")
16336 (if_then_else:SF (match_operand 1 "comparison_operator" "")
16337 (match_operand:SF 2 "register_operand" "")
16338 (match_operand:SF 3 "register_operand" "")))]
16339 "TARGET_CMOVE"
16340 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16341
16342 (define_insn "*movsfcc_1"
16343 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16344 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16345 [(reg 17) (const_int 0)])
16346 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16347 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16348 "TARGET_CMOVE
16349 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16350 "@
16351 fcmov%F1\t{%2, %0|%0, %2}
16352 fcmov%f1\t{%3, %0|%0, %3}
16353 cmov%O2%C1\t{%2, %0|%0, %2}
16354 cmov%O2%c1\t{%3, %0|%0, %3}"
16355 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16356 (set_attr "mode" "SF,SF,SI,SI")])
16357
16358 (define_expand "movdfcc"
16359 [(set (match_operand:DF 0 "register_operand" "")
16360 (if_then_else:DF (match_operand 1 "comparison_operator" "")
16361 (match_operand:DF 2 "register_operand" "")
16362 (match_operand:DF 3 "register_operand" "")))]
16363 "TARGET_CMOVE"
16364 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16365
16366 (define_insn "*movdfcc_1"
16367 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16368 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16369 [(reg 17) (const_int 0)])
16370 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16371 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16372 "!TARGET_64BIT && TARGET_CMOVE
16373 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16374 "@
16375 fcmov%F1\t{%2, %0|%0, %2}
16376 fcmov%f1\t{%3, %0|%0, %3}
16377 #
16378 #"
16379 [(set_attr "type" "fcmov,fcmov,multi,multi")
16380 (set_attr "mode" "DF")])
16381
16382 (define_insn "*movdfcc_1_rex64"
16383 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16384 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16385 [(reg 17) (const_int 0)])
16386 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16387 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16388 "TARGET_64BIT && TARGET_CMOVE
16389 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16390 "@
16391 fcmov%F1\t{%2, %0|%0, %2}
16392 fcmov%f1\t{%3, %0|%0, %3}
16393 cmov%O2%C1\t{%2, %0|%0, %2}
16394 cmov%O2%c1\t{%3, %0|%0, %3}"
16395 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16396 (set_attr "mode" "DF")])
16397
16398 (define_split
16399 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16400 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16401 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16402 (match_operand:DF 2 "nonimmediate_operand" "")
16403 (match_operand:DF 3 "nonimmediate_operand" "")))]
16404 "!TARGET_64BIT && reload_completed"
16405 [(set (match_dup 2)
16406 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16407 (match_dup 5)
16408 (match_dup 7)))
16409 (set (match_dup 3)
16410 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16411 (match_dup 6)
16412 (match_dup 8)))]
16413 "split_di (operands+2, 1, operands+5, operands+6);
16414 split_di (operands+3, 1, operands+7, operands+8);
16415 split_di (operands, 1, operands+2, operands+3);")
16416
16417 (define_expand "movxfcc"
16418 [(set (match_operand:XF 0 "register_operand" "")
16419 (if_then_else:XF (match_operand 1 "comparison_operator" "")
16420 (match_operand:XF 2 "register_operand" "")
16421 (match_operand:XF 3 "register_operand" "")))]
16422 "TARGET_CMOVE"
16423 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16424
16425 (define_insn "*movxfcc_1"
16426 [(set (match_operand:XF 0 "register_operand" "=f,f")
16427 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16428 [(reg 17) (const_int 0)])
16429 (match_operand:XF 2 "register_operand" "f,0")
16430 (match_operand:XF 3 "register_operand" "0,f")))]
16431 "TARGET_CMOVE"
16432 "@
16433 fcmov%F1\t{%2, %0|%0, %2}
16434 fcmov%f1\t{%3, %0|%0, %3}"
16435 [(set_attr "type" "fcmov")
16436 (set_attr "mode" "XF")])
16437
16438 (define_expand "minsf3"
16439 [(parallel [
16440 (set (match_operand:SF 0 "register_operand" "")
16441 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16442 (match_operand:SF 2 "nonimmediate_operand" ""))
16443 (match_dup 1)
16444 (match_dup 2)))
16445 (clobber (reg:CC 17))])]
16446 "TARGET_SSE"
16447 "")
16448
16449 (define_insn "*minsf"
16450 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16451 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
16452 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16453 (match_dup 1)
16454 (match_dup 2)))
16455 (clobber (reg:CC 17))]
16456 "TARGET_SSE && TARGET_IEEE_FP"
16457 "#")
16458
16459 (define_insn "*minsf_nonieee"
16460 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16461 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16462 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16463 (match_dup 1)
16464 (match_dup 2)))
16465 (clobber (reg:CC 17))]
16466 "TARGET_SSE && !TARGET_IEEE_FP
16467 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16468 "#")
16469
16470 (define_split
16471 [(set (match_operand:SF 0 "register_operand" "")
16472 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16473 (match_operand:SF 2 "nonimmediate_operand" ""))
16474 (match_operand:SF 3 "register_operand" "")
16475 (match_operand:SF 4 "nonimmediate_operand" "")))
16476 (clobber (reg:CC 17))]
16477 "SSE_REG_P (operands[0]) && reload_completed
16478 && ((operands_match_p (operands[1], operands[3])
16479 && operands_match_p (operands[2], operands[4]))
16480 || (operands_match_p (operands[1], operands[4])
16481 && operands_match_p (operands[2], operands[3])))"
16482 [(set (match_dup 0)
16483 (if_then_else:SF (lt (match_dup 1)
16484 (match_dup 2))
16485 (match_dup 1)
16486 (match_dup 2)))])
16487
16488 ;; Conditional addition patterns
16489 (define_expand "addqicc"
16490 [(match_operand:QI 0 "register_operand" "")
16491 (match_operand 1 "comparison_operator" "")
16492 (match_operand:QI 2 "register_operand" "")
16493 (match_operand:QI 3 "const_int_operand" "")]
16494 ""
16495 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16496
16497 (define_expand "addhicc"
16498 [(match_operand:HI 0 "register_operand" "")
16499 (match_operand 1 "comparison_operator" "")
16500 (match_operand:HI 2 "register_operand" "")
16501 (match_operand:HI 3 "const_int_operand" "")]
16502 ""
16503 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16504
16505 (define_expand "addsicc"
16506 [(match_operand:SI 0 "register_operand" "")
16507 (match_operand 1 "comparison_operator" "")
16508 (match_operand:SI 2 "register_operand" "")
16509 (match_operand:SI 3 "const_int_operand" "")]
16510 ""
16511 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16512
16513 (define_expand "adddicc"
16514 [(match_operand:DI 0 "register_operand" "")
16515 (match_operand 1 "comparison_operator" "")
16516 (match_operand:DI 2 "register_operand" "")
16517 (match_operand:DI 3 "const_int_operand" "")]
16518 "TARGET_64BIT"
16519 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
16520
16521 ;; We can't represent the LT test directly. Do this by swapping the operands.
16522
16523 (define_split
16524 [(set (match_operand:SF 0 "fp_register_operand" "")
16525 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
16526 (match_operand:SF 2 "register_operand" ""))
16527 (match_operand:SF 3 "register_operand" "")
16528 (match_operand:SF 4 "register_operand" "")))
16529 (clobber (reg:CC 17))]
16530 "reload_completed
16531 && ((operands_match_p (operands[1], operands[3])
16532 && operands_match_p (operands[2], operands[4]))
16533 || (operands_match_p (operands[1], operands[4])
16534 && operands_match_p (operands[2], operands[3])))"
16535 [(set (reg:CCFP 17)
16536 (compare:CCFP (match_dup 2)
16537 (match_dup 1)))
16538 (set (match_dup 0)
16539 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
16540 (match_dup 1)
16541 (match_dup 2)))])
16542
16543 (define_insn "*minsf_sse"
16544 [(set (match_operand:SF 0 "register_operand" "=x")
16545 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
16546 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16547 (match_dup 1)
16548 (match_dup 2)))]
16549 "TARGET_SSE && reload_completed"
16550 "minss\t{%2, %0|%0, %2}"
16551 [(set_attr "type" "sse")
16552 (set_attr "mode" "SF")])
16553
16554 (define_expand "mindf3"
16555 [(parallel [
16556 (set (match_operand:DF 0 "register_operand" "")
16557 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16558 (match_operand:DF 2 "nonimmediate_operand" ""))
16559 (match_dup 1)
16560 (match_dup 2)))
16561 (clobber (reg:CC 17))])]
16562 "TARGET_SSE2 && TARGET_SSE_MATH"
16563 "#")
16564
16565 (define_insn "*mindf"
16566 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16567 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16568 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16569 (match_dup 1)
16570 (match_dup 2)))
16571 (clobber (reg:CC 17))]
16572 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
16573 "#")
16574
16575 (define_insn "*mindf_nonieee"
16576 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16577 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16578 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16579 (match_dup 1)
16580 (match_dup 2)))
16581 (clobber (reg:CC 17))]
16582 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16583 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16584 "#")
16585
16586 (define_split
16587 [(set (match_operand:DF 0 "register_operand" "")
16588 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16589 (match_operand:DF 2 "nonimmediate_operand" ""))
16590 (match_operand:DF 3 "register_operand" "")
16591 (match_operand:DF 4 "nonimmediate_operand" "")))
16592 (clobber (reg:CC 17))]
16593 "SSE_REG_P (operands[0]) && reload_completed
16594 && ((operands_match_p (operands[1], operands[3])
16595 && operands_match_p (operands[2], operands[4]))
16596 || (operands_match_p (operands[1], operands[4])
16597 && operands_match_p (operands[2], operands[3])))"
16598 [(set (match_dup 0)
16599 (if_then_else:DF (lt (match_dup 1)
16600 (match_dup 2))
16601 (match_dup 1)
16602 (match_dup 2)))])
16603
16604 ;; We can't represent the LT test directly. Do this by swapping the operands.
16605 (define_split
16606 [(set (match_operand:DF 0 "fp_register_operand" "")
16607 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
16608 (match_operand:DF 2 "register_operand" ""))
16609 (match_operand:DF 3 "register_operand" "")
16610 (match_operand:DF 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:DF (ge (reg:CCFP 17) (const_int 0))
16622 (match_dup 1)
16623 (match_dup 2)))])
16624
16625 (define_insn "*mindf_sse"
16626 [(set (match_operand:DF 0 "register_operand" "=Y")
16627 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
16628 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16629 (match_dup 1)
16630 (match_dup 2)))]
16631 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16632 "minsd\t{%2, %0|%0, %2}"
16633 [(set_attr "type" "sse")
16634 (set_attr "mode" "DF")])
16635
16636 (define_expand "maxsf3"
16637 [(parallel [
16638 (set (match_operand:SF 0 "register_operand" "")
16639 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16640 (match_operand:SF 2 "nonimmediate_operand" ""))
16641 (match_dup 1)
16642 (match_dup 2)))
16643 (clobber (reg:CC 17))])]
16644 "TARGET_SSE"
16645 "#")
16646
16647 (define_insn "*maxsf"
16648 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
16649 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
16650 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
16651 (match_dup 1)
16652 (match_dup 2)))
16653 (clobber (reg:CC 17))]
16654 "TARGET_SSE && TARGET_IEEE_FP"
16655 "#")
16656
16657 (define_insn "*maxsf_nonieee"
16658 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
16659 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
16660 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
16661 (match_dup 1)
16662 (match_dup 2)))
16663 (clobber (reg:CC 17))]
16664 "TARGET_SSE && !TARGET_IEEE_FP
16665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16666 "#")
16667
16668 (define_split
16669 [(set (match_operand:SF 0 "register_operand" "")
16670 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16671 (match_operand:SF 2 "nonimmediate_operand" ""))
16672 (match_operand:SF 3 "register_operand" "")
16673 (match_operand:SF 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:SF (gt (match_dup 1)
16682 (match_dup 2))
16683 (match_dup 1)
16684 (match_dup 2)))])
16685
16686 (define_split
16687 [(set (match_operand:SF 0 "fp_register_operand" "")
16688 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
16689 (match_operand:SF 2 "register_operand" ""))
16690 (match_operand:SF 3 "register_operand" "")
16691 (match_operand:SF 4 "register_operand" "")))
16692 (clobber (reg:CC 17))]
16693 "reload_completed
16694 && ((operands_match_p (operands[1], operands[3])
16695 && operands_match_p (operands[2], operands[4]))
16696 || (operands_match_p (operands[1], operands[4])
16697 && operands_match_p (operands[2], operands[3])))"
16698 [(set (reg:CCFP 17)
16699 (compare:CCFP (match_dup 1)
16700 (match_dup 2)))
16701 (set (match_dup 0)
16702 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
16703 (match_dup 1)
16704 (match_dup 2)))])
16705
16706 (define_insn "*maxsf_sse"
16707 [(set (match_operand:SF 0 "register_operand" "=x")
16708 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
16709 (match_operand:SF 2 "nonimmediate_operand" "xm"))
16710 (match_dup 1)
16711 (match_dup 2)))]
16712 "TARGET_SSE && reload_completed"
16713 "maxss\t{%2, %0|%0, %2}"
16714 [(set_attr "type" "sse")
16715 (set_attr "mode" "SF")])
16716
16717 (define_expand "maxdf3"
16718 [(parallel [
16719 (set (match_operand:DF 0 "register_operand" "")
16720 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16721 (match_operand:DF 2 "nonimmediate_operand" ""))
16722 (match_dup 1)
16723 (match_dup 2)))
16724 (clobber (reg:CC 17))])]
16725 "TARGET_SSE2 && TARGET_SSE_MATH"
16726 "#")
16727
16728 (define_insn "*maxdf"
16729 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
16730 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
16731 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
16732 (match_dup 1)
16733 (match_dup 2)))
16734 (clobber (reg:CC 17))]
16735 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
16736 "#")
16737
16738 (define_insn "*maxdf_nonieee"
16739 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
16740 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
16741 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
16742 (match_dup 1)
16743 (match_dup 2)))
16744 (clobber (reg:CC 17))]
16745 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
16746 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
16747 "#")
16748
16749 (define_split
16750 [(set (match_operand:DF 0 "register_operand" "")
16751 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16752 (match_operand:DF 2 "nonimmediate_operand" ""))
16753 (match_operand:DF 3 "register_operand" "")
16754 (match_operand:DF 4 "nonimmediate_operand" "")))
16755 (clobber (reg:CC 17))]
16756 "SSE_REG_P (operands[0]) && reload_completed
16757 && ((operands_match_p (operands[1], operands[3])
16758 && operands_match_p (operands[2], operands[4]))
16759 || (operands_match_p (operands[1], operands[4])
16760 && operands_match_p (operands[2], operands[3])))"
16761 [(set (match_dup 0)
16762 (if_then_else:DF (gt (match_dup 1)
16763 (match_dup 2))
16764 (match_dup 1)
16765 (match_dup 2)))])
16766
16767 (define_split
16768 [(set (match_operand:DF 0 "fp_register_operand" "")
16769 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
16770 (match_operand:DF 2 "register_operand" ""))
16771 (match_operand:DF 3 "register_operand" "")
16772 (match_operand:DF 4 "register_operand" "")))
16773 (clobber (reg:CC 17))]
16774 "reload_completed
16775 && ((operands_match_p (operands[1], operands[3])
16776 && operands_match_p (operands[2], operands[4]))
16777 || (operands_match_p (operands[1], operands[4])
16778 && operands_match_p (operands[2], operands[3])))"
16779 [(set (reg:CCFP 17)
16780 (compare:CCFP (match_dup 1)
16781 (match_dup 2)))
16782 (set (match_dup 0)
16783 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
16784 (match_dup 1)
16785 (match_dup 2)))])
16786
16787 (define_insn "*maxdf_sse"
16788 [(set (match_operand:DF 0 "register_operand" "=Y")
16789 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
16790 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
16791 (match_dup 1)
16792 (match_dup 2)))]
16793 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
16794 "maxsd\t{%2, %0|%0, %2}"
16795 [(set_attr "type" "sse")
16796 (set_attr "mode" "DF")])
16797 \f
16798 ;; Misc patterns (?)
16799
16800 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16801 ;; Otherwise there will be nothing to keep
16802 ;;
16803 ;; [(set (reg ebp) (reg esp))]
16804 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16805 ;; (clobber (eflags)]
16806 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16807 ;;
16808 ;; in proper program order.
16809 (define_insn "pro_epilogue_adjust_stack_1"
16810 [(set (match_operand:SI 0 "register_operand" "=r,r")
16811 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16812 (match_operand:SI 2 "immediate_operand" "i,i")))
16813 (clobber (reg:CC 17))
16814 (clobber (mem:BLK (scratch)))]
16815 "!TARGET_64BIT"
16816 {
16817 switch (get_attr_type (insn))
16818 {
16819 case TYPE_IMOV:
16820 return "mov{l}\t{%1, %0|%0, %1}";
16821
16822 case TYPE_ALU:
16823 if (GET_CODE (operands[2]) == CONST_INT
16824 && (INTVAL (operands[2]) == 128
16825 || (INTVAL (operands[2]) < 0
16826 && INTVAL (operands[2]) != -128)))
16827 {
16828 operands[2] = GEN_INT (-INTVAL (operands[2]));
16829 return "sub{l}\t{%2, %0|%0, %2}";
16830 }
16831 return "add{l}\t{%2, %0|%0, %2}";
16832
16833 case TYPE_LEA:
16834 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16835 return "lea{l}\t{%a2, %0|%0, %a2}";
16836
16837 default:
16838 abort ();
16839 }
16840 }
16841 [(set (attr "type")
16842 (cond [(eq_attr "alternative" "0")
16843 (const_string "alu")
16844 (match_operand:SI 2 "const0_operand" "")
16845 (const_string "imov")
16846 ]
16847 (const_string "lea")))
16848 (set_attr "mode" "SI")])
16849
16850 (define_insn "pro_epilogue_adjust_stack_rex64"
16851 [(set (match_operand:DI 0 "register_operand" "=r,r")
16852 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16853 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16854 (clobber (reg:CC 17))
16855 (clobber (mem:BLK (scratch)))]
16856 "TARGET_64BIT"
16857 {
16858 switch (get_attr_type (insn))
16859 {
16860 case TYPE_IMOV:
16861 return "mov{q}\t{%1, %0|%0, %1}";
16862
16863 case TYPE_ALU:
16864 if (GET_CODE (operands[2]) == CONST_INT
16865 /* Avoid overflows. */
16866 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
16867 && (INTVAL (operands[2]) == 128
16868 || (INTVAL (operands[2]) < 0
16869 && INTVAL (operands[2]) != -128)))
16870 {
16871 operands[2] = GEN_INT (-INTVAL (operands[2]));
16872 return "sub{q}\t{%2, %0|%0, %2}";
16873 }
16874 return "add{q}\t{%2, %0|%0, %2}";
16875
16876 case TYPE_LEA:
16877 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16878 return "lea{q}\t{%a2, %0|%0, %a2}";
16879
16880 default:
16881 abort ();
16882 }
16883 }
16884 [(set (attr "type")
16885 (cond [(eq_attr "alternative" "0")
16886 (const_string "alu")
16887 (match_operand:DI 2 "const0_operand" "")
16888 (const_string "imov")
16889 ]
16890 (const_string "lea")))
16891 (set_attr "mode" "DI")])
16892
16893 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16894 [(set (match_operand:DI 0 "register_operand" "=r,r")
16895 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16896 (match_operand:DI 3 "immediate_operand" "i,i")))
16897 (use (match_operand:DI 2 "register_operand" "r,r"))
16898 (clobber (reg:CC 17))
16899 (clobber (mem:BLK (scratch)))]
16900 "TARGET_64BIT"
16901 {
16902 switch (get_attr_type (insn))
16903 {
16904 case TYPE_ALU:
16905 return "add{q}\t{%2, %0|%0, %2}";
16906
16907 case TYPE_LEA:
16908 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16909 return "lea{q}\t{%a2, %0|%0, %a2}";
16910
16911 default:
16912 abort ();
16913 }
16914 }
16915 [(set_attr "type" "alu,lea")
16916 (set_attr "mode" "DI")])
16917
16918 ;; Placeholder for the conditional moves. This one is split either to SSE
16919 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
16920 ;; fact is that compares supported by the cmp??ss instructions are exactly
16921 ;; swapped of those supported by cmove sequence.
16922 ;; The EQ/NE comparisons also needs bit care, since they are not directly
16923 ;; supported by i387 comparisons and we do need to emit two conditional moves
16924 ;; in tandem.
16925
16926 (define_insn "sse_movsfcc"
16927 [(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")
16928 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
16929 [(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")
16930 (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")])
16931 (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")
16932 (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")))
16933 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16934 (clobber (reg:CC 17))]
16935 "TARGET_SSE
16936 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16937 /* Avoid combine from being smart and converting min/max
16938 instruction patterns into conditional moves. */
16939 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16940 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16941 || !rtx_equal_p (operands[4], operands[2])
16942 || !rtx_equal_p (operands[5], operands[3]))
16943 && (!TARGET_IEEE_FP
16944 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16945 "#")
16946
16947 (define_insn "sse_movsfcc_eq"
16948 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
16949 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
16950 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
16951 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
16952 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
16953 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
16954 (clobber (reg:CC 17))]
16955 "TARGET_SSE
16956 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16957 "#")
16958
16959 (define_insn "sse_movdfcc"
16960 [(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")
16961 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
16962 [(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")
16963 (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")])
16964 (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")
16965 (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")))
16966 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
16967 (clobber (reg:CC 17))]
16968 "TARGET_SSE2
16969 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
16970 /* Avoid combine from being smart and converting min/max
16971 instruction patterns into conditional moves. */
16972 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
16973 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
16974 || !rtx_equal_p (operands[4], operands[2])
16975 || !rtx_equal_p (operands[5], operands[3]))
16976 && (!TARGET_IEEE_FP
16977 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
16978 "#")
16979
16980 (define_insn "sse_movdfcc_eq"
16981 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16982 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16983 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16984 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16985 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
16986 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
16987 (clobber (reg:CC 17))]
16988 "TARGET_SSE
16989 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16990 "#")
16991
16992 ;; For non-sse moves just expand the usual cmove sequence.
16993 (define_split
16994 [(set (match_operand 0 "register_operand" "")
16995 (if_then_else (match_operator 1 "comparison_operator"
16996 [(match_operand 4 "nonimmediate_operand" "")
16997 (match_operand 5 "register_operand" "")])
16998 (match_operand 2 "nonimmediate_operand" "")
16999 (match_operand 3 "nonimmediate_operand" "")))
17000 (clobber (match_operand 6 "" ""))
17001 (clobber (reg:CC 17))]
17002 "!SSE_REG_P (operands[0]) && reload_completed
17003 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17004 [(const_int 0)]
17005 {
17006 ix86_compare_op0 = operands[5];
17007 ix86_compare_op1 = operands[4];
17008 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17009 VOIDmode, operands[5], operands[4]);
17010 ix86_expand_fp_movcc (operands);
17011 DONE;
17012 })
17013
17014 ;; Split SSE based conditional move into sequence:
17015 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17016 ;; and op2, op0 - zero op2 if comparison was false
17017 ;; nand op0, op3 - load op3 to op0 if comparison was false
17018 ;; or op2, op0 - get the nonzero one into the result.
17019 (define_split
17020 [(set (match_operand 0 "register_operand" "")
17021 (if_then_else (match_operator 1 "sse_comparison_operator"
17022 [(match_operand 4 "register_operand" "")
17023 (match_operand 5 "nonimmediate_operand" "")])
17024 (match_operand 2 "register_operand" "")
17025 (match_operand 3 "register_operand" "")))
17026 (clobber (match_operand 6 "" ""))
17027 (clobber (reg:CC 17))]
17028 "SSE_REG_P (operands[0]) && reload_completed"
17029 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17030 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17031 (subreg:TI (match_dup 4) 0)))
17032 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17033 (subreg:TI (match_dup 3) 0)))
17034 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17035 (subreg:TI (match_dup 7) 0)))]
17036 {
17037 if (GET_MODE (operands[2]) == DFmode
17038 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17039 {
17040 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17041 emit_insn (gen_sse2_unpcklpd (op, op, op));
17042 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17043 emit_insn (gen_sse2_unpcklpd (op, op, op));
17044 }
17045
17046 /* If op2 == op3, op3 would be clobbered before it is used. */
17047 if (operands_match_p (operands[2], operands[3]))
17048 {
17049 emit_move_insn (operands[0], operands[2]);
17050 DONE;
17051 }
17052
17053 PUT_MODE (operands[1], GET_MODE (operands[0]));
17054 if (operands_match_p (operands[0], operands[4]))
17055 operands[6] = operands[4], operands[7] = operands[2];
17056 else
17057 operands[6] = operands[2], operands[7] = operands[4];
17058 })
17059
17060 ;; Special case of conditional move we can handle effectively.
17061 ;; Do not brother with the integer/floating point case, since these are
17062 ;; bot considerably slower, unlike in the generic case.
17063 (define_insn "*sse_movsfcc_const0_1"
17064 [(set (match_operand:SF 0 "register_operand" "=&x")
17065 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17066 [(match_operand:SF 4 "register_operand" "0")
17067 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17068 (match_operand:SF 2 "register_operand" "x")
17069 (match_operand:SF 3 "const0_operand" "X")))]
17070 "TARGET_SSE"
17071 "#")
17072
17073 (define_insn "*sse_movsfcc_const0_2"
17074 [(set (match_operand:SF 0 "register_operand" "=&x")
17075 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17076 [(match_operand:SF 4 "register_operand" "0")
17077 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17078 (match_operand:SF 2 "const0_operand" "X")
17079 (match_operand:SF 3 "register_operand" "x")))]
17080 "TARGET_SSE"
17081 "#")
17082
17083 (define_insn "*sse_movsfcc_const0_3"
17084 [(set (match_operand:SF 0 "register_operand" "=&x")
17085 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17086 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17087 (match_operand:SF 5 "register_operand" "0")])
17088 (match_operand:SF 2 "register_operand" "x")
17089 (match_operand:SF 3 "const0_operand" "X")))]
17090 "TARGET_SSE"
17091 "#")
17092
17093 (define_insn "*sse_movsfcc_const0_4"
17094 [(set (match_operand:SF 0 "register_operand" "=&x")
17095 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17096 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17097 (match_operand:SF 5 "register_operand" "0")])
17098 (match_operand:SF 2 "const0_operand" "X")
17099 (match_operand:SF 3 "register_operand" "x")))]
17100 "TARGET_SSE"
17101 "#")
17102
17103 (define_insn "*sse_movdfcc_const0_1"
17104 [(set (match_operand:DF 0 "register_operand" "=&Y")
17105 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17106 [(match_operand:DF 4 "register_operand" "0")
17107 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17108 (match_operand:DF 2 "register_operand" "Y")
17109 (match_operand:DF 3 "const0_operand" "X")))]
17110 "TARGET_SSE2"
17111 "#")
17112
17113 (define_insn "*sse_movdfcc_const0_2"
17114 [(set (match_operand:DF 0 "register_operand" "=&Y")
17115 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17116 [(match_operand:DF 4 "register_operand" "0")
17117 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17118 (match_operand:DF 2 "const0_operand" "X")
17119 (match_operand:DF 3 "register_operand" "Y")))]
17120 "TARGET_SSE2"
17121 "#")
17122
17123 (define_insn "*sse_movdfcc_const0_3"
17124 [(set (match_operand:DF 0 "register_operand" "=&Y")
17125 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17126 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17127 (match_operand:DF 5 "register_operand" "0")])
17128 (match_operand:DF 2 "register_operand" "Y")
17129 (match_operand:DF 3 "const0_operand" "X")))]
17130 "TARGET_SSE2"
17131 "#")
17132
17133 (define_insn "*sse_movdfcc_const0_4"
17134 [(set (match_operand:DF 0 "register_operand" "=&Y")
17135 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17136 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17137 (match_operand:DF 5 "register_operand" "0")])
17138 (match_operand:DF 2 "const0_operand" "X")
17139 (match_operand:DF 3 "register_operand" "Y")))]
17140 "TARGET_SSE2"
17141 "#")
17142
17143 (define_split
17144 [(set (match_operand 0 "register_operand" "")
17145 (if_then_else (match_operator 1 "comparison_operator"
17146 [(match_operand 4 "nonimmediate_operand" "")
17147 (match_operand 5 "nonimmediate_operand" "")])
17148 (match_operand 2 "nonmemory_operand" "")
17149 (match_operand 3 "nonmemory_operand" "")))]
17150 "SSE_REG_P (operands[0]) && reload_completed
17151 && (const0_operand (operands[2], GET_MODE (operands[0]))
17152 || const0_operand (operands[3], GET_MODE (operands[0])))"
17153 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17154 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17155 (match_dup 7)))]
17156 {
17157 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17158 && GET_MODE (operands[2]) == DFmode)
17159 {
17160 if (REG_P (operands[2]))
17161 {
17162 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17163 emit_insn (gen_sse2_unpcklpd (op, op, op));
17164 }
17165 if (REG_P (operands[3]))
17166 {
17167 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17168 emit_insn (gen_sse2_unpcklpd (op, op, op));
17169 }
17170 }
17171 PUT_MODE (operands[1], GET_MODE (operands[0]));
17172 if (!sse_comparison_operator (operands[1], VOIDmode)
17173 || !rtx_equal_p (operands[0], operands[4]))
17174 {
17175 rtx tmp = operands[5];
17176 operands[5] = operands[4];
17177 operands[4] = tmp;
17178 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17179 }
17180 if (!rtx_equal_p (operands[0], operands[4]))
17181 abort ();
17182 if (const0_operand (operands[2], GET_MODE (operands[0])))
17183 {
17184 operands[7] = operands[3];
17185 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17186 0));
17187 }
17188 else
17189 {
17190 operands[7] = operands[2];
17191 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17192 }
17193 operands[7] = simplify_gen_subreg (TImode, operands[7],
17194 GET_MODE (operands[7]), 0);
17195 })
17196
17197 (define_expand "allocate_stack_worker"
17198 [(match_operand:SI 0 "register_operand" "")]
17199 "TARGET_STACK_PROBE"
17200 {
17201 if (reload_completed)
17202 {
17203 if (TARGET_64BIT)
17204 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
17205 else
17206 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
17207 }
17208 else
17209 {
17210 if (TARGET_64BIT)
17211 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17212 else
17213 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17214 }
17215 DONE;
17216 })
17217
17218 (define_insn "allocate_stack_worker_1"
17219 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17220 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17221 (clobber (match_scratch:SI 1 "=0"))
17222 (clobber (reg:CC 17))]
17223 "!TARGET_64BIT && TARGET_STACK_PROBE"
17224 "call\t__alloca"
17225 [(set_attr "type" "multi")
17226 (set_attr "length" "5")])
17227
17228 (define_expand "allocate_stack_worker_postreload"
17229 [(parallel [(unspec:SI [(match_operand:SI 0 "register_operand" "a")]
17230 UNSPEC_STACK_PROBE)
17231 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17232 (clobber (match_dup 0))
17233 (clobber (reg:CC 17))])]
17234 ""
17235 "")
17236
17237 (define_insn "allocate_stack_worker_rex64"
17238 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17239 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17240 (clobber (match_scratch:DI 1 "=0"))
17241 (clobber (reg:CC 17))]
17242 "TARGET_64BIT && TARGET_STACK_PROBE"
17243 "call\t__alloca"
17244 [(set_attr "type" "multi")
17245 (set_attr "length" "5")])
17246
17247 (define_expand "allocate_stack_worker_rex64_postreload"
17248 [(parallel [(unspec:DI [(match_operand:DI 0 "register_operand" "a")]
17249 UNSPEC_STACK_PROBE)
17250 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17251 (clobber (match_dup 0))
17252 (clobber (reg:CC 17))])]
17253 ""
17254 "")
17255
17256 (define_expand "allocate_stack"
17257 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17258 (minus:SI (reg:SI 7)
17259 (match_operand:SI 1 "general_operand" "")))
17260 (clobber (reg:CC 17))])
17261 (parallel [(set (reg:SI 7)
17262 (minus:SI (reg:SI 7) (match_dup 1)))
17263 (clobber (reg:CC 17))])]
17264 "TARGET_STACK_PROBE"
17265 {
17266 #ifdef CHECK_STACK_LIMIT
17267 if (GET_CODE (operands[1]) == CONST_INT
17268 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17269 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17270 operands[1]));
17271 else
17272 #endif
17273 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17274 operands[1])));
17275
17276 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17277 DONE;
17278 })
17279
17280 (define_expand "builtin_setjmp_receiver"
17281 [(label_ref (match_operand 0 "" ""))]
17282 "!TARGET_64BIT && flag_pic"
17283 {
17284 emit_insn (gen_set_got (pic_offset_table_rtx));
17285 DONE;
17286 })
17287 \f
17288 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17289
17290 (define_split
17291 [(set (match_operand 0 "register_operand" "")
17292 (match_operator 3 "promotable_binary_operator"
17293 [(match_operand 1 "register_operand" "")
17294 (match_operand 2 "aligned_operand" "")]))
17295 (clobber (reg:CC 17))]
17296 "! TARGET_PARTIAL_REG_STALL && reload_completed
17297 && ((GET_MODE (operands[0]) == HImode
17298 && ((!optimize_size && !TARGET_FAST_PREFIX)
17299 || GET_CODE (operands[2]) != CONST_INT
17300 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17301 || (GET_MODE (operands[0]) == QImode
17302 && (TARGET_PROMOTE_QImode || optimize_size)))"
17303 [(parallel [(set (match_dup 0)
17304 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17305 (clobber (reg:CC 17))])]
17306 "operands[0] = gen_lowpart (SImode, operands[0]);
17307 operands[1] = gen_lowpart (SImode, operands[1]);
17308 if (GET_CODE (operands[3]) != ASHIFT)
17309 operands[2] = gen_lowpart (SImode, operands[2]);
17310 PUT_MODE (operands[3], SImode);")
17311
17312 ; Promote the QImode tests, as i386 has encoding of the AND
17313 ; instruction with 32-bit sign-extended immediate and thus the
17314 ; instruction size is unchanged, except in the %eax case for
17315 ; which it is increased by one byte, hence the ! optimize_size.
17316 (define_split
17317 [(set (reg 17)
17318 (compare (and (match_operand 1 "aligned_operand" "")
17319 (match_operand 2 "const_int_operand" ""))
17320 (const_int 0)))
17321 (set (match_operand 0 "register_operand" "")
17322 (and (match_dup 1) (match_dup 2)))]
17323 "! TARGET_PARTIAL_REG_STALL && reload_completed
17324 /* Ensure that the operand will remain sign-extended immediate. */
17325 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17326 && ! optimize_size
17327 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17328 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17329 [(parallel [(set (reg:CCNO 17)
17330 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17331 (const_int 0)))
17332 (set (match_dup 0)
17333 (and:SI (match_dup 1) (match_dup 2)))])]
17334 "operands[2]
17335 = gen_int_mode (INTVAL (operands[2])
17336 & GET_MODE_MASK (GET_MODE (operands[0])),
17337 SImode);
17338 operands[0] = gen_lowpart (SImode, operands[0]);
17339 operands[1] = gen_lowpart (SImode, operands[1]);")
17340
17341 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17342 ; the TEST instruction with 32-bit sign-extended immediate and thus
17343 ; the instruction size would at least double, which is not what we
17344 ; want even with ! optimize_size.
17345 (define_split
17346 [(set (reg 17)
17347 (compare (and (match_operand:HI 0 "aligned_operand" "")
17348 (match_operand:HI 1 "const_int_operand" ""))
17349 (const_int 0)))]
17350 "! TARGET_PARTIAL_REG_STALL && reload_completed
17351 /* Ensure that the operand will remain sign-extended immediate. */
17352 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17353 && ! TARGET_FAST_PREFIX
17354 && ! optimize_size"
17355 [(set (reg:CCNO 17)
17356 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17357 (const_int 0)))]
17358 "operands[1]
17359 = gen_int_mode (INTVAL (operands[1])
17360 & GET_MODE_MASK (GET_MODE (operands[0])),
17361 SImode);
17362 operands[0] = gen_lowpart (SImode, operands[0]);")
17363
17364 (define_split
17365 [(set (match_operand 0 "register_operand" "")
17366 (neg (match_operand 1 "register_operand" "")))
17367 (clobber (reg:CC 17))]
17368 "! TARGET_PARTIAL_REG_STALL && reload_completed
17369 && (GET_MODE (operands[0]) == HImode
17370 || (GET_MODE (operands[0]) == QImode
17371 && (TARGET_PROMOTE_QImode || optimize_size)))"
17372 [(parallel [(set (match_dup 0)
17373 (neg:SI (match_dup 1)))
17374 (clobber (reg:CC 17))])]
17375 "operands[0] = gen_lowpart (SImode, operands[0]);
17376 operands[1] = gen_lowpart (SImode, operands[1]);")
17377
17378 (define_split
17379 [(set (match_operand 0 "register_operand" "")
17380 (not (match_operand 1 "register_operand" "")))]
17381 "! TARGET_PARTIAL_REG_STALL && reload_completed
17382 && (GET_MODE (operands[0]) == HImode
17383 || (GET_MODE (operands[0]) == QImode
17384 && (TARGET_PROMOTE_QImode || optimize_size)))"
17385 [(set (match_dup 0)
17386 (not:SI (match_dup 1)))]
17387 "operands[0] = gen_lowpart (SImode, operands[0]);
17388 operands[1] = gen_lowpart (SImode, operands[1]);")
17389
17390 (define_split
17391 [(set (match_operand 0 "register_operand" "")
17392 (if_then_else (match_operator 1 "comparison_operator"
17393 [(reg 17) (const_int 0)])
17394 (match_operand 2 "register_operand" "")
17395 (match_operand 3 "register_operand" "")))]
17396 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17397 && (GET_MODE (operands[0]) == HImode
17398 || (GET_MODE (operands[0]) == QImode
17399 && (TARGET_PROMOTE_QImode || optimize_size)))"
17400 [(set (match_dup 0)
17401 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17402 "operands[0] = gen_lowpart (SImode, operands[0]);
17403 operands[2] = gen_lowpart (SImode, operands[2]);
17404 operands[3] = gen_lowpart (SImode, operands[3]);")
17405
17406 \f
17407 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17408 ;; transform a complex memory operation into two memory to register operations.
17409
17410 ;; Don't push memory operands
17411 (define_peephole2
17412 [(set (match_operand:SI 0 "push_operand" "")
17413 (match_operand:SI 1 "memory_operand" ""))
17414 (match_scratch:SI 2 "r")]
17415 "! optimize_size && ! TARGET_PUSH_MEMORY"
17416 [(set (match_dup 2) (match_dup 1))
17417 (set (match_dup 0) (match_dup 2))]
17418 "")
17419
17420 (define_peephole2
17421 [(set (match_operand:DI 0 "push_operand" "")
17422 (match_operand:DI 1 "memory_operand" ""))
17423 (match_scratch:DI 2 "r")]
17424 "! optimize_size && ! TARGET_PUSH_MEMORY"
17425 [(set (match_dup 2) (match_dup 1))
17426 (set (match_dup 0) (match_dup 2))]
17427 "")
17428
17429 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17430 ;; SImode pushes.
17431 (define_peephole2
17432 [(set (match_operand:SF 0 "push_operand" "")
17433 (match_operand:SF 1 "memory_operand" ""))
17434 (match_scratch:SF 2 "r")]
17435 "! optimize_size && ! TARGET_PUSH_MEMORY"
17436 [(set (match_dup 2) (match_dup 1))
17437 (set (match_dup 0) (match_dup 2))]
17438 "")
17439
17440 (define_peephole2
17441 [(set (match_operand:HI 0 "push_operand" "")
17442 (match_operand:HI 1 "memory_operand" ""))
17443 (match_scratch:HI 2 "r")]
17444 "! optimize_size && ! TARGET_PUSH_MEMORY"
17445 [(set (match_dup 2) (match_dup 1))
17446 (set (match_dup 0) (match_dup 2))]
17447 "")
17448
17449 (define_peephole2
17450 [(set (match_operand:QI 0 "push_operand" "")
17451 (match_operand:QI 1 "memory_operand" ""))
17452 (match_scratch:QI 2 "q")]
17453 "! optimize_size && ! TARGET_PUSH_MEMORY"
17454 [(set (match_dup 2) (match_dup 1))
17455 (set (match_dup 0) (match_dup 2))]
17456 "")
17457
17458 ;; Don't move an immediate directly to memory when the instruction
17459 ;; gets too big.
17460 (define_peephole2
17461 [(match_scratch:SI 1 "r")
17462 (set (match_operand:SI 0 "memory_operand" "")
17463 (const_int 0))]
17464 "! optimize_size
17465 && ! TARGET_USE_MOV0
17466 && TARGET_SPLIT_LONG_MOVES
17467 && get_attr_length (insn) >= ix86_cost->large_insn
17468 && peep2_regno_dead_p (0, FLAGS_REG)"
17469 [(parallel [(set (match_dup 1) (const_int 0))
17470 (clobber (reg:CC 17))])
17471 (set (match_dup 0) (match_dup 1))]
17472 "")
17473
17474 (define_peephole2
17475 [(match_scratch:HI 1 "r")
17476 (set (match_operand:HI 0 "memory_operand" "")
17477 (const_int 0))]
17478 "! optimize_size
17479 && ! TARGET_USE_MOV0
17480 && TARGET_SPLIT_LONG_MOVES
17481 && get_attr_length (insn) >= ix86_cost->large_insn
17482 && peep2_regno_dead_p (0, FLAGS_REG)"
17483 [(parallel [(set (match_dup 2) (const_int 0))
17484 (clobber (reg:CC 17))])
17485 (set (match_dup 0) (match_dup 1))]
17486 "operands[2] = gen_lowpart (SImode, operands[1]);")
17487
17488 (define_peephole2
17489 [(match_scratch:QI 1 "q")
17490 (set (match_operand:QI 0 "memory_operand" "")
17491 (const_int 0))]
17492 "! optimize_size
17493 && ! TARGET_USE_MOV0
17494 && TARGET_SPLIT_LONG_MOVES
17495 && get_attr_length (insn) >= ix86_cost->large_insn
17496 && peep2_regno_dead_p (0, FLAGS_REG)"
17497 [(parallel [(set (match_dup 2) (const_int 0))
17498 (clobber (reg:CC 17))])
17499 (set (match_dup 0) (match_dup 1))]
17500 "operands[2] = gen_lowpart (SImode, operands[1]);")
17501
17502 (define_peephole2
17503 [(match_scratch:SI 2 "r")
17504 (set (match_operand:SI 0 "memory_operand" "")
17505 (match_operand:SI 1 "immediate_operand" ""))]
17506 "! optimize_size
17507 && get_attr_length (insn) >= ix86_cost->large_insn
17508 && TARGET_SPLIT_LONG_MOVES"
17509 [(set (match_dup 2) (match_dup 1))
17510 (set (match_dup 0) (match_dup 2))]
17511 "")
17512
17513 (define_peephole2
17514 [(match_scratch:HI 2 "r")
17515 (set (match_operand:HI 0 "memory_operand" "")
17516 (match_operand:HI 1 "immediate_operand" ""))]
17517 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17518 && TARGET_SPLIT_LONG_MOVES"
17519 [(set (match_dup 2) (match_dup 1))
17520 (set (match_dup 0) (match_dup 2))]
17521 "")
17522
17523 (define_peephole2
17524 [(match_scratch:QI 2 "q")
17525 (set (match_operand:QI 0 "memory_operand" "")
17526 (match_operand:QI 1 "immediate_operand" ""))]
17527 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
17528 && TARGET_SPLIT_LONG_MOVES"
17529 [(set (match_dup 2) (match_dup 1))
17530 (set (match_dup 0) (match_dup 2))]
17531 "")
17532
17533 ;; Don't compare memory with zero, load and use a test instead.
17534 (define_peephole2
17535 [(set (reg 17)
17536 (compare (match_operand:SI 0 "memory_operand" "")
17537 (const_int 0)))
17538 (match_scratch:SI 3 "r")]
17539 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
17540 [(set (match_dup 3) (match_dup 0))
17541 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
17542 "")
17543
17544 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17545 ;; Don't split NOTs with a displacement operand, because resulting XOR
17546 ;; will not be pairable anyway.
17547 ;;
17548 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
17549 ;; represented using a modRM byte. The XOR replacement is long decoded,
17550 ;; so this split helps here as well.
17551 ;;
17552 ;; Note: Can't do this as a regular split because we can't get proper
17553 ;; lifetime information then.
17554
17555 (define_peephole2
17556 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17557 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17558 "!optimize_size
17559 && peep2_regno_dead_p (0, FLAGS_REG)
17560 && ((TARGET_PENTIUM
17561 && (GET_CODE (operands[0]) != MEM
17562 || !memory_displacement_operand (operands[0], SImode)))
17563 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
17564 [(parallel [(set (match_dup 0)
17565 (xor:SI (match_dup 1) (const_int -1)))
17566 (clobber (reg:CC 17))])]
17567 "")
17568
17569 (define_peephole2
17570 [(set (match_operand:HI 0 "nonimmediate_operand" "")
17571 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17572 "!optimize_size
17573 && peep2_regno_dead_p (0, FLAGS_REG)
17574 && ((TARGET_PENTIUM
17575 && (GET_CODE (operands[0]) != MEM
17576 || !memory_displacement_operand (operands[0], HImode)))
17577 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
17578 [(parallel [(set (match_dup 0)
17579 (xor:HI (match_dup 1) (const_int -1)))
17580 (clobber (reg:CC 17))])]
17581 "")
17582
17583 (define_peephole2
17584 [(set (match_operand:QI 0 "nonimmediate_operand" "")
17585 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17586 "!optimize_size
17587 && peep2_regno_dead_p (0, FLAGS_REG)
17588 && ((TARGET_PENTIUM
17589 && (GET_CODE (operands[0]) != MEM
17590 || !memory_displacement_operand (operands[0], QImode)))
17591 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
17592 [(parallel [(set (match_dup 0)
17593 (xor:QI (match_dup 1) (const_int -1)))
17594 (clobber (reg:CC 17))])]
17595 "")
17596
17597 ;; Non pairable "test imm, reg" instructions can be translated to
17598 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17599 ;; byte opcode instead of two, have a short form for byte operands),
17600 ;; so do it for other CPUs as well. Given that the value was dead,
17601 ;; this should not create any new dependencies. Pass on the sub-word
17602 ;; versions if we're concerned about partial register stalls.
17603
17604 (define_peephole2
17605 [(set (reg 17)
17606 (compare (and:SI (match_operand:SI 0 "register_operand" "")
17607 (match_operand:SI 1 "immediate_operand" ""))
17608 (const_int 0)))]
17609 "ix86_match_ccmode (insn, CCNOmode)
17610 && (true_regnum (operands[0]) != 0
17611 || (GET_CODE (operands[1]) == CONST_INT
17612 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
17613 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17614 [(parallel
17615 [(set (reg:CCNO 17)
17616 (compare:CCNO (and:SI (match_dup 0)
17617 (match_dup 1))
17618 (const_int 0)))
17619 (set (match_dup 0)
17620 (and:SI (match_dup 0) (match_dup 1)))])]
17621 "")
17622
17623 ;; We don't need to handle HImode case, because it will be promoted to SImode
17624 ;; on ! TARGET_PARTIAL_REG_STALL
17625
17626 (define_peephole2
17627 [(set (reg 17)
17628 (compare (and:QI (match_operand:QI 0 "register_operand" "")
17629 (match_operand:QI 1 "immediate_operand" ""))
17630 (const_int 0)))]
17631 "! TARGET_PARTIAL_REG_STALL
17632 && ix86_match_ccmode (insn, CCNOmode)
17633 && true_regnum (operands[0]) != 0
17634 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17635 [(parallel
17636 [(set (reg:CCNO 17)
17637 (compare:CCNO (and:QI (match_dup 0)
17638 (match_dup 1))
17639 (const_int 0)))
17640 (set (match_dup 0)
17641 (and:QI (match_dup 0) (match_dup 1)))])]
17642 "")
17643
17644 (define_peephole2
17645 [(set (reg 17)
17646 (compare
17647 (and:SI
17648 (zero_extract:SI
17649 (match_operand 0 "ext_register_operand" "")
17650 (const_int 8)
17651 (const_int 8))
17652 (match_operand 1 "const_int_operand" ""))
17653 (const_int 0)))]
17654 "! TARGET_PARTIAL_REG_STALL
17655 && ix86_match_ccmode (insn, CCNOmode)
17656 && true_regnum (operands[0]) != 0
17657 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17658 [(parallel [(set (reg:CCNO 17)
17659 (compare:CCNO
17660 (and:SI
17661 (zero_extract:SI
17662 (match_dup 0)
17663 (const_int 8)
17664 (const_int 8))
17665 (match_dup 1))
17666 (const_int 0)))
17667 (set (zero_extract:SI (match_dup 0)
17668 (const_int 8)
17669 (const_int 8))
17670 (and:SI
17671 (zero_extract:SI
17672 (match_dup 0)
17673 (const_int 8)
17674 (const_int 8))
17675 (match_dup 1)))])]
17676 "")
17677
17678 ;; Don't do logical operations with memory inputs.
17679 (define_peephole2
17680 [(match_scratch:SI 2 "r")
17681 (parallel [(set (match_operand:SI 0 "register_operand" "")
17682 (match_operator:SI 3 "arith_or_logical_operator"
17683 [(match_dup 0)
17684 (match_operand:SI 1 "memory_operand" "")]))
17685 (clobber (reg:CC 17))])]
17686 "! optimize_size && ! TARGET_READ_MODIFY"
17687 [(set (match_dup 2) (match_dup 1))
17688 (parallel [(set (match_dup 0)
17689 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17690 (clobber (reg:CC 17))])]
17691 "")
17692
17693 (define_peephole2
17694 [(match_scratch:SI 2 "r")
17695 (parallel [(set (match_operand:SI 0 "register_operand" "")
17696 (match_operator:SI 3 "arith_or_logical_operator"
17697 [(match_operand:SI 1 "memory_operand" "")
17698 (match_dup 0)]))
17699 (clobber (reg:CC 17))])]
17700 "! optimize_size && ! TARGET_READ_MODIFY"
17701 [(set (match_dup 2) (match_dup 1))
17702 (parallel [(set (match_dup 0)
17703 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17704 (clobber (reg:CC 17))])]
17705 "")
17706
17707 ; Don't do logical operations with memory outputs
17708 ;
17709 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17710 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17711 ; the same decoder scheduling characteristics as the original.
17712
17713 (define_peephole2
17714 [(match_scratch:SI 2 "r")
17715 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17716 (match_operator:SI 3 "arith_or_logical_operator"
17717 [(match_dup 0)
17718 (match_operand:SI 1 "nonmemory_operand" "")]))
17719 (clobber (reg:CC 17))])]
17720 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17721 [(set (match_dup 2) (match_dup 0))
17722 (parallel [(set (match_dup 2)
17723 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17724 (clobber (reg:CC 17))])
17725 (set (match_dup 0) (match_dup 2))]
17726 "")
17727
17728 (define_peephole2
17729 [(match_scratch:SI 2 "r")
17730 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17731 (match_operator:SI 3 "arith_or_logical_operator"
17732 [(match_operand:SI 1 "nonmemory_operand" "")
17733 (match_dup 0)]))
17734 (clobber (reg:CC 17))])]
17735 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
17736 [(set (match_dup 2) (match_dup 0))
17737 (parallel [(set (match_dup 2)
17738 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17739 (clobber (reg:CC 17))])
17740 (set (match_dup 0) (match_dup 2))]
17741 "")
17742
17743 ;; Attempt to always use XOR for zeroing registers.
17744 (define_peephole2
17745 [(set (match_operand 0 "register_operand" "")
17746 (const_int 0))]
17747 "(GET_MODE (operands[0]) == QImode
17748 || GET_MODE (operands[0]) == HImode
17749 || GET_MODE (operands[0]) == SImode
17750 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17751 && (! TARGET_USE_MOV0 || optimize_size)
17752 && peep2_regno_dead_p (0, FLAGS_REG)"
17753 [(parallel [(set (match_dup 0) (const_int 0))
17754 (clobber (reg:CC 17))])]
17755 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17756 operands[0]);")
17757
17758 (define_peephole2
17759 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17760 (const_int 0))]
17761 "(GET_MODE (operands[0]) == QImode
17762 || GET_MODE (operands[0]) == HImode)
17763 && (! TARGET_USE_MOV0 || optimize_size)
17764 && peep2_regno_dead_p (0, FLAGS_REG)"
17765 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17766 (clobber (reg:CC 17))])])
17767
17768 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17769 (define_peephole2
17770 [(set (match_operand 0 "register_operand" "")
17771 (const_int -1))]
17772 "(GET_MODE (operands[0]) == HImode
17773 || GET_MODE (operands[0]) == SImode
17774 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17775 && (optimize_size || TARGET_PENTIUM)
17776 && peep2_regno_dead_p (0, FLAGS_REG)"
17777 [(parallel [(set (match_dup 0) (const_int -1))
17778 (clobber (reg:CC 17))])]
17779 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17780 operands[0]);")
17781
17782 ;; Attempt to convert simple leas to adds. These can be created by
17783 ;; move expanders.
17784 (define_peephole2
17785 [(set (match_operand:SI 0 "register_operand" "")
17786 (plus:SI (match_dup 0)
17787 (match_operand:SI 1 "nonmemory_operand" "")))]
17788 "peep2_regno_dead_p (0, FLAGS_REG)"
17789 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17790 (clobber (reg:CC 17))])]
17791 "")
17792
17793 (define_peephole2
17794 [(set (match_operand:SI 0 "register_operand" "")
17795 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17796 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17797 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17798 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17799 (clobber (reg:CC 17))])]
17800 "operands[2] = gen_lowpart (SImode, operands[2]);")
17801
17802 (define_peephole2
17803 [(set (match_operand:DI 0 "register_operand" "")
17804 (plus:DI (match_dup 0)
17805 (match_operand:DI 1 "x86_64_general_operand" "")))]
17806 "peep2_regno_dead_p (0, FLAGS_REG)"
17807 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17808 (clobber (reg:CC 17))])]
17809 "")
17810
17811 (define_peephole2
17812 [(set (match_operand:SI 0 "register_operand" "")
17813 (mult:SI (match_dup 0)
17814 (match_operand:SI 1 "const_int_operand" "")))]
17815 "exact_log2 (INTVAL (operands[1])) >= 0
17816 && peep2_regno_dead_p (0, FLAGS_REG)"
17817 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17818 (clobber (reg:CC 17))])]
17819 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17820
17821 (define_peephole2
17822 [(set (match_operand:DI 0 "register_operand" "")
17823 (mult:DI (match_dup 0)
17824 (match_operand:DI 1 "const_int_operand" "")))]
17825 "exact_log2 (INTVAL (operands[1])) >= 0
17826 && peep2_regno_dead_p (0, FLAGS_REG)"
17827 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17828 (clobber (reg:CC 17))])]
17829 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17830
17831 (define_peephole2
17832 [(set (match_operand:SI 0 "register_operand" "")
17833 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17834 (match_operand:DI 2 "const_int_operand" "")) 0))]
17835 "exact_log2 (INTVAL (operands[2])) >= 0
17836 && REGNO (operands[0]) == REGNO (operands[1])
17837 && peep2_regno_dead_p (0, FLAGS_REG)"
17838 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17839 (clobber (reg:CC 17))])]
17840 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17841
17842 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17843 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17844 ;; many CPUs it is also faster, since special hardware to avoid esp
17845 ;; dependencies is present.
17846
17847 ;; While some of these conversions may be done using splitters, we use peepholes
17848 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17849
17850 ;; Convert prologue esp subtractions to push.
17851 ;; We need register to push. In order to keep verify_flow_info happy we have
17852 ;; two choices
17853 ;; - use scratch and clobber it in order to avoid dependencies
17854 ;; - use already live register
17855 ;; We can't use the second way right now, since there is no reliable way how to
17856 ;; verify that given register is live. First choice will also most likely in
17857 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17858 ;; call clobbered registers are dead. We may want to use base pointer as an
17859 ;; alternative when no register is available later.
17860
17861 (define_peephole2
17862 [(match_scratch:SI 0 "r")
17863 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17864 (clobber (reg:CC 17))
17865 (clobber (mem:BLK (scratch)))])]
17866 "optimize_size || !TARGET_SUB_ESP_4"
17867 [(clobber (match_dup 0))
17868 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17869 (clobber (mem:BLK (scratch)))])])
17870
17871 (define_peephole2
17872 [(match_scratch:SI 0 "r")
17873 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17874 (clobber (reg:CC 17))
17875 (clobber (mem:BLK (scratch)))])]
17876 "optimize_size || !TARGET_SUB_ESP_8"
17877 [(clobber (match_dup 0))
17878 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17879 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17880 (clobber (mem:BLK (scratch)))])])
17881
17882 ;; Convert esp subtractions to push.
17883 (define_peephole2
17884 [(match_scratch:SI 0 "r")
17885 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
17886 (clobber (reg:CC 17))])]
17887 "optimize_size || !TARGET_SUB_ESP_4"
17888 [(clobber (match_dup 0))
17889 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17890
17891 (define_peephole2
17892 [(match_scratch:SI 0 "r")
17893 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
17894 (clobber (reg:CC 17))])]
17895 "optimize_size || !TARGET_SUB_ESP_8"
17896 [(clobber (match_dup 0))
17897 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
17898 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
17899
17900 ;; Convert epilogue deallocator to pop.
17901 (define_peephole2
17902 [(match_scratch:SI 0 "r")
17903 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17904 (clobber (reg:CC 17))
17905 (clobber (mem:BLK (scratch)))])]
17906 "optimize_size || !TARGET_ADD_ESP_4"
17907 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17908 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17909 (clobber (mem:BLK (scratch)))])]
17910 "")
17911
17912 ;; Two pops case is tricky, since pop causes dependency on destination register.
17913 ;; We use two registers if available.
17914 (define_peephole2
17915 [(match_scratch:SI 0 "r")
17916 (match_scratch:SI 1 "r")
17917 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17918 (clobber (reg:CC 17))
17919 (clobber (mem:BLK (scratch)))])]
17920 "optimize_size || !TARGET_ADD_ESP_8"
17921 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17922 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17923 (clobber (mem:BLK (scratch)))])
17924 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17925 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17926 "")
17927
17928 (define_peephole2
17929 [(match_scratch:SI 0 "r")
17930 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17931 (clobber (reg:CC 17))
17932 (clobber (mem:BLK (scratch)))])]
17933 "optimize_size"
17934 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17935 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17936 (clobber (mem:BLK (scratch)))])
17937 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17938 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17939 "")
17940
17941 ;; Convert esp additions to pop.
17942 (define_peephole2
17943 [(match_scratch:SI 0 "r")
17944 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
17945 (clobber (reg:CC 17))])]
17946 ""
17947 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17948 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17949 "")
17950
17951 ;; Two pops case is tricky, since pop causes dependency on destination register.
17952 ;; We use two registers if available.
17953 (define_peephole2
17954 [(match_scratch:SI 0 "r")
17955 (match_scratch:SI 1 "r")
17956 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17957 (clobber (reg:CC 17))])]
17958 ""
17959 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17960 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17961 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
17962 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17963 "")
17964
17965 (define_peephole2
17966 [(match_scratch:SI 0 "r")
17967 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
17968 (clobber (reg:CC 17))])]
17969 "optimize_size"
17970 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17971 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
17972 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
17973 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
17974 "")
17975 \f
17976 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17977 ;; required and register dies.
17978 (define_peephole2
17979 [(set (reg 17)
17980 (compare (match_operand:SI 0 "register_operand" "")
17981 (match_operand:SI 1 "incdec_operand" "")))]
17982 "ix86_match_ccmode (insn, CCGCmode)
17983 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17984 [(parallel [(set (reg:CCGC 17)
17985 (compare:CCGC (match_dup 0)
17986 (match_dup 1)))
17987 (clobber (match_dup 0))])]
17988 "")
17989
17990 (define_peephole2
17991 [(set (reg 17)
17992 (compare (match_operand:HI 0 "register_operand" "")
17993 (match_operand:HI 1 "incdec_operand" "")))]
17994 "ix86_match_ccmode (insn, CCGCmode)
17995 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
17996 [(parallel [(set (reg:CCGC 17)
17997 (compare:CCGC (match_dup 0)
17998 (match_dup 1)))
17999 (clobber (match_dup 0))])]
18000 "")
18001
18002 (define_peephole2
18003 [(set (reg 17)
18004 (compare (match_operand:QI 0 "register_operand" "")
18005 (match_operand:QI 1 "incdec_operand" "")))]
18006 "ix86_match_ccmode (insn, CCGCmode)
18007 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18008 [(parallel [(set (reg:CCGC 17)
18009 (compare:CCGC (match_dup 0)
18010 (match_dup 1)))
18011 (clobber (match_dup 0))])]
18012 "")
18013
18014 ;; Convert compares with 128 to shorter add -128
18015 (define_peephole2
18016 [(set (reg 17)
18017 (compare (match_operand:SI 0 "register_operand" "")
18018 (const_int 128)))]
18019 "ix86_match_ccmode (insn, CCGCmode)
18020 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18021 [(parallel [(set (reg:CCGC 17)
18022 (compare:CCGC (match_dup 0)
18023 (const_int 128)))
18024 (clobber (match_dup 0))])]
18025 "")
18026
18027 (define_peephole2
18028 [(set (reg 17)
18029 (compare (match_operand:HI 0 "register_operand" "")
18030 (const_int 128)))]
18031 "ix86_match_ccmode (insn, CCGCmode)
18032 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18033 [(parallel [(set (reg:CCGC 17)
18034 (compare:CCGC (match_dup 0)
18035 (const_int 128)))
18036 (clobber (match_dup 0))])]
18037 "")
18038 \f
18039 (define_peephole2
18040 [(match_scratch:DI 0 "r")
18041 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18042 (clobber (reg:CC 17))
18043 (clobber (mem:BLK (scratch)))])]
18044 "optimize_size || !TARGET_SUB_ESP_4"
18045 [(clobber (match_dup 0))
18046 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18047 (clobber (mem:BLK (scratch)))])])
18048
18049 (define_peephole2
18050 [(match_scratch:DI 0 "r")
18051 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18052 (clobber (reg:CC 17))
18053 (clobber (mem:BLK (scratch)))])]
18054 "optimize_size || !TARGET_SUB_ESP_8"
18055 [(clobber (match_dup 0))
18056 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18057 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18058 (clobber (mem:BLK (scratch)))])])
18059
18060 ;; Convert esp subtractions to push.
18061 (define_peephole2
18062 [(match_scratch:DI 0 "r")
18063 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18064 (clobber (reg:CC 17))])]
18065 "optimize_size || !TARGET_SUB_ESP_4"
18066 [(clobber (match_dup 0))
18067 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18068
18069 (define_peephole2
18070 [(match_scratch:DI 0 "r")
18071 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18072 (clobber (reg:CC 17))])]
18073 "optimize_size || !TARGET_SUB_ESP_8"
18074 [(clobber (match_dup 0))
18075 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18076 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18077
18078 ;; Convert epilogue deallocator to pop.
18079 (define_peephole2
18080 [(match_scratch:DI 0 "r")
18081 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18082 (clobber (reg:CC 17))
18083 (clobber (mem:BLK (scratch)))])]
18084 "optimize_size || !TARGET_ADD_ESP_4"
18085 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18086 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18087 (clobber (mem:BLK (scratch)))])]
18088 "")
18089
18090 ;; Two pops case is tricky, since pop causes dependency on destination register.
18091 ;; We use two registers if available.
18092 (define_peephole2
18093 [(match_scratch:DI 0 "r")
18094 (match_scratch:DI 1 "r")
18095 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18096 (clobber (reg:CC 17))
18097 (clobber (mem:BLK (scratch)))])]
18098 "optimize_size || !TARGET_ADD_ESP_8"
18099 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18100 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18101 (clobber (mem:BLK (scratch)))])
18102 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18103 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18104 "")
18105
18106 (define_peephole2
18107 [(match_scratch:DI 0 "r")
18108 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18109 (clobber (reg:CC 17))
18110 (clobber (mem:BLK (scratch)))])]
18111 "optimize_size"
18112 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18113 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18114 (clobber (mem:BLK (scratch)))])
18115 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18116 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18117 "")
18118
18119 ;; Convert esp additions to pop.
18120 (define_peephole2
18121 [(match_scratch:DI 0 "r")
18122 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18123 (clobber (reg:CC 17))])]
18124 ""
18125 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18126 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18127 "")
18128
18129 ;; Two pops case is tricky, since pop causes dependency on destination register.
18130 ;; We use two registers if available.
18131 (define_peephole2
18132 [(match_scratch:DI 0 "r")
18133 (match_scratch:DI 1 "r")
18134 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18135 (clobber (reg:CC 17))])]
18136 ""
18137 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18138 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18139 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18140 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18141 "")
18142
18143 (define_peephole2
18144 [(match_scratch:DI 0 "r")
18145 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18146 (clobber (reg:CC 17))])]
18147 "optimize_size"
18148 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18149 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18150 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18151 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18152 "")
18153 \f
18154 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18155 ;; imul $32bit_imm, reg, reg is direct decoded.
18156 (define_peephole2
18157 [(match_scratch:DI 3 "r")
18158 (parallel [(set (match_operand:DI 0 "register_operand" "")
18159 (mult:DI (match_operand:DI 1 "memory_operand" "")
18160 (match_operand:DI 2 "immediate_operand" "")))
18161 (clobber (reg:CC 17))])]
18162 "TARGET_K8 && !optimize_size
18163 && (GET_CODE (operands[2]) != CONST_INT
18164 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18165 [(set (match_dup 3) (match_dup 1))
18166 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18167 (clobber (reg:CC 17))])]
18168 "")
18169
18170 (define_peephole2
18171 [(match_scratch:SI 3 "r")
18172 (parallel [(set (match_operand:SI 0 "register_operand" "")
18173 (mult:SI (match_operand:SI 1 "memory_operand" "")
18174 (match_operand:SI 2 "immediate_operand" "")))
18175 (clobber (reg:CC 17))])]
18176 "TARGET_K8 && !optimize_size
18177 && (GET_CODE (operands[2]) != CONST_INT
18178 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18179 [(set (match_dup 3) (match_dup 1))
18180 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18181 (clobber (reg:CC 17))])]
18182 "")
18183
18184 (define_peephole2
18185 [(match_scratch:SI 3 "r")
18186 (parallel [(set (match_operand:DI 0 "register_operand" "")
18187 (zero_extend:DI
18188 (mult:SI (match_operand:SI 1 "memory_operand" "")
18189 (match_operand:SI 2 "immediate_operand" ""))))
18190 (clobber (reg:CC 17))])]
18191 "TARGET_K8 && !optimize_size
18192 && (GET_CODE (operands[2]) != CONST_INT
18193 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18194 [(set (match_dup 3) (match_dup 1))
18195 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18196 (clobber (reg:CC 17))])]
18197 "")
18198
18199 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18200 ;; Convert it into imul reg, reg
18201 ;; It would be better to force assembler to encode instruction using long
18202 ;; immediate, but there is apparently no way to do so.
18203 (define_peephole2
18204 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18205 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18206 (match_operand:DI 2 "const_int_operand" "")))
18207 (clobber (reg:CC 17))])
18208 (match_scratch:DI 3 "r")]
18209 "TARGET_K8 && !optimize_size
18210 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18211 [(set (match_dup 3) (match_dup 2))
18212 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18213 (clobber (reg:CC 17))])]
18214 {
18215 if (!rtx_equal_p (operands[0], operands[1]))
18216 emit_move_insn (operands[0], operands[1]);
18217 })
18218
18219 (define_peephole2
18220 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18221 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18222 (match_operand:SI 2 "const_int_operand" "")))
18223 (clobber (reg:CC 17))])
18224 (match_scratch:SI 3 "r")]
18225 "TARGET_K8 && !optimize_size
18226 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18227 [(set (match_dup 3) (match_dup 2))
18228 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18229 (clobber (reg:CC 17))])]
18230 {
18231 if (!rtx_equal_p (operands[0], operands[1]))
18232 emit_move_insn (operands[0], operands[1]);
18233 })
18234
18235 (define_peephole2
18236 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18237 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18238 (match_operand:HI 2 "immediate_operand" "")))
18239 (clobber (reg:CC 17))])
18240 (match_scratch:HI 3 "r")]
18241 "TARGET_K8 && !optimize_size"
18242 [(set (match_dup 3) (match_dup 2))
18243 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18244 (clobber (reg:CC 17))])]
18245 {
18246 if (!rtx_equal_p (operands[0], operands[1]))
18247 emit_move_insn (operands[0], operands[1]);
18248 })
18249 \f
18250 ;; Call-value patterns last so that the wildcard operand does not
18251 ;; disrupt insn-recog's switch tables.
18252
18253 (define_insn "*call_value_pop_0"
18254 [(set (match_operand 0 "" "")
18255 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18256 (match_operand:SI 2 "" "")))
18257 (set (reg:SI 7) (plus:SI (reg:SI 7)
18258 (match_operand:SI 3 "immediate_operand" "")))]
18259 "!TARGET_64BIT"
18260 {
18261 if (SIBLING_CALL_P (insn))
18262 return "jmp\t%P1";
18263 else
18264 return "call\t%P1";
18265 }
18266 [(set_attr "type" "callv")])
18267
18268 (define_insn "*call_value_pop_1"
18269 [(set (match_operand 0 "" "")
18270 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18271 (match_operand:SI 2 "" "")))
18272 (set (reg:SI 7) (plus:SI (reg:SI 7)
18273 (match_operand:SI 3 "immediate_operand" "i")))]
18274 "!TARGET_64BIT"
18275 {
18276 if (constant_call_address_operand (operands[1], QImode))
18277 {
18278 if (SIBLING_CALL_P (insn))
18279 return "jmp\t%P1";
18280 else
18281 return "call\t%P1";
18282 }
18283 if (SIBLING_CALL_P (insn))
18284 return "jmp\t%A1";
18285 else
18286 return "call\t%A1";
18287 }
18288 [(set_attr "type" "callv")])
18289
18290 (define_insn "*call_value_0"
18291 [(set (match_operand 0 "" "")
18292 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18293 (match_operand:SI 2 "" "")))]
18294 "!TARGET_64BIT"
18295 {
18296 if (SIBLING_CALL_P (insn))
18297 return "jmp\t%P1";
18298 else
18299 return "call\t%P1";
18300 }
18301 [(set_attr "type" "callv")])
18302
18303 (define_insn "*call_value_0_rex64"
18304 [(set (match_operand 0 "" "")
18305 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18306 (match_operand:DI 2 "const_int_operand" "")))]
18307 "TARGET_64BIT"
18308 {
18309 if (SIBLING_CALL_P (insn))
18310 return "jmp\t%P1";
18311 else
18312 return "call\t%P1";
18313 }
18314 [(set_attr "type" "callv")])
18315
18316 (define_insn "*call_value_1"
18317 [(set (match_operand 0 "" "")
18318 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18319 (match_operand:SI 2 "" "")))]
18320 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18321 {
18322 if (constant_call_address_operand (operands[1], QImode))
18323 return "call\t%P1";
18324 return "call\t%*%1";
18325 }
18326 [(set_attr "type" "callv")])
18327
18328 (define_insn "*sibcall_value_1"
18329 [(set (match_operand 0 "" "")
18330 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18331 (match_operand:SI 2 "" "")))]
18332 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18333 {
18334 if (constant_call_address_operand (operands[1], QImode))
18335 return "jmp\t%P1";
18336 return "jmp\t%*%1";
18337 }
18338 [(set_attr "type" "callv")])
18339
18340 (define_insn "*call_value_1_rex64"
18341 [(set (match_operand 0 "" "")
18342 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18343 (match_operand:DI 2 "" "")))]
18344 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18345 {
18346 if (constant_call_address_operand (operands[1], QImode))
18347 return "call\t%P1";
18348 return "call\t%A1";
18349 }
18350 [(set_attr "type" "callv")])
18351
18352 (define_insn "*sibcall_value_1_rex64"
18353 [(set (match_operand 0 "" "")
18354 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18355 (match_operand:DI 2 "" "")))]
18356 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18357 "jmp\t%P1"
18358 [(set_attr "type" "callv")])
18359
18360 (define_insn "*sibcall_value_1_rex64_v"
18361 [(set (match_operand 0 "" "")
18362 (call (mem:QI (reg:DI 40))
18363 (match_operand:DI 1 "" "")))]
18364 "SIBLING_CALL_P (insn) && TARGET_64BIT"
18365 "jmp\t*%%r11"
18366 [(set_attr "type" "callv")])
18367 \f
18368 (define_insn "trap"
18369 [(trap_if (const_int 1) (const_int 5))]
18370 ""
18371 "int\t$5")
18372
18373 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18374 ;;; for the sake of bounds checking. By emitting bounds checks as
18375 ;;; conditional traps rather than as conditional jumps around
18376 ;;; unconditional traps we avoid introducing spurious basic-block
18377 ;;; boundaries and facilitate elimination of redundant checks. In
18378 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18379 ;;; interrupt 5.
18380 ;;;
18381 ;;; FIXME: Static branch prediction rules for ix86 are such that
18382 ;;; forward conditional branches predict as untaken. As implemented
18383 ;;; below, pseudo conditional traps violate that rule. We should use
18384 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18385 ;;; section loaded at the end of the text segment and branch forward
18386 ;;; there on bounds-failure, and then jump back immediately (in case
18387 ;;; the system chooses to ignore bounds violations, or to report
18388 ;;; violations and continue execution).
18389
18390 (define_expand "conditional_trap"
18391 [(trap_if (match_operator 0 "comparison_operator"
18392 [(match_dup 2) (const_int 0)])
18393 (match_operand 1 "const_int_operand" ""))]
18394 ""
18395 {
18396 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18397 ix86_expand_compare (GET_CODE (operands[0]),
18398 NULL, NULL),
18399 operands[1]));
18400 DONE;
18401 })
18402
18403 (define_insn "*conditional_trap_1"
18404 [(trap_if (match_operator 0 "comparison_operator"
18405 [(reg 17) (const_int 0)])
18406 (match_operand 1 "const_int_operand" ""))]
18407 ""
18408 {
18409 operands[2] = gen_label_rtx ();
18410 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18411 (*targetm.asm_out.internal_label) (asm_out_file, "L",
18412 CODE_LABEL_NUMBER (operands[2]));
18413 RET;
18414 })
18415
18416 ;; Pentium III SIMD instructions.
18417
18418 ;; Moves for SSE/MMX regs.
18419
18420 (define_insn "movv4sf_internal"
18421 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18422 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18423 "TARGET_SSE"
18424 "@
18425 xorps\t%0, %0
18426 movaps\t{%1, %0|%0, %1}
18427 movaps\t{%1, %0|%0, %1}"
18428 [(set_attr "type" "ssemov")
18429 (set_attr "mode" "V4SF")])
18430
18431 (define_split
18432 [(set (match_operand:V4SF 0 "register_operand" "")
18433 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18434 "TARGET_SSE"
18435 [(set (match_dup 0)
18436 (vec_merge:V4SF
18437 (vec_duplicate:V4SF (match_dup 1))
18438 (match_dup 2)
18439 (const_int 1)))]
18440 {
18441 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18442 operands[2] = CONST0_RTX (V4SFmode);
18443 })
18444
18445 (define_insn "movv4si_internal"
18446 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18447 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18448 "TARGET_SSE"
18449 {
18450 switch (which_alternative)
18451 {
18452 case 0:
18453 if (get_attr_mode (insn) == MODE_V4SF)
18454 return "xorps\t%0, %0";
18455 else
18456 return "pxor\t%0, %0";
18457 case 1:
18458 case 2:
18459 if (get_attr_mode (insn) == MODE_V4SF)
18460 return "movaps\t{%1, %0|%0, %1}";
18461 else
18462 return "movdqa\t{%1, %0|%0, %1}";
18463 default:
18464 abort ();
18465 }
18466 }
18467 [(set_attr "type" "ssemov")
18468 (set (attr "mode")
18469 (cond [(eq_attr "alternative" "0,1")
18470 (if_then_else
18471 (ne (symbol_ref "optimize_size")
18472 (const_int 0))
18473 (const_string "V4SF")
18474 (const_string "TI"))
18475 (eq_attr "alternative" "2")
18476 (if_then_else
18477 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18478 (const_int 0))
18479 (ne (symbol_ref "optimize_size")
18480 (const_int 0)))
18481 (const_string "V4SF")
18482 (const_string "TI"))]
18483 (const_string "TI")))])
18484
18485 (define_insn "movv2di_internal"
18486 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
18487 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
18488 "TARGET_SSE2"
18489 {
18490 switch (which_alternative)
18491 {
18492 case 0:
18493 if (get_attr_mode (insn) == MODE_V4SF)
18494 return "xorps\t%0, %0";
18495 else
18496 return "pxor\t%0, %0";
18497 case 1:
18498 case 2:
18499 if (get_attr_mode (insn) == MODE_V4SF)
18500 return "movaps\t{%1, %0|%0, %1}";
18501 else
18502 return "movdqa\t{%1, %0|%0, %1}";
18503 default:
18504 abort ();
18505 }
18506 }
18507 [(set_attr "type" "ssemov")
18508 (set (attr "mode")
18509 (cond [(eq_attr "alternative" "0,1")
18510 (if_then_else
18511 (ne (symbol_ref "optimize_size")
18512 (const_int 0))
18513 (const_string "V4SF")
18514 (const_string "TI"))
18515 (eq_attr "alternative" "2")
18516 (if_then_else
18517 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18518 (const_int 0))
18519 (ne (symbol_ref "optimize_size")
18520 (const_int 0)))
18521 (const_string "V4SF")
18522 (const_string "TI"))]
18523 (const_string "TI")))])
18524
18525 (define_split
18526 [(set (match_operand:V2DF 0 "register_operand" "")
18527 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
18528 "TARGET_SSE2"
18529 [(set (match_dup 0)
18530 (vec_merge:V2DF
18531 (vec_duplicate:V2DF (match_dup 1))
18532 (match_dup 2)
18533 (const_int 1)))]
18534 {
18535 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
18536 operands[2] = CONST0_RTX (V2DFmode);
18537 })
18538
18539 (define_insn "movv8qi_internal"
18540 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
18541 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
18542 "TARGET_MMX
18543 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18544 "@
18545 pxor\t%0, %0
18546 movq\t{%1, %0|%0, %1}
18547 movq\t{%1, %0|%0, %1}"
18548 [(set_attr "type" "mmxmov")
18549 (set_attr "mode" "DI")])
18550
18551 (define_insn "movv4hi_internal"
18552 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
18553 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
18554 "TARGET_MMX
18555 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18556 "@
18557 pxor\t%0, %0
18558 movq\t{%1, %0|%0, %1}
18559 movq\t{%1, %0|%0, %1}"
18560 [(set_attr "type" "mmxmov")
18561 (set_attr "mode" "DI")])
18562
18563 (define_insn "movv2si_internal"
18564 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
18565 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
18566 "TARGET_MMX
18567 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18568 "@
18569 pxor\t%0, %0
18570 movq\t{%1, %0|%0, %1}
18571 movq\t{%1, %0|%0, %1}"
18572 [(set_attr "type" "mmxcvt")
18573 (set_attr "mode" "DI")])
18574
18575 (define_insn "movv2sf_internal"
18576 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
18577 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
18578 "TARGET_3DNOW
18579 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18580 "@
18581 pxor\t%0, %0
18582 movq\t{%1, %0|%0, %1}
18583 movq\t{%1, %0|%0, %1}"
18584 [(set_attr "type" "mmxcvt")
18585 (set_attr "mode" "DI")])
18586
18587 (define_expand "movti"
18588 [(set (match_operand:TI 0 "nonimmediate_operand" "")
18589 (match_operand:TI 1 "nonimmediate_operand" ""))]
18590 "TARGET_SSE || TARGET_64BIT"
18591 {
18592 if (TARGET_64BIT)
18593 ix86_expand_move (TImode, operands);
18594 else
18595 ix86_expand_vector_move (TImode, operands);
18596 DONE;
18597 })
18598
18599 (define_expand "movtf"
18600 [(set (match_operand:TF 0 "nonimmediate_operand" "")
18601 (match_operand:TF 1 "nonimmediate_operand" ""))]
18602 "TARGET_64BIT"
18603 {
18604 if (TARGET_64BIT)
18605 ix86_expand_move (TFmode, operands);
18606 else
18607 ix86_expand_vector_move (TFmode, operands);
18608 DONE;
18609 })
18610
18611 (define_insn "movv2df_internal"
18612 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
18613 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
18614 "TARGET_SSE2
18615 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18616 {
18617 switch (which_alternative)
18618 {
18619 case 0:
18620 if (get_attr_mode (insn) == MODE_V4SF)
18621 return "xorps\t%0, %0";
18622 else
18623 return "xorpd\t%0, %0";
18624 case 1:
18625 case 2:
18626 if (get_attr_mode (insn) == MODE_V4SF)
18627 return "movaps\t{%1, %0|%0, %1}";
18628 else
18629 return "movapd\t{%1, %0|%0, %1}";
18630 default:
18631 abort ();
18632 }
18633 }
18634 [(set_attr "type" "ssemov")
18635 (set (attr "mode")
18636 (cond [(eq_attr "alternative" "0,1")
18637 (if_then_else
18638 (ne (symbol_ref "optimize_size")
18639 (const_int 0))
18640 (const_string "V4SF")
18641 (const_string "V2DF"))
18642 (eq_attr "alternative" "2")
18643 (if_then_else
18644 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18645 (const_int 0))
18646 (ne (symbol_ref "optimize_size")
18647 (const_int 0)))
18648 (const_string "V4SF")
18649 (const_string "V2DF"))]
18650 (const_string "V2DF")))])
18651
18652 (define_insn "movv8hi_internal"
18653 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
18654 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
18655 "TARGET_SSE2
18656 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18657 {
18658 switch (which_alternative)
18659 {
18660 case 0:
18661 if (get_attr_mode (insn) == MODE_V4SF)
18662 return "xorps\t%0, %0";
18663 else
18664 return "pxor\t%0, %0";
18665 case 1:
18666 case 2:
18667 if (get_attr_mode (insn) == MODE_V4SF)
18668 return "movaps\t{%1, %0|%0, %1}";
18669 else
18670 return "movdqa\t{%1, %0|%0, %1}";
18671 default:
18672 abort ();
18673 }
18674 }
18675 [(set_attr "type" "ssemov")
18676 (set (attr "mode")
18677 (cond [(eq_attr "alternative" "0,1")
18678 (if_then_else
18679 (ne (symbol_ref "optimize_size")
18680 (const_int 0))
18681 (const_string "V4SF")
18682 (const_string "TI"))
18683 (eq_attr "alternative" "2")
18684 (if_then_else
18685 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18686 (const_int 0))
18687 (ne (symbol_ref "optimize_size")
18688 (const_int 0)))
18689 (const_string "V4SF")
18690 (const_string "TI"))]
18691 (const_string "TI")))])
18692
18693 (define_insn "movv16qi_internal"
18694 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
18695 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
18696 "TARGET_SSE2
18697 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18698 {
18699 switch (which_alternative)
18700 {
18701 case 0:
18702 if (get_attr_mode (insn) == MODE_V4SF)
18703 return "xorps\t%0, %0";
18704 else
18705 return "pxor\t%0, %0";
18706 case 1:
18707 case 2:
18708 if (get_attr_mode (insn) == MODE_V4SF)
18709 return "movaps\t{%1, %0|%0, %1}";
18710 else
18711 return "movdqa\t{%1, %0|%0, %1}";
18712 default:
18713 abort ();
18714 }
18715 }
18716 [(set_attr "type" "ssemov")
18717 (set (attr "mode")
18718 (cond [(eq_attr "alternative" "0,1")
18719 (if_then_else
18720 (ne (symbol_ref "optimize_size")
18721 (const_int 0))
18722 (const_string "V4SF")
18723 (const_string "TI"))
18724 (eq_attr "alternative" "2")
18725 (if_then_else
18726 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18727 (const_int 0))
18728 (ne (symbol_ref "optimize_size")
18729 (const_int 0)))
18730 (const_string "V4SF")
18731 (const_string "TI"))]
18732 (const_string "TI")))])
18733
18734 (define_expand "movv2df"
18735 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
18736 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
18737 "TARGET_SSE2"
18738 {
18739 ix86_expand_vector_move (V2DFmode, operands);
18740 DONE;
18741 })
18742
18743 (define_expand "movv8hi"
18744 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
18745 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
18746 "TARGET_SSE2"
18747 {
18748 ix86_expand_vector_move (V8HImode, operands);
18749 DONE;
18750 })
18751
18752 (define_expand "movv16qi"
18753 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
18754 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
18755 "TARGET_SSE2"
18756 {
18757 ix86_expand_vector_move (V16QImode, operands);
18758 DONE;
18759 })
18760
18761 (define_expand "movv4sf"
18762 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
18763 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
18764 "TARGET_SSE"
18765 {
18766 ix86_expand_vector_move (V4SFmode, operands);
18767 DONE;
18768 })
18769
18770 (define_expand "movv4si"
18771 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
18772 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
18773 "TARGET_SSE"
18774 {
18775 ix86_expand_vector_move (V4SImode, operands);
18776 DONE;
18777 })
18778
18779 (define_expand "movv2di"
18780 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
18781 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
18782 "TARGET_SSE"
18783 {
18784 ix86_expand_vector_move (V2DImode, operands);
18785 DONE;
18786 })
18787
18788 (define_expand "movv2si"
18789 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
18790 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
18791 "TARGET_MMX"
18792 {
18793 ix86_expand_vector_move (V2SImode, operands);
18794 DONE;
18795 })
18796
18797 (define_expand "movv4hi"
18798 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
18799 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
18800 "TARGET_MMX"
18801 {
18802 ix86_expand_vector_move (V4HImode, operands);
18803 DONE;
18804 })
18805
18806 (define_expand "movv8qi"
18807 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
18808 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
18809 "TARGET_MMX"
18810 {
18811 ix86_expand_vector_move (V8QImode, operands);
18812 DONE;
18813 })
18814
18815 (define_expand "movv2sf"
18816 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
18817 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
18818 "TARGET_3DNOW"
18819 {
18820 ix86_expand_vector_move (V2SFmode, operands);
18821 DONE;
18822 })
18823
18824 (define_insn "*pushti"
18825 [(set (match_operand:TI 0 "push_operand" "=<")
18826 (match_operand:TI 1 "register_operand" "x"))]
18827 "TARGET_SSE"
18828 "#")
18829
18830 (define_insn "*pushv2df"
18831 [(set (match_operand:V2DF 0 "push_operand" "=<")
18832 (match_operand:V2DF 1 "register_operand" "x"))]
18833 "TARGET_SSE"
18834 "#")
18835
18836 (define_insn "*pushv2di"
18837 [(set (match_operand:V2DI 0 "push_operand" "=<")
18838 (match_operand:V2DI 1 "register_operand" "x"))]
18839 "TARGET_SSE2"
18840 "#")
18841
18842 (define_insn "*pushv8hi"
18843 [(set (match_operand:V8HI 0 "push_operand" "=<")
18844 (match_operand:V8HI 1 "register_operand" "x"))]
18845 "TARGET_SSE2"
18846 "#")
18847
18848 (define_insn "*pushv16qi"
18849 [(set (match_operand:V16QI 0 "push_operand" "=<")
18850 (match_operand:V16QI 1 "register_operand" "x"))]
18851 "TARGET_SSE2"
18852 "#")
18853
18854 (define_insn "*pushv4sf"
18855 [(set (match_operand:V4SF 0 "push_operand" "=<")
18856 (match_operand:V4SF 1 "register_operand" "x"))]
18857 "TARGET_SSE"
18858 "#")
18859
18860 (define_insn "*pushv4si"
18861 [(set (match_operand:V4SI 0 "push_operand" "=<")
18862 (match_operand:V4SI 1 "register_operand" "x"))]
18863 "TARGET_SSE2"
18864 "#")
18865
18866 (define_insn "*pushv2si"
18867 [(set (match_operand:V2SI 0 "push_operand" "=<")
18868 (match_operand:V2SI 1 "register_operand" "y"))]
18869 "TARGET_MMX"
18870 "#")
18871
18872 (define_insn "*pushv4hi"
18873 [(set (match_operand:V4HI 0 "push_operand" "=<")
18874 (match_operand:V4HI 1 "register_operand" "y"))]
18875 "TARGET_MMX"
18876 "#")
18877
18878 (define_insn "*pushv8qi"
18879 [(set (match_operand:V8QI 0 "push_operand" "=<")
18880 (match_operand:V8QI 1 "register_operand" "y"))]
18881 "TARGET_MMX"
18882 "#")
18883
18884 (define_insn "*pushv2sf"
18885 [(set (match_operand:V2SF 0 "push_operand" "=<")
18886 (match_operand:V2SF 1 "register_operand" "y"))]
18887 "TARGET_3DNOW"
18888 "#")
18889
18890 (define_split
18891 [(set (match_operand 0 "push_operand" "")
18892 (match_operand 1 "register_operand" ""))]
18893 "!TARGET_64BIT && reload_completed
18894 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18895 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
18896 (set (match_dup 2) (match_dup 1))]
18897 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18898 stack_pointer_rtx);
18899 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18900
18901 (define_split
18902 [(set (match_operand 0 "push_operand" "")
18903 (match_operand 1 "register_operand" ""))]
18904 "TARGET_64BIT && reload_completed
18905 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
18906 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
18907 (set (match_dup 2) (match_dup 1))]
18908 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
18909 stack_pointer_rtx);
18910 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
18911
18912
18913 (define_insn "movti_internal"
18914 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
18915 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
18916 "TARGET_SSE && !TARGET_64BIT
18917 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18918 {
18919 switch (which_alternative)
18920 {
18921 case 0:
18922 if (get_attr_mode (insn) == MODE_V4SF)
18923 return "xorps\t%0, %0";
18924 else
18925 return "pxor\t%0, %0";
18926 case 1:
18927 case 2:
18928 if (get_attr_mode (insn) == MODE_V4SF)
18929 return "movaps\t{%1, %0|%0, %1}";
18930 else
18931 return "movdqa\t{%1, %0|%0, %1}";
18932 default:
18933 abort ();
18934 }
18935 }
18936 [(set_attr "type" "ssemov,ssemov,ssemov")
18937 (set (attr "mode")
18938 (cond [(eq_attr "alternative" "0,1")
18939 (if_then_else
18940 (ne (symbol_ref "optimize_size")
18941 (const_int 0))
18942 (const_string "V4SF")
18943 (const_string "TI"))
18944 (eq_attr "alternative" "2")
18945 (if_then_else
18946 (ne (symbol_ref "optimize_size")
18947 (const_int 0))
18948 (const_string "V4SF")
18949 (const_string "TI"))]
18950 (const_string "TI")))])
18951
18952 (define_insn "*movti_rex64"
18953 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
18954 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
18955 "TARGET_64BIT
18956 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
18957 {
18958 switch (which_alternative)
18959 {
18960 case 0:
18961 case 1:
18962 return "#";
18963 case 2:
18964 if (get_attr_mode (insn) == MODE_V4SF)
18965 return "xorps\t%0, %0";
18966 else
18967 return "pxor\t%0, %0";
18968 case 3:
18969 case 4:
18970 if (get_attr_mode (insn) == MODE_V4SF)
18971 return "movaps\t{%1, %0|%0, %1}";
18972 else
18973 return "movdqa\t{%1, %0|%0, %1}";
18974 default:
18975 abort ();
18976 }
18977 }
18978 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
18979 (set (attr "mode")
18980 (cond [(eq_attr "alternative" "2,3")
18981 (if_then_else
18982 (ne (symbol_ref "optimize_size")
18983 (const_int 0))
18984 (const_string "V4SF")
18985 (const_string "TI"))
18986 (eq_attr "alternative" "4")
18987 (if_then_else
18988 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
18989 (const_int 0))
18990 (ne (symbol_ref "optimize_size")
18991 (const_int 0)))
18992 (const_string "V4SF")
18993 (const_string "TI"))]
18994 (const_string "DI")))])
18995
18996 (define_insn "*movtf_rex64"
18997 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
18998 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
18999 "TARGET_64BIT
19000 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19001 {
19002 switch (which_alternative)
19003 {
19004 case 0:
19005 case 1:
19006 return "#";
19007 case 2:
19008 if (get_attr_mode (insn) == MODE_V4SF)
19009 return "xorps\t%0, %0";
19010 else
19011 return "pxor\t%0, %0";
19012 case 3:
19013 case 4:
19014 if (get_attr_mode (insn) == MODE_V4SF)
19015 return "movaps\t{%1, %0|%0, %1}";
19016 else
19017 return "movdqa\t{%1, %0|%0, %1}";
19018 default:
19019 abort ();
19020 }
19021 }
19022 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19023 (set (attr "mode")
19024 (cond [(eq_attr "alternative" "2,3")
19025 (if_then_else
19026 (ne (symbol_ref "optimize_size")
19027 (const_int 0))
19028 (const_string "V4SF")
19029 (const_string "TI"))
19030 (eq_attr "alternative" "4")
19031 (if_then_else
19032 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19033 (const_int 0))
19034 (ne (symbol_ref "optimize_size")
19035 (const_int 0)))
19036 (const_string "V4SF")
19037 (const_string "TI"))]
19038 (const_string "DI")))])
19039
19040 (define_split
19041 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19042 (match_operand:TI 1 "general_operand" ""))]
19043 "reload_completed && !SSE_REG_P (operands[0])
19044 && !SSE_REG_P (operands[1])"
19045 [(const_int 0)]
19046 "ix86_split_long_move (operands); DONE;")
19047
19048 (define_split
19049 [(set (match_operand:TF 0 "nonimmediate_operand" "")
19050 (match_operand:TF 1 "general_operand" ""))]
19051 "reload_completed && !SSE_REG_P (operands[0])
19052 && !SSE_REG_P (operands[1])"
19053 [(const_int 0)]
19054 "ix86_split_long_move (operands); DONE;")
19055
19056 ;; These two patterns are useful for specifying exactly whether to use
19057 ;; movaps or movups
19058 (define_expand "sse_movaps"
19059 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19060 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19061 UNSPEC_MOVA))]
19062 "TARGET_SSE"
19063 {
19064 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19065 {
19066 rtx tmp = gen_reg_rtx (V4SFmode);
19067 emit_insn (gen_sse_movaps (tmp, operands[1]));
19068 emit_move_insn (operands[0], tmp);
19069 DONE;
19070 }
19071 })
19072
19073 (define_insn "*sse_movaps_1"
19074 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19075 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19076 UNSPEC_MOVA))]
19077 "TARGET_SSE
19078 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19079 "movaps\t{%1, %0|%0, %1}"
19080 [(set_attr "type" "ssemov,ssemov")
19081 (set_attr "mode" "V4SF")])
19082
19083 (define_expand "sse_movups"
19084 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19085 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19086 UNSPEC_MOVU))]
19087 "TARGET_SSE"
19088 {
19089 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19090 {
19091 rtx tmp = gen_reg_rtx (V4SFmode);
19092 emit_insn (gen_sse_movups (tmp, operands[1]));
19093 emit_move_insn (operands[0], tmp);
19094 DONE;
19095 }
19096 })
19097
19098 (define_insn "*sse_movups_1"
19099 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19100 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19101 UNSPEC_MOVU))]
19102 "TARGET_SSE
19103 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19104 "movups\t{%1, %0|%0, %1}"
19105 [(set_attr "type" "ssecvt,ssecvt")
19106 (set_attr "mode" "V4SF")])
19107
19108 ;; SSE Strange Moves.
19109
19110 (define_insn "sse_movmskps"
19111 [(set (match_operand:SI 0 "register_operand" "=r")
19112 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19113 UNSPEC_MOVMSK))]
19114 "TARGET_SSE"
19115 "movmskps\t{%1, %0|%0, %1}"
19116 [(set_attr "type" "ssecvt")
19117 (set_attr "mode" "V4SF")])
19118
19119 (define_insn "mmx_pmovmskb"
19120 [(set (match_operand:SI 0 "register_operand" "=r")
19121 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19122 UNSPEC_MOVMSK))]
19123 "TARGET_SSE || TARGET_3DNOW_A"
19124 "pmovmskb\t{%1, %0|%0, %1}"
19125 [(set_attr "type" "ssecvt")
19126 (set_attr "mode" "V4SF")])
19127
19128
19129 (define_insn "mmx_maskmovq"
19130 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19131 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19132 (match_operand:V8QI 2 "register_operand" "y")]
19133 UNSPEC_MASKMOV))]
19134 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19135 ;; @@@ check ordering of operands in intel/nonintel syntax
19136 "maskmovq\t{%2, %1|%1, %2}"
19137 [(set_attr "type" "mmxcvt")
19138 (set_attr "mode" "DI")])
19139
19140 (define_insn "mmx_maskmovq_rex"
19141 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19142 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19143 (match_operand:V8QI 2 "register_operand" "y")]
19144 UNSPEC_MASKMOV))]
19145 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19146 ;; @@@ check ordering of operands in intel/nonintel syntax
19147 "maskmovq\t{%2, %1|%1, %2}"
19148 [(set_attr "type" "mmxcvt")
19149 (set_attr "mode" "DI")])
19150
19151 (define_insn "sse_movntv4sf"
19152 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19153 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19154 UNSPEC_MOVNT))]
19155 "TARGET_SSE"
19156 "movntps\t{%1, %0|%0, %1}"
19157 [(set_attr "type" "ssemov")
19158 (set_attr "mode" "V4SF")])
19159
19160 (define_insn "sse_movntdi"
19161 [(set (match_operand:DI 0 "memory_operand" "=m")
19162 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19163 UNSPEC_MOVNT))]
19164 "TARGET_SSE || TARGET_3DNOW_A"
19165 "movntq\t{%1, %0|%0, %1}"
19166 [(set_attr "type" "mmxmov")
19167 (set_attr "mode" "DI")])
19168
19169 (define_insn "sse_movhlps"
19170 [(set (match_operand:V4SF 0 "register_operand" "=x")
19171 (vec_merge:V4SF
19172 (match_operand:V4SF 1 "register_operand" "0")
19173 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19174 (parallel [(const_int 2)
19175 (const_int 3)
19176 (const_int 0)
19177 (const_int 1)]))
19178 (const_int 3)))]
19179 "TARGET_SSE"
19180 "movhlps\t{%2, %0|%0, %2}"
19181 [(set_attr "type" "ssecvt")
19182 (set_attr "mode" "V4SF")])
19183
19184 (define_insn "sse_movlhps"
19185 [(set (match_operand:V4SF 0 "register_operand" "=x")
19186 (vec_merge:V4SF
19187 (match_operand:V4SF 1 "register_operand" "0")
19188 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19189 (parallel [(const_int 2)
19190 (const_int 3)
19191 (const_int 0)
19192 (const_int 1)]))
19193 (const_int 12)))]
19194 "TARGET_SSE"
19195 "movlhps\t{%2, %0|%0, %2}"
19196 [(set_attr "type" "ssecvt")
19197 (set_attr "mode" "V4SF")])
19198
19199 (define_insn "sse_movhps"
19200 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19201 (vec_merge:V4SF
19202 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19203 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19204 (const_int 12)))]
19205 "TARGET_SSE
19206 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19207 "movhps\t{%2, %0|%0, %2}"
19208 [(set_attr "type" "ssecvt")
19209 (set_attr "mode" "V4SF")])
19210
19211 (define_insn "sse_movlps"
19212 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19213 (vec_merge:V4SF
19214 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19215 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19216 (const_int 3)))]
19217 "TARGET_SSE
19218 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19219 "movlps\t{%2, %0|%0, %2}"
19220 [(set_attr "type" "ssecvt")
19221 (set_attr "mode" "V4SF")])
19222
19223 (define_expand "sse_loadss"
19224 [(match_operand:V4SF 0 "register_operand" "")
19225 (match_operand:SF 1 "memory_operand" "")]
19226 "TARGET_SSE"
19227 {
19228 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19229 CONST0_RTX (V4SFmode)));
19230 DONE;
19231 })
19232
19233 (define_insn "sse_loadss_1"
19234 [(set (match_operand:V4SF 0 "register_operand" "=x")
19235 (vec_merge:V4SF
19236 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19237 (match_operand:V4SF 2 "const0_operand" "X")
19238 (const_int 1)))]
19239 "TARGET_SSE"
19240 "movss\t{%1, %0|%0, %1}"
19241 [(set_attr "type" "ssemov")
19242 (set_attr "mode" "SF")])
19243
19244 (define_insn "sse_movss"
19245 [(set (match_operand:V4SF 0 "register_operand" "=x")
19246 (vec_merge:V4SF
19247 (match_operand:V4SF 1 "register_operand" "0")
19248 (match_operand:V4SF 2 "register_operand" "x")
19249 (const_int 1)))]
19250 "TARGET_SSE"
19251 "movss\t{%2, %0|%0, %2}"
19252 [(set_attr "type" "ssemov")
19253 (set_attr "mode" "SF")])
19254
19255 (define_insn "sse_storess"
19256 [(set (match_operand:SF 0 "memory_operand" "=m")
19257 (vec_select:SF
19258 (match_operand:V4SF 1 "register_operand" "x")
19259 (parallel [(const_int 0)])))]
19260 "TARGET_SSE"
19261 "movss\t{%1, %0|%0, %1}"
19262 [(set_attr "type" "ssemov")
19263 (set_attr "mode" "SF")])
19264
19265 (define_insn "sse_shufps"
19266 [(set (match_operand:V4SF 0 "register_operand" "=x")
19267 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19268 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19269 (match_operand:SI 3 "immediate_operand" "i")]
19270 UNSPEC_SHUFFLE))]
19271 "TARGET_SSE"
19272 ;; @@@ check operand order for intel/nonintel syntax
19273 "shufps\t{%3, %2, %0|%0, %2, %3}"
19274 [(set_attr "type" "ssecvt")
19275 (set_attr "mode" "V4SF")])
19276
19277
19278 ;; SSE arithmetic
19279
19280 (define_insn "addv4sf3"
19281 [(set (match_operand:V4SF 0 "register_operand" "=x")
19282 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19283 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19284 "TARGET_SSE"
19285 "addps\t{%2, %0|%0, %2}"
19286 [(set_attr "type" "sseadd")
19287 (set_attr "mode" "V4SF")])
19288
19289 (define_insn "vmaddv4sf3"
19290 [(set (match_operand:V4SF 0 "register_operand" "=x")
19291 (vec_merge:V4SF
19292 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19293 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19294 (match_dup 1)
19295 (const_int 1)))]
19296 "TARGET_SSE"
19297 "addss\t{%2, %0|%0, %2}"
19298 [(set_attr "type" "sseadd")
19299 (set_attr "mode" "SF")])
19300
19301 (define_insn "subv4sf3"
19302 [(set (match_operand:V4SF 0 "register_operand" "=x")
19303 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19304 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19305 "TARGET_SSE"
19306 "subps\t{%2, %0|%0, %2}"
19307 [(set_attr "type" "sseadd")
19308 (set_attr "mode" "V4SF")])
19309
19310 (define_insn "vmsubv4sf3"
19311 [(set (match_operand:V4SF 0 "register_operand" "=x")
19312 (vec_merge:V4SF
19313 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19314 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19315 (match_dup 1)
19316 (const_int 1)))]
19317 "TARGET_SSE"
19318 "subss\t{%2, %0|%0, %2}"
19319 [(set_attr "type" "sseadd")
19320 (set_attr "mode" "SF")])
19321
19322 (define_insn "mulv4sf3"
19323 [(set (match_operand:V4SF 0 "register_operand" "=x")
19324 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19325 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19326 "TARGET_SSE"
19327 "mulps\t{%2, %0|%0, %2}"
19328 [(set_attr "type" "ssemul")
19329 (set_attr "mode" "V4SF")])
19330
19331 (define_insn "vmmulv4sf3"
19332 [(set (match_operand:V4SF 0 "register_operand" "=x")
19333 (vec_merge:V4SF
19334 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19335 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19336 (match_dup 1)
19337 (const_int 1)))]
19338 "TARGET_SSE"
19339 "mulss\t{%2, %0|%0, %2}"
19340 [(set_attr "type" "ssemul")
19341 (set_attr "mode" "SF")])
19342
19343 (define_insn "divv4sf3"
19344 [(set (match_operand:V4SF 0 "register_operand" "=x")
19345 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19346 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19347 "TARGET_SSE"
19348 "divps\t{%2, %0|%0, %2}"
19349 [(set_attr "type" "ssediv")
19350 (set_attr "mode" "V4SF")])
19351
19352 (define_insn "vmdivv4sf3"
19353 [(set (match_operand:V4SF 0 "register_operand" "=x")
19354 (vec_merge:V4SF
19355 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19356 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19357 (match_dup 1)
19358 (const_int 1)))]
19359 "TARGET_SSE"
19360 "divss\t{%2, %0|%0, %2}"
19361 [(set_attr "type" "ssediv")
19362 (set_attr "mode" "SF")])
19363
19364
19365 ;; SSE square root/reciprocal
19366
19367 (define_insn "rcpv4sf2"
19368 [(set (match_operand:V4SF 0 "register_operand" "=x")
19369 (unspec:V4SF
19370 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19371 "TARGET_SSE"
19372 "rcpps\t{%1, %0|%0, %1}"
19373 [(set_attr "type" "sse")
19374 (set_attr "mode" "V4SF")])
19375
19376 (define_insn "vmrcpv4sf2"
19377 [(set (match_operand:V4SF 0 "register_operand" "=x")
19378 (vec_merge:V4SF
19379 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19380 UNSPEC_RCP)
19381 (match_operand:V4SF 2 "register_operand" "0")
19382 (const_int 1)))]
19383 "TARGET_SSE"
19384 "rcpss\t{%1, %0|%0, %1}"
19385 [(set_attr "type" "sse")
19386 (set_attr "mode" "SF")])
19387
19388 (define_insn "rsqrtv4sf2"
19389 [(set (match_operand:V4SF 0 "register_operand" "=x")
19390 (unspec:V4SF
19391 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19392 "TARGET_SSE"
19393 "rsqrtps\t{%1, %0|%0, %1}"
19394 [(set_attr "type" "sse")
19395 (set_attr "mode" "V4SF")])
19396
19397 (define_insn "vmrsqrtv4sf2"
19398 [(set (match_operand:V4SF 0 "register_operand" "=x")
19399 (vec_merge:V4SF
19400 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19401 UNSPEC_RSQRT)
19402 (match_operand:V4SF 2 "register_operand" "0")
19403 (const_int 1)))]
19404 "TARGET_SSE"
19405 "rsqrtss\t{%1, %0|%0, %1}"
19406 [(set_attr "type" "sse")
19407 (set_attr "mode" "SF")])
19408
19409 (define_insn "sqrtv4sf2"
19410 [(set (match_operand:V4SF 0 "register_operand" "=x")
19411 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19412 "TARGET_SSE"
19413 "sqrtps\t{%1, %0|%0, %1}"
19414 [(set_attr "type" "sse")
19415 (set_attr "mode" "V4SF")])
19416
19417 (define_insn "vmsqrtv4sf2"
19418 [(set (match_operand:V4SF 0 "register_operand" "=x")
19419 (vec_merge:V4SF
19420 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19421 (match_operand:V4SF 2 "register_operand" "0")
19422 (const_int 1)))]
19423 "TARGET_SSE"
19424 "sqrtss\t{%1, %0|%0, %1}"
19425 [(set_attr "type" "sse")
19426 (set_attr "mode" "SF")])
19427
19428 ;; SSE logical operations.
19429
19430 ;; SSE defines logical operations on floating point values. This brings
19431 ;; interesting challenge to RTL representation where logicals are only valid
19432 ;; on integral types. We deal with this by representing the floating point
19433 ;; logical as logical on arguments casted to TImode as this is what hardware
19434 ;; really does. Unfortunately hardware requires the type information to be
19435 ;; present and thus we must avoid subregs from being simplified and eliminated
19436 ;; in later compilation phases.
19437 ;;
19438 ;; We have following variants from each instruction:
19439 ;; sse_andsf3 - the operation taking V4SF vector operands
19440 ;; and doing TImode cast on them
19441 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19442 ;; TImode, since backend insist on eliminating casts
19443 ;; on memory operands
19444 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19445 ;; We can not accept memory operand here as instruction reads
19446 ;; whole scalar. This is generated only post reload by GCC
19447 ;; scalar float operations that expands to logicals (fabs)
19448 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19449 ;; memory operand. Eventually combine can be able
19450 ;; to synthesize these using splitter.
19451 ;; sse2_anddf3, *sse2_anddf3_memory
19452 ;;
19453 ;;
19454 ;; These are not called andti3 etc. because we really really don't want
19455 ;; the compiler to widen DImode ands to TImode ands and then try to move
19456 ;; into DImode subregs of SSE registers, and them together, and move out
19457 ;; of DImode subregs again!
19458 ;; SSE1 single precision floating point logical operation
19459 (define_expand "sse_andv4sf3"
19460 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19461 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19462 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19463 "TARGET_SSE"
19464 "")
19465
19466 (define_insn "*sse_andv4sf3"
19467 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19468 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19469 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19470 "TARGET_SSE
19471 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19472 "andps\t{%2, %0|%0, %2}"
19473 [(set_attr "type" "sselog")
19474 (set_attr "mode" "V4SF")])
19475
19476 (define_insn "*sse_andsf3"
19477 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19478 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19479 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19480 "TARGET_SSE
19481 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19482 "andps\t{%2, %0|%0, %2}"
19483 [(set_attr "type" "sselog")
19484 (set_attr "mode" "V4SF")])
19485
19486 (define_expand "sse_nandv4sf3"
19487 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19488 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19489 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19490 "TARGET_SSE"
19491 "")
19492
19493 (define_insn "*sse_nandv4sf3"
19494 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19495 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19496 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19497 "TARGET_SSE"
19498 "andnps\t{%2, %0|%0, %2}"
19499 [(set_attr "type" "sselog")
19500 (set_attr "mode" "V4SF")])
19501
19502 (define_insn "*sse_nandsf3"
19503 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19504 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19505 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19506 "TARGET_SSE"
19507 "andnps\t{%2, %0|%0, %2}"
19508 [(set_attr "type" "sselog")
19509 (set_attr "mode" "V4SF")])
19510
19511 (define_expand "sse_iorv4sf3"
19512 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19513 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19514 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19515 "TARGET_SSE"
19516 "")
19517
19518 (define_insn "*sse_iorv4sf3"
19519 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19520 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19521 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19522 "TARGET_SSE
19523 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19524 "orps\t{%2, %0|%0, %2}"
19525 [(set_attr "type" "sselog")
19526 (set_attr "mode" "V4SF")])
19527
19528 (define_insn "*sse_iorsf3"
19529 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19530 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19531 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19532 "TARGET_SSE
19533 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19534 "orps\t{%2, %0|%0, %2}"
19535 [(set_attr "type" "sselog")
19536 (set_attr "mode" "V4SF")])
19537
19538 (define_expand "sse_xorv4sf3"
19539 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19540 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19541 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19542 "TARGET_SSE
19543 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19544 "")
19545
19546 (define_insn "*sse_xorv4sf3"
19547 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19548 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19549 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19550 "TARGET_SSE
19551 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19552 "xorps\t{%2, %0|%0, %2}"
19553 [(set_attr "type" "sselog")
19554 (set_attr "mode" "V4SF")])
19555
19556 (define_insn "*sse_xorsf3"
19557 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19558 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19559 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19560 "TARGET_SSE
19561 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19562 "xorps\t{%2, %0|%0, %2}"
19563 [(set_attr "type" "sselog")
19564 (set_attr "mode" "V4SF")])
19565
19566 ;; SSE2 double precision floating point logical operation
19567
19568 (define_expand "sse2_andv2df3"
19569 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19570 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19571 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19572 "TARGET_SSE2"
19573 "")
19574
19575 (define_insn "*sse2_andv2df3"
19576 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19577 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19578 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19579 "TARGET_SSE2
19580 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19581 "andpd\t{%2, %0|%0, %2}"
19582 [(set_attr "type" "sselog")
19583 (set_attr "mode" "V2DF")])
19584
19585 (define_insn "*sse2_andv2df3"
19586 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19587 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19588 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19589 "TARGET_SSE2
19590 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19591 "andpd\t{%2, %0|%0, %2}"
19592 [(set_attr "type" "sselog")
19593 (set_attr "mode" "V2DF")])
19594
19595 (define_expand "sse2_nandv2df3"
19596 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19597 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
19598 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19599 "TARGET_SSE2"
19600 "")
19601
19602 (define_insn "*sse2_nandv2df3"
19603 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19604 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19605 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19606 "TARGET_SSE2"
19607 "andnpd\t{%2, %0|%0, %2}"
19608 [(set_attr "type" "sselog")
19609 (set_attr "mode" "V2DF")])
19610
19611 (define_insn "*sse_nandti3_df"
19612 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
19613 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19614 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
19615 "TARGET_SSE2"
19616 "andnpd\t{%2, %0|%0, %2}"
19617 [(set_attr "type" "sselog")
19618 (set_attr "mode" "V2DF")])
19619
19620 (define_expand "sse2_iorv2df3"
19621 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19622 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
19623 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19624 "TARGET_SSE2"
19625 "")
19626
19627 (define_insn "*sse2_iorv2df3"
19628 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19629 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19630 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19631 "TARGET_SSE2
19632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19633 "orpd\t{%2, %0|%0, %2}"
19634 [(set_attr "type" "sselog")
19635 (set_attr "mode" "V2DF")])
19636
19637 (define_insn "*sse2_iordf3"
19638 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19639 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19640 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19641 "TARGET_SSE2
19642 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19643 "orpd\t{%2, %0|%0, %2}"
19644 [(set_attr "type" "sselog")
19645 (set_attr "mode" "V2DF")])
19646
19647 (define_expand "sse2_xorv2df3"
19648 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
19649 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
19650 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
19651 "TARGET_SSE2"
19652 "")
19653
19654 (define_insn "*sse2_xorv2df3"
19655 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
19656 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19657 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19658 "TARGET_SSE2
19659 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19660 "xorpd\t{%2, %0|%0, %2}"
19661 [(set_attr "type" "sselog")
19662 (set_attr "mode" "V2DF")])
19663
19664 (define_insn "*sse2_xordf3"
19665 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
19666 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19667 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19668 "TARGET_SSE2
19669 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19670 "xorpd\t{%2, %0|%0, %2}"
19671 [(set_attr "type" "sselog")
19672 (set_attr "mode" "V2DF")])
19673
19674 ;; SSE2 integral logicals. These patterns must always come after floating
19675 ;; point ones since we don't want compiler to use integer opcodes on floating
19676 ;; point SSE values to avoid matching of subregs in the match_operand.
19677 (define_insn "*sse2_andti3"
19678 [(set (match_operand:TI 0 "register_operand" "=x")
19679 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19680 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19681 "TARGET_SSE2
19682 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19683 "pand\t{%2, %0|%0, %2}"
19684 [(set_attr "type" "sselog")
19685 (set_attr "mode" "TI")])
19686
19687 (define_insn "sse2_andv2di3"
19688 [(set (match_operand:V2DI 0 "register_operand" "=x")
19689 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19690 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19691 "TARGET_SSE2
19692 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19693 "pand\t{%2, %0|%0, %2}"
19694 [(set_attr "type" "sselog")
19695 (set_attr "mode" "TI")])
19696
19697 (define_insn "*sse2_nandti3"
19698 [(set (match_operand:TI 0 "register_operand" "=x")
19699 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19700 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19701 "TARGET_SSE2"
19702 "pandn\t{%2, %0|%0, %2}"
19703 [(set_attr "type" "sselog")
19704 (set_attr "mode" "TI")])
19705
19706 (define_insn "sse2_nandv2di3"
19707 [(set (match_operand:V2DI 0 "register_operand" "=x")
19708 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
19709 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19710 "TARGET_SSE2
19711 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19712 "pandn\t{%2, %0|%0, %2}"
19713 [(set_attr "type" "sselog")
19714 (set_attr "mode" "TI")])
19715
19716 (define_insn "*sse2_iorti3"
19717 [(set (match_operand:TI 0 "register_operand" "=x")
19718 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19719 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19720 "TARGET_SSE2
19721 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19722 "por\t{%2, %0|%0, %2}"
19723 [(set_attr "type" "sselog")
19724 (set_attr "mode" "TI")])
19725
19726 (define_insn "sse2_iorv2di3"
19727 [(set (match_operand:V2DI 0 "register_operand" "=x")
19728 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19729 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19730 "TARGET_SSE2
19731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19732 "por\t{%2, %0|%0, %2}"
19733 [(set_attr "type" "sselog")
19734 (set_attr "mode" "TI")])
19735
19736 (define_insn "*sse2_xorti3"
19737 [(set (match_operand:TI 0 "register_operand" "=x")
19738 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19739 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19740 "TARGET_SSE2
19741 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19742 "pxor\t{%2, %0|%0, %2}"
19743 [(set_attr "type" "sselog")
19744 (set_attr "mode" "TI")])
19745
19746 (define_insn "sse2_xorv2di3"
19747 [(set (match_operand:V2DI 0 "register_operand" "=x")
19748 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
19749 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
19750 "TARGET_SSE2
19751 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19752 "pxor\t{%2, %0|%0, %2}"
19753 [(set_attr "type" "sselog")
19754 (set_attr "mode" "TI")])
19755
19756 ;; Use xor, but don't show input operands so they aren't live before
19757 ;; this insn.
19758 (define_insn "sse_clrv4sf"
19759 [(set (match_operand:V4SF 0 "register_operand" "=x")
19760 (match_operand:V4SF 1 "const0_operand" "X"))]
19761 "TARGET_SSE"
19762 {
19763 if (get_attr_mode (insn) == MODE_TI)
19764 return "pxor\t{%0, %0|%0, %0}";
19765 else
19766 return "xorps\t{%0, %0|%0, %0}";
19767 }
19768 [(set_attr "type" "sselog")
19769 (set_attr "memory" "none")
19770 (set (attr "mode")
19771 (if_then_else
19772 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
19773 (const_int 0))
19774 (ne (symbol_ref "TARGET_SSE2")
19775 (const_int 0)))
19776 (eq (symbol_ref "optimize_size")
19777 (const_int 0)))
19778 (const_string "TI")
19779 (const_string "V4SF")))])
19780
19781 ;; Use xor, but don't show input operands so they aren't live before
19782 ;; this insn.
19783 (define_insn "sse_clrv2df"
19784 [(set (match_operand:V2DF 0 "register_operand" "=x")
19785 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
19786 "TARGET_SSE2"
19787 "xorpd\t{%0, %0|%0, %0}"
19788 [(set_attr "type" "sselog")
19789 (set_attr "memory" "none")
19790 (set_attr "mode" "V4SF")])
19791
19792 ;; SSE mask-generating compares
19793
19794 (define_insn "maskcmpv4sf3"
19795 [(set (match_operand:V4SI 0 "register_operand" "=x")
19796 (match_operator:V4SI 3 "sse_comparison_operator"
19797 [(match_operand:V4SF 1 "register_operand" "0")
19798 (match_operand:V4SF 2 "register_operand" "x")]))]
19799 "TARGET_SSE"
19800 "cmp%D3ps\t{%2, %0|%0, %2}"
19801 [(set_attr "type" "ssecmp")
19802 (set_attr "mode" "V4SF")])
19803
19804 (define_insn "maskncmpv4sf3"
19805 [(set (match_operand:V4SI 0 "register_operand" "=x")
19806 (not:V4SI
19807 (match_operator:V4SI 3 "sse_comparison_operator"
19808 [(match_operand:V4SF 1 "register_operand" "0")
19809 (match_operand:V4SF 2 "register_operand" "x")])))]
19810 "TARGET_SSE"
19811 {
19812 if (GET_CODE (operands[3]) == UNORDERED)
19813 return "cmpordps\t{%2, %0|%0, %2}";
19814 else
19815 return "cmpn%D3ps\t{%2, %0|%0, %2}";
19816 }
19817 [(set_attr "type" "ssecmp")
19818 (set_attr "mode" "V4SF")])
19819
19820 (define_insn "vmmaskcmpv4sf3"
19821 [(set (match_operand:V4SI 0 "register_operand" "=x")
19822 (vec_merge:V4SI
19823 (match_operator:V4SI 3 "sse_comparison_operator"
19824 [(match_operand:V4SF 1 "register_operand" "0")
19825 (match_operand:V4SF 2 "register_operand" "x")])
19826 (subreg:V4SI (match_dup 1) 0)
19827 (const_int 1)))]
19828 "TARGET_SSE"
19829 "cmp%D3ss\t{%2, %0|%0, %2}"
19830 [(set_attr "type" "ssecmp")
19831 (set_attr "mode" "SF")])
19832
19833 (define_insn "vmmaskncmpv4sf3"
19834 [(set (match_operand:V4SI 0 "register_operand" "=x")
19835 (vec_merge:V4SI
19836 (not:V4SI
19837 (match_operator:V4SI 3 "sse_comparison_operator"
19838 [(match_operand:V4SF 1 "register_operand" "0")
19839 (match_operand:V4SF 2 "register_operand" "x")]))
19840 (subreg:V4SI (match_dup 1) 0)
19841 (const_int 1)))]
19842 "TARGET_SSE"
19843 {
19844 if (GET_CODE (operands[3]) == UNORDERED)
19845 return "cmpordss\t{%2, %0|%0, %2}";
19846 else
19847 return "cmpn%D3ss\t{%2, %0|%0, %2}";
19848 }
19849 [(set_attr "type" "ssecmp")
19850 (set_attr "mode" "SF")])
19851
19852 (define_insn "sse_comi"
19853 [(set (reg:CCFP 17)
19854 (compare:CCFP (vec_select:SF
19855 (match_operand:V4SF 0 "register_operand" "x")
19856 (parallel [(const_int 0)]))
19857 (vec_select:SF
19858 (match_operand:V4SF 1 "register_operand" "x")
19859 (parallel [(const_int 0)]))))]
19860 "TARGET_SSE"
19861 "comiss\t{%1, %0|%0, %1}"
19862 [(set_attr "type" "ssecomi")
19863 (set_attr "mode" "SF")])
19864
19865 (define_insn "sse_ucomi"
19866 [(set (reg:CCFPU 17)
19867 (compare:CCFPU (vec_select:SF
19868 (match_operand:V4SF 0 "register_operand" "x")
19869 (parallel [(const_int 0)]))
19870 (vec_select:SF
19871 (match_operand:V4SF 1 "register_operand" "x")
19872 (parallel [(const_int 0)]))))]
19873 "TARGET_SSE"
19874 "ucomiss\t{%1, %0|%0, %1}"
19875 [(set_attr "type" "ssecomi")
19876 (set_attr "mode" "SF")])
19877
19878
19879 ;; SSE unpack
19880
19881 (define_insn "sse_unpckhps"
19882 [(set (match_operand:V4SF 0 "register_operand" "=x")
19883 (vec_merge:V4SF
19884 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19885 (parallel [(const_int 2)
19886 (const_int 0)
19887 (const_int 3)
19888 (const_int 1)]))
19889 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19890 (parallel [(const_int 0)
19891 (const_int 2)
19892 (const_int 1)
19893 (const_int 3)]))
19894 (const_int 5)))]
19895 "TARGET_SSE"
19896 "unpckhps\t{%2, %0|%0, %2}"
19897 [(set_attr "type" "ssecvt")
19898 (set_attr "mode" "V4SF")])
19899
19900 (define_insn "sse_unpcklps"
19901 [(set (match_operand:V4SF 0 "register_operand" "=x")
19902 (vec_merge:V4SF
19903 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
19904 (parallel [(const_int 0)
19905 (const_int 2)
19906 (const_int 1)
19907 (const_int 3)]))
19908 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19909 (parallel [(const_int 2)
19910 (const_int 0)
19911 (const_int 3)
19912 (const_int 1)]))
19913 (const_int 5)))]
19914 "TARGET_SSE"
19915 "unpcklps\t{%2, %0|%0, %2}"
19916 [(set_attr "type" "ssecvt")
19917 (set_attr "mode" "V4SF")])
19918
19919
19920 ;; SSE min/max
19921
19922 (define_insn "smaxv4sf3"
19923 [(set (match_operand:V4SF 0 "register_operand" "=x")
19924 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19925 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19926 "TARGET_SSE"
19927 "maxps\t{%2, %0|%0, %2}"
19928 [(set_attr "type" "sse")
19929 (set_attr "mode" "V4SF")])
19930
19931 (define_insn "vmsmaxv4sf3"
19932 [(set (match_operand:V4SF 0 "register_operand" "=x")
19933 (vec_merge:V4SF
19934 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
19935 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19936 (match_dup 1)
19937 (const_int 1)))]
19938 "TARGET_SSE"
19939 "maxss\t{%2, %0|%0, %2}"
19940 [(set_attr "type" "sse")
19941 (set_attr "mode" "SF")])
19942
19943 (define_insn "sminv4sf3"
19944 [(set (match_operand:V4SF 0 "register_operand" "=x")
19945 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19946 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19947 "TARGET_SSE"
19948 "minps\t{%2, %0|%0, %2}"
19949 [(set_attr "type" "sse")
19950 (set_attr "mode" "V4SF")])
19951
19952 (define_insn "vmsminv4sf3"
19953 [(set (match_operand:V4SF 0 "register_operand" "=x")
19954 (vec_merge:V4SF
19955 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
19956 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19957 (match_dup 1)
19958 (const_int 1)))]
19959 "TARGET_SSE"
19960 "minss\t{%2, %0|%0, %2}"
19961 [(set_attr "type" "sse")
19962 (set_attr "mode" "SF")])
19963
19964 ;; SSE <-> integer/MMX conversions
19965
19966 (define_insn "cvtpi2ps"
19967 [(set (match_operand:V4SF 0 "register_operand" "=x")
19968 (vec_merge:V4SF
19969 (match_operand:V4SF 1 "register_operand" "0")
19970 (vec_duplicate:V4SF
19971 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
19972 (const_int 12)))]
19973 "TARGET_SSE"
19974 "cvtpi2ps\t{%2, %0|%0, %2}"
19975 [(set_attr "type" "ssecvt")
19976 (set_attr "mode" "V4SF")])
19977
19978 (define_insn "cvtps2pi"
19979 [(set (match_operand:V2SI 0 "register_operand" "=y")
19980 (vec_select:V2SI
19981 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19982 (parallel [(const_int 0) (const_int 1)])))]
19983 "TARGET_SSE"
19984 "cvtps2pi\t{%1, %0|%0, %1}"
19985 [(set_attr "type" "ssecvt")
19986 (set_attr "mode" "V4SF")])
19987
19988 (define_insn "cvttps2pi"
19989 [(set (match_operand:V2SI 0 "register_operand" "=y")
19990 (vec_select:V2SI
19991 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19992 UNSPEC_FIX)
19993 (parallel [(const_int 0) (const_int 1)])))]
19994 "TARGET_SSE"
19995 "cvttps2pi\t{%1, %0|%0, %1}"
19996 [(set_attr "type" "ssecvt")
19997 (set_attr "mode" "SF")])
19998
19999 (define_insn "cvtsi2ss"
20000 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20001 (vec_merge:V4SF
20002 (match_operand:V4SF 1 "register_operand" "0,0")
20003 (vec_duplicate:V4SF
20004 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20005 (const_int 14)))]
20006 "TARGET_SSE"
20007 "cvtsi2ss\t{%2, %0|%0, %2}"
20008 [(set_attr "type" "sseicvt")
20009 (set_attr "athlon_decode" "vector,double")
20010 (set_attr "mode" "SF")])
20011
20012 (define_insn "cvtsi2ssq"
20013 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20014 (vec_merge:V4SF
20015 (match_operand:V4SF 1 "register_operand" "0,0")
20016 (vec_duplicate:V4SF
20017 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20018 (const_int 14)))]
20019 "TARGET_SSE && TARGET_64BIT"
20020 "cvtsi2ssq\t{%2, %0|%0, %2}"
20021 [(set_attr "type" "sseicvt")
20022 (set_attr "athlon_decode" "vector,double")
20023 (set_attr "mode" "SF")])
20024
20025 (define_insn "cvtss2si"
20026 [(set (match_operand:SI 0 "register_operand" "=r,r")
20027 (vec_select:SI
20028 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20029 (parallel [(const_int 0)])))]
20030 "TARGET_SSE"
20031 "cvtss2si\t{%1, %0|%0, %1}"
20032 [(set_attr "type" "sseicvt")
20033 (set_attr "athlon_decode" "double,vector")
20034 (set_attr "mode" "SI")])
20035
20036 (define_insn "cvtss2siq"
20037 [(set (match_operand:DI 0 "register_operand" "=r,r")
20038 (vec_select:DI
20039 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20040 (parallel [(const_int 0)])))]
20041 "TARGET_SSE"
20042 "cvtss2siq\t{%1, %0|%0, %1}"
20043 [(set_attr "type" "sseicvt")
20044 (set_attr "athlon_decode" "double,vector")
20045 (set_attr "mode" "DI")])
20046
20047 (define_insn "cvttss2si"
20048 [(set (match_operand:SI 0 "register_operand" "=r,r")
20049 (vec_select:SI
20050 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20051 UNSPEC_FIX)
20052 (parallel [(const_int 0)])))]
20053 "TARGET_SSE"
20054 "cvttss2si\t{%1, %0|%0, %1}"
20055 [(set_attr "type" "sseicvt")
20056 (set_attr "mode" "SF")
20057 (set_attr "athlon_decode" "double,vector")])
20058
20059 (define_insn "cvttss2siq"
20060 [(set (match_operand:DI 0 "register_operand" "=r,r")
20061 (vec_select:DI
20062 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20063 UNSPEC_FIX)
20064 (parallel [(const_int 0)])))]
20065 "TARGET_SSE && TARGET_64BIT"
20066 "cvttss2siq\t{%1, %0|%0, %1}"
20067 [(set_attr "type" "sseicvt")
20068 (set_attr "mode" "SF")
20069 (set_attr "athlon_decode" "double,vector")])
20070
20071
20072 ;; MMX insns
20073
20074 ;; MMX arithmetic
20075
20076 (define_insn "addv8qi3"
20077 [(set (match_operand:V8QI 0 "register_operand" "=y")
20078 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20079 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20080 "TARGET_MMX"
20081 "paddb\t{%2, %0|%0, %2}"
20082 [(set_attr "type" "mmxadd")
20083 (set_attr "mode" "DI")])
20084
20085 (define_insn "addv4hi3"
20086 [(set (match_operand:V4HI 0 "register_operand" "=y")
20087 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20088 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20089 "TARGET_MMX"
20090 "paddw\t{%2, %0|%0, %2}"
20091 [(set_attr "type" "mmxadd")
20092 (set_attr "mode" "DI")])
20093
20094 (define_insn "addv2si3"
20095 [(set (match_operand:V2SI 0 "register_operand" "=y")
20096 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20097 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20098 "TARGET_MMX"
20099 "paddd\t{%2, %0|%0, %2}"
20100 [(set_attr "type" "mmxadd")
20101 (set_attr "mode" "DI")])
20102
20103 (define_insn "mmx_adddi3"
20104 [(set (match_operand:DI 0 "register_operand" "=y")
20105 (unspec:DI
20106 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20107 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20108 UNSPEC_NOP))]
20109 "TARGET_MMX"
20110 "paddq\t{%2, %0|%0, %2}"
20111 [(set_attr "type" "mmxadd")
20112 (set_attr "mode" "DI")])
20113
20114 (define_insn "ssaddv8qi3"
20115 [(set (match_operand:V8QI 0 "register_operand" "=y")
20116 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20117 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20118 "TARGET_MMX"
20119 "paddsb\t{%2, %0|%0, %2}"
20120 [(set_attr "type" "mmxadd")
20121 (set_attr "mode" "DI")])
20122
20123 (define_insn "ssaddv4hi3"
20124 [(set (match_operand:V4HI 0 "register_operand" "=y")
20125 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20126 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20127 "TARGET_MMX"
20128 "paddsw\t{%2, %0|%0, %2}"
20129 [(set_attr "type" "mmxadd")
20130 (set_attr "mode" "DI")])
20131
20132 (define_insn "usaddv8qi3"
20133 [(set (match_operand:V8QI 0 "register_operand" "=y")
20134 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20135 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20136 "TARGET_MMX"
20137 "paddusb\t{%2, %0|%0, %2}"
20138 [(set_attr "type" "mmxadd")
20139 (set_attr "mode" "DI")])
20140
20141 (define_insn "usaddv4hi3"
20142 [(set (match_operand:V4HI 0 "register_operand" "=y")
20143 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20144 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20145 "TARGET_MMX"
20146 "paddusw\t{%2, %0|%0, %2}"
20147 [(set_attr "type" "mmxadd")
20148 (set_attr "mode" "DI")])
20149
20150 (define_insn "subv8qi3"
20151 [(set (match_operand:V8QI 0 "register_operand" "=y")
20152 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20153 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20154 "TARGET_MMX"
20155 "psubb\t{%2, %0|%0, %2}"
20156 [(set_attr "type" "mmxadd")
20157 (set_attr "mode" "DI")])
20158
20159 (define_insn "subv4hi3"
20160 [(set (match_operand:V4HI 0 "register_operand" "=y")
20161 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20162 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20163 "TARGET_MMX"
20164 "psubw\t{%2, %0|%0, %2}"
20165 [(set_attr "type" "mmxadd")
20166 (set_attr "mode" "DI")])
20167
20168 (define_insn "subv2si3"
20169 [(set (match_operand:V2SI 0 "register_operand" "=y")
20170 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20171 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20172 "TARGET_MMX"
20173 "psubd\t{%2, %0|%0, %2}"
20174 [(set_attr "type" "mmxadd")
20175 (set_attr "mode" "DI")])
20176
20177 (define_insn "mmx_subdi3"
20178 [(set (match_operand:DI 0 "register_operand" "=y")
20179 (unspec:DI
20180 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20181 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20182 UNSPEC_NOP))]
20183 "TARGET_MMX"
20184 "psubq\t{%2, %0|%0, %2}"
20185 [(set_attr "type" "mmxadd")
20186 (set_attr "mode" "DI")])
20187
20188 (define_insn "sssubv8qi3"
20189 [(set (match_operand:V8QI 0 "register_operand" "=y")
20190 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20191 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20192 "TARGET_MMX"
20193 "psubsb\t{%2, %0|%0, %2}"
20194 [(set_attr "type" "mmxadd")
20195 (set_attr "mode" "DI")])
20196
20197 (define_insn "sssubv4hi3"
20198 [(set (match_operand:V4HI 0 "register_operand" "=y")
20199 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20200 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20201 "TARGET_MMX"
20202 "psubsw\t{%2, %0|%0, %2}"
20203 [(set_attr "type" "mmxadd")
20204 (set_attr "mode" "DI")])
20205
20206 (define_insn "ussubv8qi3"
20207 [(set (match_operand:V8QI 0 "register_operand" "=y")
20208 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20209 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20210 "TARGET_MMX"
20211 "psubusb\t{%2, %0|%0, %2}"
20212 [(set_attr "type" "mmxadd")
20213 (set_attr "mode" "DI")])
20214
20215 (define_insn "ussubv4hi3"
20216 [(set (match_operand:V4HI 0 "register_operand" "=y")
20217 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20218 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20219 "TARGET_MMX"
20220 "psubusw\t{%2, %0|%0, %2}"
20221 [(set_attr "type" "mmxadd")
20222 (set_attr "mode" "DI")])
20223
20224 (define_insn "mulv4hi3"
20225 [(set (match_operand:V4HI 0 "register_operand" "=y")
20226 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20227 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20228 "TARGET_MMX"
20229 "pmullw\t{%2, %0|%0, %2}"
20230 [(set_attr "type" "mmxmul")
20231 (set_attr "mode" "DI")])
20232
20233 (define_insn "smulv4hi3_highpart"
20234 [(set (match_operand:V4HI 0 "register_operand" "=y")
20235 (truncate:V4HI
20236 (lshiftrt:V4SI
20237 (mult:V4SI (sign_extend:V4SI
20238 (match_operand:V4HI 1 "register_operand" "0"))
20239 (sign_extend:V4SI
20240 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20241 (const_int 16))))]
20242 "TARGET_MMX"
20243 "pmulhw\t{%2, %0|%0, %2}"
20244 [(set_attr "type" "mmxmul")
20245 (set_attr "mode" "DI")])
20246
20247 (define_insn "umulv4hi3_highpart"
20248 [(set (match_operand:V4HI 0 "register_operand" "=y")
20249 (truncate:V4HI
20250 (lshiftrt:V4SI
20251 (mult:V4SI (zero_extend:V4SI
20252 (match_operand:V4HI 1 "register_operand" "0"))
20253 (zero_extend:V4SI
20254 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20255 (const_int 16))))]
20256 "TARGET_SSE || TARGET_3DNOW_A"
20257 "pmulhuw\t{%2, %0|%0, %2}"
20258 [(set_attr "type" "mmxmul")
20259 (set_attr "mode" "DI")])
20260
20261 (define_insn "mmx_pmaddwd"
20262 [(set (match_operand:V2SI 0 "register_operand" "=y")
20263 (plus:V2SI
20264 (mult:V2SI
20265 (sign_extend:V2SI
20266 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20267 (parallel [(const_int 0) (const_int 2)])))
20268 (sign_extend:V2SI
20269 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20270 (parallel [(const_int 0) (const_int 2)]))))
20271 (mult:V2SI
20272 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20273 (parallel [(const_int 1)
20274 (const_int 3)])))
20275 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20276 (parallel [(const_int 1)
20277 (const_int 3)]))))))]
20278 "TARGET_MMX"
20279 "pmaddwd\t{%2, %0|%0, %2}"
20280 [(set_attr "type" "mmxmul")
20281 (set_attr "mode" "DI")])
20282
20283
20284 ;; MMX logical operations
20285 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20286 ;; normal code that also wants to use the FPU from getting broken.
20287 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20288 (define_insn "mmx_iordi3"
20289 [(set (match_operand:DI 0 "register_operand" "=y")
20290 (unspec:DI
20291 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20292 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20293 UNSPEC_NOP))]
20294 "TARGET_MMX"
20295 "por\t{%2, %0|%0, %2}"
20296 [(set_attr "type" "mmxadd")
20297 (set_attr "mode" "DI")])
20298
20299 (define_insn "mmx_xordi3"
20300 [(set (match_operand:DI 0 "register_operand" "=y")
20301 (unspec:DI
20302 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20303 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20304 UNSPEC_NOP))]
20305 "TARGET_MMX"
20306 "pxor\t{%2, %0|%0, %2}"
20307 [(set_attr "type" "mmxadd")
20308 (set_attr "mode" "DI")
20309 (set_attr "memory" "none")])
20310
20311 ;; Same as pxor, but don't show input operands so that we don't think
20312 ;; they are live.
20313 (define_insn "mmx_clrdi"
20314 [(set (match_operand:DI 0 "register_operand" "=y")
20315 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20316 "TARGET_MMX"
20317 "pxor\t{%0, %0|%0, %0}"
20318 [(set_attr "type" "mmxadd")
20319 (set_attr "mode" "DI")
20320 (set_attr "memory" "none")])
20321
20322 (define_insn "mmx_anddi3"
20323 [(set (match_operand:DI 0 "register_operand" "=y")
20324 (unspec:DI
20325 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20326 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20327 UNSPEC_NOP))]
20328 "TARGET_MMX"
20329 "pand\t{%2, %0|%0, %2}"
20330 [(set_attr "type" "mmxadd")
20331 (set_attr "mode" "DI")])
20332
20333 (define_insn "mmx_nanddi3"
20334 [(set (match_operand:DI 0 "register_operand" "=y")
20335 (unspec:DI
20336 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20337 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20338 UNSPEC_NOP))]
20339 "TARGET_MMX"
20340 "pandn\t{%2, %0|%0, %2}"
20341 [(set_attr "type" "mmxadd")
20342 (set_attr "mode" "DI")])
20343
20344
20345 ;; MMX unsigned averages/sum of absolute differences
20346
20347 (define_insn "mmx_uavgv8qi3"
20348 [(set (match_operand:V8QI 0 "register_operand" "=y")
20349 (ashiftrt:V8QI
20350 (plus:V8QI (plus:V8QI
20351 (match_operand:V8QI 1 "register_operand" "0")
20352 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20353 (const_vector:V8QI [(const_int 1)
20354 (const_int 1)
20355 (const_int 1)
20356 (const_int 1)
20357 (const_int 1)
20358 (const_int 1)
20359 (const_int 1)
20360 (const_int 1)]))
20361 (const_int 1)))]
20362 "TARGET_SSE || TARGET_3DNOW_A"
20363 "pavgb\t{%2, %0|%0, %2}"
20364 [(set_attr "type" "mmxshft")
20365 (set_attr "mode" "DI")])
20366
20367 (define_insn "mmx_uavgv4hi3"
20368 [(set (match_operand:V4HI 0 "register_operand" "=y")
20369 (ashiftrt:V4HI
20370 (plus:V4HI (plus:V4HI
20371 (match_operand:V4HI 1 "register_operand" "0")
20372 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20373 (const_vector:V4HI [(const_int 1)
20374 (const_int 1)
20375 (const_int 1)
20376 (const_int 1)]))
20377 (const_int 1)))]
20378 "TARGET_SSE || TARGET_3DNOW_A"
20379 "pavgw\t{%2, %0|%0, %2}"
20380 [(set_attr "type" "mmxshft")
20381 (set_attr "mode" "DI")])
20382
20383 (define_insn "mmx_psadbw"
20384 [(set (match_operand:DI 0 "register_operand" "=y")
20385 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20386 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20387 UNSPEC_PSADBW))]
20388 "TARGET_SSE || TARGET_3DNOW_A"
20389 "psadbw\t{%2, %0|%0, %2}"
20390 [(set_attr "type" "mmxshft")
20391 (set_attr "mode" "DI")])
20392
20393
20394 ;; MMX insert/extract/shuffle
20395
20396 (define_insn "mmx_pinsrw"
20397 [(set (match_operand:V4HI 0 "register_operand" "=y")
20398 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20399 (vec_duplicate:V4HI
20400 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20401 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
20402 "TARGET_SSE || TARGET_3DNOW_A"
20403 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20404 [(set_attr "type" "mmxcvt")
20405 (set_attr "mode" "DI")])
20406
20407 (define_insn "mmx_pextrw"
20408 [(set (match_operand:SI 0 "register_operand" "=r")
20409 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20410 (parallel
20411 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
20412 "TARGET_SSE || TARGET_3DNOW_A"
20413 "pextrw\t{%2, %1, %0|%0, %1, %2}"
20414 [(set_attr "type" "mmxcvt")
20415 (set_attr "mode" "DI")])
20416
20417 (define_insn "mmx_pshufw"
20418 [(set (match_operand:V4HI 0 "register_operand" "=y")
20419 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20420 (match_operand:SI 2 "immediate_operand" "i")]
20421 UNSPEC_SHUFFLE))]
20422 "TARGET_SSE || TARGET_3DNOW_A"
20423 "pshufw\t{%2, %1, %0|%0, %1, %2}"
20424 [(set_attr "type" "mmxcvt")
20425 (set_attr "mode" "DI")])
20426
20427
20428 ;; MMX mask-generating comparisons
20429
20430 (define_insn "eqv8qi3"
20431 [(set (match_operand:V8QI 0 "register_operand" "=y")
20432 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20433 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20434 "TARGET_MMX"
20435 "pcmpeqb\t{%2, %0|%0, %2}"
20436 [(set_attr "type" "mmxcmp")
20437 (set_attr "mode" "DI")])
20438
20439 (define_insn "eqv4hi3"
20440 [(set (match_operand:V4HI 0 "register_operand" "=y")
20441 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20442 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20443 "TARGET_MMX"
20444 "pcmpeqw\t{%2, %0|%0, %2}"
20445 [(set_attr "type" "mmxcmp")
20446 (set_attr "mode" "DI")])
20447
20448 (define_insn "eqv2si3"
20449 [(set (match_operand:V2SI 0 "register_operand" "=y")
20450 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20451 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20452 "TARGET_MMX"
20453 "pcmpeqd\t{%2, %0|%0, %2}"
20454 [(set_attr "type" "mmxcmp")
20455 (set_attr "mode" "DI")])
20456
20457 (define_insn "gtv8qi3"
20458 [(set (match_operand:V8QI 0 "register_operand" "=y")
20459 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20460 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20461 "TARGET_MMX"
20462 "pcmpgtb\t{%2, %0|%0, %2}"
20463 [(set_attr "type" "mmxcmp")
20464 (set_attr "mode" "DI")])
20465
20466 (define_insn "gtv4hi3"
20467 [(set (match_operand:V4HI 0 "register_operand" "=y")
20468 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20469 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20470 "TARGET_MMX"
20471 "pcmpgtw\t{%2, %0|%0, %2}"
20472 [(set_attr "type" "mmxcmp")
20473 (set_attr "mode" "DI")])
20474
20475 (define_insn "gtv2si3"
20476 [(set (match_operand:V2SI 0 "register_operand" "=y")
20477 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20478 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20479 "TARGET_MMX"
20480 "pcmpgtd\t{%2, %0|%0, %2}"
20481 [(set_attr "type" "mmxcmp")
20482 (set_attr "mode" "DI")])
20483
20484
20485 ;; MMX max/min insns
20486
20487 (define_insn "umaxv8qi3"
20488 [(set (match_operand:V8QI 0 "register_operand" "=y")
20489 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20490 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20491 "TARGET_SSE || TARGET_3DNOW_A"
20492 "pmaxub\t{%2, %0|%0, %2}"
20493 [(set_attr "type" "mmxadd")
20494 (set_attr "mode" "DI")])
20495
20496 (define_insn "smaxv4hi3"
20497 [(set (match_operand:V4HI 0 "register_operand" "=y")
20498 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20499 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20500 "TARGET_SSE || TARGET_3DNOW_A"
20501 "pmaxsw\t{%2, %0|%0, %2}"
20502 [(set_attr "type" "mmxadd")
20503 (set_attr "mode" "DI")])
20504
20505 (define_insn "uminv8qi3"
20506 [(set (match_operand:V8QI 0 "register_operand" "=y")
20507 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20508 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20509 "TARGET_SSE || TARGET_3DNOW_A"
20510 "pminub\t{%2, %0|%0, %2}"
20511 [(set_attr "type" "mmxadd")
20512 (set_attr "mode" "DI")])
20513
20514 (define_insn "sminv4hi3"
20515 [(set (match_operand:V4HI 0 "register_operand" "=y")
20516 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20517 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20518 "TARGET_SSE || TARGET_3DNOW_A"
20519 "pminsw\t{%2, %0|%0, %2}"
20520 [(set_attr "type" "mmxadd")
20521 (set_attr "mode" "DI")])
20522
20523
20524 ;; MMX shifts
20525
20526 (define_insn "ashrv4hi3"
20527 [(set (match_operand:V4HI 0 "register_operand" "=y")
20528 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20529 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20530 "TARGET_MMX"
20531 "psraw\t{%2, %0|%0, %2}"
20532 [(set_attr "type" "mmxshft")
20533 (set_attr "mode" "DI")])
20534
20535 (define_insn "ashrv2si3"
20536 [(set (match_operand:V2SI 0 "register_operand" "=y")
20537 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20538 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20539 "TARGET_MMX"
20540 "psrad\t{%2, %0|%0, %2}"
20541 [(set_attr "type" "mmxshft")
20542 (set_attr "mode" "DI")])
20543
20544 (define_insn "lshrv4hi3"
20545 [(set (match_operand:V4HI 0 "register_operand" "=y")
20546 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20547 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20548 "TARGET_MMX"
20549 "psrlw\t{%2, %0|%0, %2}"
20550 [(set_attr "type" "mmxshft")
20551 (set_attr "mode" "DI")])
20552
20553 (define_insn "lshrv2si3"
20554 [(set (match_operand:V2SI 0 "register_operand" "=y")
20555 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20556 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20557 "TARGET_MMX"
20558 "psrld\t{%2, %0|%0, %2}"
20559 [(set_attr "type" "mmxshft")
20560 (set_attr "mode" "DI")])
20561
20562 ;; See logical MMX insns.
20563 (define_insn "mmx_lshrdi3"
20564 [(set (match_operand:DI 0 "register_operand" "=y")
20565 (unspec:DI
20566 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
20567 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20568 UNSPEC_NOP))]
20569 "TARGET_MMX"
20570 "psrlq\t{%2, %0|%0, %2}"
20571 [(set_attr "type" "mmxshft")
20572 (set_attr "mode" "DI")])
20573
20574 (define_insn "ashlv4hi3"
20575 [(set (match_operand:V4HI 0 "register_operand" "=y")
20576 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
20577 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20578 "TARGET_MMX"
20579 "psllw\t{%2, %0|%0, %2}"
20580 [(set_attr "type" "mmxshft")
20581 (set_attr "mode" "DI")])
20582
20583 (define_insn "ashlv2si3"
20584 [(set (match_operand:V2SI 0 "register_operand" "=y")
20585 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
20586 (match_operand:DI 2 "nonmemory_operand" "yi")))]
20587 "TARGET_MMX"
20588 "pslld\t{%2, %0|%0, %2}"
20589 [(set_attr "type" "mmxshft")
20590 (set_attr "mode" "DI")])
20591
20592 ;; See logical MMX insns.
20593 (define_insn "mmx_ashldi3"
20594 [(set (match_operand:DI 0 "register_operand" "=y")
20595 (unspec:DI
20596 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
20597 (match_operand:DI 2 "nonmemory_operand" "yi"))]
20598 UNSPEC_NOP))]
20599 "TARGET_MMX"
20600 "psllq\t{%2, %0|%0, %2}"
20601 [(set_attr "type" "mmxshft")
20602 (set_attr "mode" "DI")])
20603
20604
20605 ;; MMX pack/unpack insns.
20606
20607 (define_insn "mmx_packsswb"
20608 [(set (match_operand:V8QI 0 "register_operand" "=y")
20609 (vec_concat:V8QI
20610 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20611 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20612 "TARGET_MMX"
20613 "packsswb\t{%2, %0|%0, %2}"
20614 [(set_attr "type" "mmxshft")
20615 (set_attr "mode" "DI")])
20616
20617 (define_insn "mmx_packssdw"
20618 [(set (match_operand:V4HI 0 "register_operand" "=y")
20619 (vec_concat:V4HI
20620 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
20621 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
20622 "TARGET_MMX"
20623 "packssdw\t{%2, %0|%0, %2}"
20624 [(set_attr "type" "mmxshft")
20625 (set_attr "mode" "DI")])
20626
20627 (define_insn "mmx_packuswb"
20628 [(set (match_operand:V8QI 0 "register_operand" "=y")
20629 (vec_concat:V8QI
20630 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
20631 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
20632 "TARGET_MMX"
20633 "packuswb\t{%2, %0|%0, %2}"
20634 [(set_attr "type" "mmxshft")
20635 (set_attr "mode" "DI")])
20636
20637 (define_insn "mmx_punpckhbw"
20638 [(set (match_operand:V8QI 0 "register_operand" "=y")
20639 (vec_merge:V8QI
20640 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20641 (parallel [(const_int 4)
20642 (const_int 0)
20643 (const_int 5)
20644 (const_int 1)
20645 (const_int 6)
20646 (const_int 2)
20647 (const_int 7)
20648 (const_int 3)]))
20649 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20650 (parallel [(const_int 0)
20651 (const_int 4)
20652 (const_int 1)
20653 (const_int 5)
20654 (const_int 2)
20655 (const_int 6)
20656 (const_int 3)
20657 (const_int 7)]))
20658 (const_int 85)))]
20659 "TARGET_MMX"
20660 "punpckhbw\t{%2, %0|%0, %2}"
20661 [(set_attr "type" "mmxcvt")
20662 (set_attr "mode" "DI")])
20663
20664 (define_insn "mmx_punpckhwd"
20665 [(set (match_operand:V4HI 0 "register_operand" "=y")
20666 (vec_merge:V4HI
20667 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20668 (parallel [(const_int 0)
20669 (const_int 2)
20670 (const_int 1)
20671 (const_int 3)]))
20672 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20673 (parallel [(const_int 2)
20674 (const_int 0)
20675 (const_int 3)
20676 (const_int 1)]))
20677 (const_int 5)))]
20678 "TARGET_MMX"
20679 "punpckhwd\t{%2, %0|%0, %2}"
20680 [(set_attr "type" "mmxcvt")
20681 (set_attr "mode" "DI")])
20682
20683 (define_insn "mmx_punpckhdq"
20684 [(set (match_operand:V2SI 0 "register_operand" "=y")
20685 (vec_merge:V2SI
20686 (match_operand:V2SI 1 "register_operand" "0")
20687 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
20688 (parallel [(const_int 1)
20689 (const_int 0)]))
20690 (const_int 1)))]
20691 "TARGET_MMX"
20692 "punpckhdq\t{%2, %0|%0, %2}"
20693 [(set_attr "type" "mmxcvt")
20694 (set_attr "mode" "DI")])
20695
20696 (define_insn "mmx_punpcklbw"
20697 [(set (match_operand:V8QI 0 "register_operand" "=y")
20698 (vec_merge:V8QI
20699 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
20700 (parallel [(const_int 0)
20701 (const_int 4)
20702 (const_int 1)
20703 (const_int 5)
20704 (const_int 2)
20705 (const_int 6)
20706 (const_int 3)
20707 (const_int 7)]))
20708 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
20709 (parallel [(const_int 4)
20710 (const_int 0)
20711 (const_int 5)
20712 (const_int 1)
20713 (const_int 6)
20714 (const_int 2)
20715 (const_int 7)
20716 (const_int 3)]))
20717 (const_int 85)))]
20718 "TARGET_MMX"
20719 "punpcklbw\t{%2, %0|%0, %2}"
20720 [(set_attr "type" "mmxcvt")
20721 (set_attr "mode" "DI")])
20722
20723 (define_insn "mmx_punpcklwd"
20724 [(set (match_operand:V4HI 0 "register_operand" "=y")
20725 (vec_merge:V4HI
20726 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
20727 (parallel [(const_int 2)
20728 (const_int 0)
20729 (const_int 3)
20730 (const_int 1)]))
20731 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
20732 (parallel [(const_int 0)
20733 (const_int 2)
20734 (const_int 1)
20735 (const_int 3)]))
20736 (const_int 5)))]
20737 "TARGET_MMX"
20738 "punpcklwd\t{%2, %0|%0, %2}"
20739 [(set_attr "type" "mmxcvt")
20740 (set_attr "mode" "DI")])
20741
20742 (define_insn "mmx_punpckldq"
20743 [(set (match_operand:V2SI 0 "register_operand" "=y")
20744 (vec_merge:V2SI
20745 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
20746 (parallel [(const_int 1)
20747 (const_int 0)]))
20748 (match_operand:V2SI 2 "register_operand" "y")
20749 (const_int 1)))]
20750 "TARGET_MMX"
20751 "punpckldq\t{%2, %0|%0, %2}"
20752 [(set_attr "type" "mmxcvt")
20753 (set_attr "mode" "DI")])
20754
20755
20756 ;; Miscellaneous stuff
20757
20758 (define_insn "emms"
20759 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
20760 (clobber (reg:XF 8))
20761 (clobber (reg:XF 9))
20762 (clobber (reg:XF 10))
20763 (clobber (reg:XF 11))
20764 (clobber (reg:XF 12))
20765 (clobber (reg:XF 13))
20766 (clobber (reg:XF 14))
20767 (clobber (reg:XF 15))
20768 (clobber (reg:DI 29))
20769 (clobber (reg:DI 30))
20770 (clobber (reg:DI 31))
20771 (clobber (reg:DI 32))
20772 (clobber (reg:DI 33))
20773 (clobber (reg:DI 34))
20774 (clobber (reg:DI 35))
20775 (clobber (reg:DI 36))]
20776 "TARGET_MMX"
20777 "emms"
20778 [(set_attr "type" "mmx")
20779 (set_attr "memory" "unknown")])
20780
20781 (define_insn "ldmxcsr"
20782 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
20783 UNSPECV_LDMXCSR)]
20784 "TARGET_SSE"
20785 "ldmxcsr\t%0"
20786 [(set_attr "type" "sse")
20787 (set_attr "memory" "load")])
20788
20789 (define_insn "stmxcsr"
20790 [(set (match_operand:SI 0 "memory_operand" "=m")
20791 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
20792 "TARGET_SSE"
20793 "stmxcsr\t%0"
20794 [(set_attr "type" "sse")
20795 (set_attr "memory" "store")])
20796
20797 (define_expand "sfence"
20798 [(set (match_dup 0)
20799 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20800 "TARGET_SSE || TARGET_3DNOW_A"
20801 {
20802 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20803 MEM_VOLATILE_P (operands[0]) = 1;
20804 })
20805
20806 (define_insn "*sfence_insn"
20807 [(set (match_operand:BLK 0 "" "")
20808 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
20809 "TARGET_SSE || TARGET_3DNOW_A"
20810 "sfence"
20811 [(set_attr "type" "sse")
20812 (set_attr "memory" "unknown")])
20813
20814 (define_expand "sse_prologue_save"
20815 [(parallel [(set (match_operand:BLK 0 "" "")
20816 (unspec:BLK [(reg:DI 21)
20817 (reg:DI 22)
20818 (reg:DI 23)
20819 (reg:DI 24)
20820 (reg:DI 25)
20821 (reg:DI 26)
20822 (reg:DI 27)
20823 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20824 (use (match_operand:DI 1 "register_operand" ""))
20825 (use (match_operand:DI 2 "immediate_operand" ""))
20826 (use (label_ref:DI (match_operand 3 "" "")))])]
20827 "TARGET_64BIT"
20828 "")
20829
20830 (define_insn "*sse_prologue_save_insn"
20831 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20832 (match_operand:DI 4 "const_int_operand" "n")))
20833 (unspec:BLK [(reg:DI 21)
20834 (reg:DI 22)
20835 (reg:DI 23)
20836 (reg:DI 24)
20837 (reg:DI 25)
20838 (reg:DI 26)
20839 (reg:DI 27)
20840 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20841 (use (match_operand:DI 1 "register_operand" "r"))
20842 (use (match_operand:DI 2 "const_int_operand" "i"))
20843 (use (label_ref:DI (match_operand 3 "" "X")))]
20844 "TARGET_64BIT
20845 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20846 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20847 "*
20848 {
20849 int i;
20850 operands[0] = gen_rtx_MEM (Pmode,
20851 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20852 output_asm_insn (\"jmp\\t%A1\", operands);
20853 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20854 {
20855 operands[4] = adjust_address (operands[0], DImode, i*16);
20856 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20857 PUT_MODE (operands[4], TImode);
20858 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20859 output_asm_insn (\"rex\", operands);
20860 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20861 }
20862 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20863 CODE_LABEL_NUMBER (operands[3]));
20864 RET;
20865 }
20866 "
20867 [(set_attr "type" "other")
20868 (set_attr "length_immediate" "0")
20869 (set_attr "length_address" "0")
20870 (set_attr "length" "135")
20871 (set_attr "memory" "store")
20872 (set_attr "modrm" "0")
20873 (set_attr "mode" "DI")])
20874
20875 ;; 3Dnow! instructions
20876
20877 (define_insn "addv2sf3"
20878 [(set (match_operand:V2SF 0 "register_operand" "=y")
20879 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20880 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20881 "TARGET_3DNOW"
20882 "pfadd\\t{%2, %0|%0, %2}"
20883 [(set_attr "type" "mmxadd")
20884 (set_attr "mode" "V2SF")])
20885
20886 (define_insn "subv2sf3"
20887 [(set (match_operand:V2SF 0 "register_operand" "=y")
20888 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
20889 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20890 "TARGET_3DNOW"
20891 "pfsub\\t{%2, %0|%0, %2}"
20892 [(set_attr "type" "mmxadd")
20893 (set_attr "mode" "V2SF")])
20894
20895 (define_insn "subrv2sf3"
20896 [(set (match_operand:V2SF 0 "register_operand" "=y")
20897 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
20898 (match_operand:V2SF 1 "register_operand" "0")))]
20899 "TARGET_3DNOW"
20900 "pfsubr\\t{%2, %0|%0, %2}"
20901 [(set_attr "type" "mmxadd")
20902 (set_attr "mode" "V2SF")])
20903
20904 (define_insn "gtv2sf3"
20905 [(set (match_operand:V2SI 0 "register_operand" "=y")
20906 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
20907 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20908 "TARGET_3DNOW"
20909 "pfcmpgt\\t{%2, %0|%0, %2}"
20910 [(set_attr "type" "mmxcmp")
20911 (set_attr "mode" "V2SF")])
20912
20913 (define_insn "gev2sf3"
20914 [(set (match_operand:V2SI 0 "register_operand" "=y")
20915 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
20916 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20917 "TARGET_3DNOW"
20918 "pfcmpge\\t{%2, %0|%0, %2}"
20919 [(set_attr "type" "mmxcmp")
20920 (set_attr "mode" "V2SF")])
20921
20922 (define_insn "eqv2sf3"
20923 [(set (match_operand:V2SI 0 "register_operand" "=y")
20924 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
20925 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20926 "TARGET_3DNOW"
20927 "pfcmpeq\\t{%2, %0|%0, %2}"
20928 [(set_attr "type" "mmxcmp")
20929 (set_attr "mode" "V2SF")])
20930
20931 (define_insn "pfmaxv2sf3"
20932 [(set (match_operand:V2SF 0 "register_operand" "=y")
20933 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
20934 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20935 "TARGET_3DNOW"
20936 "pfmax\\t{%2, %0|%0, %2}"
20937 [(set_attr "type" "mmxadd")
20938 (set_attr "mode" "V2SF")])
20939
20940 (define_insn "pfminv2sf3"
20941 [(set (match_operand:V2SF 0 "register_operand" "=y")
20942 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
20943 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20944 "TARGET_3DNOW"
20945 "pfmin\\t{%2, %0|%0, %2}"
20946 [(set_attr "type" "mmxadd")
20947 (set_attr "mode" "V2SF")])
20948
20949 (define_insn "mulv2sf3"
20950 [(set (match_operand:V2SF 0 "register_operand" "=y")
20951 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
20952 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
20953 "TARGET_3DNOW"
20954 "pfmul\\t{%2, %0|%0, %2}"
20955 [(set_attr "type" "mmxmul")
20956 (set_attr "mode" "V2SF")])
20957
20958 (define_insn "femms"
20959 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
20960 (clobber (reg:XF 8))
20961 (clobber (reg:XF 9))
20962 (clobber (reg:XF 10))
20963 (clobber (reg:XF 11))
20964 (clobber (reg:XF 12))
20965 (clobber (reg:XF 13))
20966 (clobber (reg:XF 14))
20967 (clobber (reg:XF 15))
20968 (clobber (reg:DI 29))
20969 (clobber (reg:DI 30))
20970 (clobber (reg:DI 31))
20971 (clobber (reg:DI 32))
20972 (clobber (reg:DI 33))
20973 (clobber (reg:DI 34))
20974 (clobber (reg:DI 35))
20975 (clobber (reg:DI 36))]
20976 "TARGET_3DNOW"
20977 "femms"
20978 [(set_attr "type" "mmx")
20979 (set_attr "memory" "none")])
20980
20981 (define_insn "pf2id"
20982 [(set (match_operand:V2SI 0 "register_operand" "=y")
20983 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
20984 "TARGET_3DNOW"
20985 "pf2id\\t{%1, %0|%0, %1}"
20986 [(set_attr "type" "mmxcvt")
20987 (set_attr "mode" "V2SF")])
20988
20989 (define_insn "pf2iw"
20990 [(set (match_operand:V2SI 0 "register_operand" "=y")
20991 (sign_extend:V2SI
20992 (ss_truncate:V2HI
20993 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
20994 "TARGET_3DNOW_A"
20995 "pf2iw\\t{%1, %0|%0, %1}"
20996 [(set_attr "type" "mmxcvt")
20997 (set_attr "mode" "V2SF")])
20998
20999 (define_insn "pfacc"
21000 [(set (match_operand:V2SF 0 "register_operand" "=y")
21001 (vec_concat:V2SF
21002 (plus:SF
21003 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21004 (parallel [(const_int 0)]))
21005 (vec_select:SF (match_dup 1)
21006 (parallel [(const_int 1)])))
21007 (plus:SF
21008 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21009 (parallel [(const_int 0)]))
21010 (vec_select:SF (match_dup 2)
21011 (parallel [(const_int 1)])))))]
21012 "TARGET_3DNOW"
21013 "pfacc\\t{%2, %0|%0, %2}"
21014 [(set_attr "type" "mmxadd")
21015 (set_attr "mode" "V2SF")])
21016
21017 (define_insn "pfnacc"
21018 [(set (match_operand:V2SF 0 "register_operand" "=y")
21019 (vec_concat:V2SF
21020 (minus:SF
21021 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21022 (parallel [(const_int 0)]))
21023 (vec_select:SF (match_dup 1)
21024 (parallel [(const_int 1)])))
21025 (minus:SF
21026 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21027 (parallel [(const_int 0)]))
21028 (vec_select:SF (match_dup 2)
21029 (parallel [(const_int 1)])))))]
21030 "TARGET_3DNOW_A"
21031 "pfnacc\\t{%2, %0|%0, %2}"
21032 [(set_attr "type" "mmxadd")
21033 (set_attr "mode" "V2SF")])
21034
21035 (define_insn "pfpnacc"
21036 [(set (match_operand:V2SF 0 "register_operand" "=y")
21037 (vec_concat:V2SF
21038 (minus:SF
21039 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21040 (parallel [(const_int 0)]))
21041 (vec_select:SF (match_dup 1)
21042 (parallel [(const_int 1)])))
21043 (plus:SF
21044 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21045 (parallel [(const_int 0)]))
21046 (vec_select:SF (match_dup 2)
21047 (parallel [(const_int 1)])))))]
21048 "TARGET_3DNOW_A"
21049 "pfpnacc\\t{%2, %0|%0, %2}"
21050 [(set_attr "type" "mmxadd")
21051 (set_attr "mode" "V2SF")])
21052
21053 (define_insn "pi2fw"
21054 [(set (match_operand:V2SF 0 "register_operand" "=y")
21055 (float:V2SF
21056 (vec_concat:V2SI
21057 (sign_extend:SI
21058 (truncate:HI
21059 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21060 (parallel [(const_int 0)]))))
21061 (sign_extend:SI
21062 (truncate:HI
21063 (vec_select:SI (match_dup 1)
21064 (parallel [(const_int 1)])))))))]
21065 "TARGET_3DNOW_A"
21066 "pi2fw\\t{%1, %0|%0, %1}"
21067 [(set_attr "type" "mmxcvt")
21068 (set_attr "mode" "V2SF")])
21069
21070 (define_insn "floatv2si2"
21071 [(set (match_operand:V2SF 0 "register_operand" "=y")
21072 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21073 "TARGET_3DNOW"
21074 "pi2fd\\t{%1, %0|%0, %1}"
21075 [(set_attr "type" "mmxcvt")
21076 (set_attr "mode" "V2SF")])
21077
21078 ;; This insn is identical to pavgb in operation, but the opcode is
21079 ;; different. To avoid accidentally matching pavgb, use an unspec.
21080
21081 (define_insn "pavgusb"
21082 [(set (match_operand:V8QI 0 "register_operand" "=y")
21083 (unspec:V8QI
21084 [(match_operand:V8QI 1 "register_operand" "0")
21085 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21086 UNSPEC_PAVGUSB))]
21087 "TARGET_3DNOW"
21088 "pavgusb\\t{%2, %0|%0, %2}"
21089 [(set_attr "type" "mmxshft")
21090 (set_attr "mode" "TI")])
21091
21092 ;; 3DNow reciprocal and sqrt
21093
21094 (define_insn "pfrcpv2sf2"
21095 [(set (match_operand:V2SF 0 "register_operand" "=y")
21096 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21097 UNSPEC_PFRCP))]
21098 "TARGET_3DNOW"
21099 "pfrcp\\t{%1, %0|%0, %1}"
21100 [(set_attr "type" "mmx")
21101 (set_attr "mode" "TI")])
21102
21103 (define_insn "pfrcpit1v2sf3"
21104 [(set (match_operand:V2SF 0 "register_operand" "=y")
21105 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21106 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21107 UNSPEC_PFRCPIT1))]
21108 "TARGET_3DNOW"
21109 "pfrcpit1\\t{%2, %0|%0, %2}"
21110 [(set_attr "type" "mmx")
21111 (set_attr "mode" "TI")])
21112
21113 (define_insn "pfrcpit2v2sf3"
21114 [(set (match_operand:V2SF 0 "register_operand" "=y")
21115 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21116 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21117 UNSPEC_PFRCPIT2))]
21118 "TARGET_3DNOW"
21119 "pfrcpit2\\t{%2, %0|%0, %2}"
21120 [(set_attr "type" "mmx")
21121 (set_attr "mode" "TI")])
21122
21123 (define_insn "pfrsqrtv2sf2"
21124 [(set (match_operand:V2SF 0 "register_operand" "=y")
21125 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21126 UNSPEC_PFRSQRT))]
21127 "TARGET_3DNOW"
21128 "pfrsqrt\\t{%1, %0|%0, %1}"
21129 [(set_attr "type" "mmx")
21130 (set_attr "mode" "TI")])
21131
21132 (define_insn "pfrsqit1v2sf3"
21133 [(set (match_operand:V2SF 0 "register_operand" "=y")
21134 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21135 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21136 UNSPEC_PFRSQIT1))]
21137 "TARGET_3DNOW"
21138 "pfrsqit1\\t{%2, %0|%0, %2}"
21139 [(set_attr "type" "mmx")
21140 (set_attr "mode" "TI")])
21141
21142 (define_insn "pmulhrwv4hi3"
21143 [(set (match_operand:V4HI 0 "register_operand" "=y")
21144 (truncate:V4HI
21145 (lshiftrt:V4SI
21146 (plus:V4SI
21147 (mult:V4SI
21148 (sign_extend:V4SI
21149 (match_operand:V4HI 1 "register_operand" "0"))
21150 (sign_extend:V4SI
21151 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21152 (const_vector:V4SI [(const_int 32768)
21153 (const_int 32768)
21154 (const_int 32768)
21155 (const_int 32768)]))
21156 (const_int 16))))]
21157 "TARGET_3DNOW"
21158 "pmulhrw\\t{%2, %0|%0, %2}"
21159 [(set_attr "type" "mmxmul")
21160 (set_attr "mode" "TI")])
21161
21162 (define_insn "pswapdv2si2"
21163 [(set (match_operand:V2SI 0 "register_operand" "=y")
21164 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21165 (parallel [(const_int 1) (const_int 0)])))]
21166 "TARGET_3DNOW_A"
21167 "pswapd\\t{%1, %0|%0, %1}"
21168 [(set_attr "type" "mmxcvt")
21169 (set_attr "mode" "TI")])
21170
21171 (define_insn "pswapdv2sf2"
21172 [(set (match_operand:V2SF 0 "register_operand" "=y")
21173 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21174 (parallel [(const_int 1) (const_int 0)])))]
21175 "TARGET_3DNOW_A"
21176 "pswapd\\t{%1, %0|%0, %1}"
21177 [(set_attr "type" "mmxcvt")
21178 (set_attr "mode" "TI")])
21179
21180 (define_expand "prefetch"
21181 [(prefetch (match_operand 0 "address_operand" "")
21182 (match_operand:SI 1 "const_int_operand" "")
21183 (match_operand:SI 2 "const_int_operand" ""))]
21184 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21185 {
21186 int rw = INTVAL (operands[1]);
21187 int locality = INTVAL (operands[2]);
21188
21189 if (rw != 0 && rw != 1)
21190 abort ();
21191 if (locality < 0 || locality > 3)
21192 abort ();
21193 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21194 abort ();
21195
21196 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21197 suported by SSE counterpart or the SSE prefetch is not available
21198 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21199 of locality. */
21200 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21201 operands[2] = GEN_INT (3);
21202 else
21203 operands[1] = const0_rtx;
21204 })
21205
21206 (define_insn "*prefetch_sse"
21207 [(prefetch (match_operand:SI 0 "address_operand" "p")
21208 (const_int 0)
21209 (match_operand:SI 1 "const_int_operand" ""))]
21210 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21211 {
21212 static const char * const patterns[4] = {
21213 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21214 };
21215
21216 int locality = INTVAL (operands[1]);
21217 if (locality < 0 || locality > 3)
21218 abort ();
21219
21220 return patterns[locality];
21221 }
21222 [(set_attr "type" "sse")
21223 (set_attr "memory" "none")])
21224
21225 (define_insn "*prefetch_sse_rex"
21226 [(prefetch (match_operand:DI 0 "address_operand" "p")
21227 (const_int 0)
21228 (match_operand:SI 1 "const_int_operand" ""))]
21229 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21230 {
21231 static const char * const patterns[4] = {
21232 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21233 };
21234
21235 int locality = INTVAL (operands[1]);
21236 if (locality < 0 || locality > 3)
21237 abort ();
21238
21239 return patterns[locality];
21240 }
21241 [(set_attr "type" "sse")
21242 (set_attr "memory" "none")])
21243
21244 (define_insn "*prefetch_3dnow"
21245 [(prefetch (match_operand:SI 0 "address_operand" "p")
21246 (match_operand:SI 1 "const_int_operand" "n")
21247 (const_int 3))]
21248 "TARGET_3DNOW && !TARGET_64BIT"
21249 {
21250 if (INTVAL (operands[1]) == 0)
21251 return "prefetch\t%a0";
21252 else
21253 return "prefetchw\t%a0";
21254 }
21255 [(set_attr "type" "mmx")
21256 (set_attr "memory" "none")])
21257
21258 (define_insn "*prefetch_3dnow_rex"
21259 [(prefetch (match_operand:DI 0 "address_operand" "p")
21260 (match_operand:SI 1 "const_int_operand" "n")
21261 (const_int 3))]
21262 "TARGET_3DNOW && TARGET_64BIT"
21263 {
21264 if (INTVAL (operands[1]) == 0)
21265 return "prefetch\t%a0";
21266 else
21267 return "prefetchw\t%a0";
21268 }
21269 [(set_attr "type" "mmx")
21270 (set_attr "memory" "none")])
21271
21272 ;; SSE2 support
21273
21274 (define_insn "addv2df3"
21275 [(set (match_operand:V2DF 0 "register_operand" "=x")
21276 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21277 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21278 "TARGET_SSE2"
21279 "addpd\t{%2, %0|%0, %2}"
21280 [(set_attr "type" "sseadd")
21281 (set_attr "mode" "V2DF")])
21282
21283 (define_insn "vmaddv2df3"
21284 [(set (match_operand:V2DF 0 "register_operand" "=x")
21285 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21286 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21287 (match_dup 1)
21288 (const_int 1)))]
21289 "TARGET_SSE2"
21290 "addsd\t{%2, %0|%0, %2}"
21291 [(set_attr "type" "sseadd")
21292 (set_attr "mode" "DF")])
21293
21294 (define_insn "subv2df3"
21295 [(set (match_operand:V2DF 0 "register_operand" "=x")
21296 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21297 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21298 "TARGET_SSE2"
21299 "subpd\t{%2, %0|%0, %2}"
21300 [(set_attr "type" "sseadd")
21301 (set_attr "mode" "V2DF")])
21302
21303 (define_insn "vmsubv2df3"
21304 [(set (match_operand:V2DF 0 "register_operand" "=x")
21305 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21306 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21307 (match_dup 1)
21308 (const_int 1)))]
21309 "TARGET_SSE2"
21310 "subsd\t{%2, %0|%0, %2}"
21311 [(set_attr "type" "sseadd")
21312 (set_attr "mode" "DF")])
21313
21314 (define_insn "mulv2df3"
21315 [(set (match_operand:V2DF 0 "register_operand" "=x")
21316 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21317 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21318 "TARGET_SSE2"
21319 "mulpd\t{%2, %0|%0, %2}"
21320 [(set_attr "type" "ssemul")
21321 (set_attr "mode" "V2DF")])
21322
21323 (define_insn "vmmulv2df3"
21324 [(set (match_operand:V2DF 0 "register_operand" "=x")
21325 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21326 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21327 (match_dup 1)
21328 (const_int 1)))]
21329 "TARGET_SSE2"
21330 "mulsd\t{%2, %0|%0, %2}"
21331 [(set_attr "type" "ssemul")
21332 (set_attr "mode" "DF")])
21333
21334 (define_insn "divv2df3"
21335 [(set (match_operand:V2DF 0 "register_operand" "=x")
21336 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21337 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21338 "TARGET_SSE2"
21339 "divpd\t{%2, %0|%0, %2}"
21340 [(set_attr "type" "ssediv")
21341 (set_attr "mode" "V2DF")])
21342
21343 (define_insn "vmdivv2df3"
21344 [(set (match_operand:V2DF 0 "register_operand" "=x")
21345 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21346 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21347 (match_dup 1)
21348 (const_int 1)))]
21349 "TARGET_SSE2"
21350 "divsd\t{%2, %0|%0, %2}"
21351 [(set_attr "type" "ssediv")
21352 (set_attr "mode" "DF")])
21353
21354 ;; SSE min/max
21355
21356 (define_insn "smaxv2df3"
21357 [(set (match_operand:V2DF 0 "register_operand" "=x")
21358 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21359 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21360 "TARGET_SSE2"
21361 "maxpd\t{%2, %0|%0, %2}"
21362 [(set_attr "type" "sseadd")
21363 (set_attr "mode" "V2DF")])
21364
21365 (define_insn "vmsmaxv2df3"
21366 [(set (match_operand:V2DF 0 "register_operand" "=x")
21367 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21368 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21369 (match_dup 1)
21370 (const_int 1)))]
21371 "TARGET_SSE2"
21372 "maxsd\t{%2, %0|%0, %2}"
21373 [(set_attr "type" "sseadd")
21374 (set_attr "mode" "DF")])
21375
21376 (define_insn "sminv2df3"
21377 [(set (match_operand:V2DF 0 "register_operand" "=x")
21378 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21379 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21380 "TARGET_SSE2"
21381 "minpd\t{%2, %0|%0, %2}"
21382 [(set_attr "type" "sseadd")
21383 (set_attr "mode" "V2DF")])
21384
21385 (define_insn "vmsminv2df3"
21386 [(set (match_operand:V2DF 0 "register_operand" "=x")
21387 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21388 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21389 (match_dup 1)
21390 (const_int 1)))]
21391 "TARGET_SSE2"
21392 "minsd\t{%2, %0|%0, %2}"
21393 [(set_attr "type" "sseadd")
21394 (set_attr "mode" "DF")])
21395 ;; SSE2 square root. There doesn't appear to be an extension for the
21396 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21397
21398 (define_insn "sqrtv2df2"
21399 [(set (match_operand:V2DF 0 "register_operand" "=x")
21400 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21401 "TARGET_SSE2"
21402 "sqrtpd\t{%1, %0|%0, %1}"
21403 [(set_attr "type" "sse")
21404 (set_attr "mode" "V2DF")])
21405
21406 (define_insn "vmsqrtv2df2"
21407 [(set (match_operand:V2DF 0 "register_operand" "=x")
21408 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21409 (match_operand:V2DF 2 "register_operand" "0")
21410 (const_int 1)))]
21411 "TARGET_SSE2"
21412 "sqrtsd\t{%1, %0|%0, %1}"
21413 [(set_attr "type" "sse")
21414 (set_attr "mode" "SF")])
21415
21416 ;; SSE mask-generating compares
21417
21418 (define_insn "maskcmpv2df3"
21419 [(set (match_operand:V2DI 0 "register_operand" "=x")
21420 (match_operator:V2DI 3 "sse_comparison_operator"
21421 [(match_operand:V2DF 1 "register_operand" "0")
21422 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21423 "TARGET_SSE2"
21424 "cmp%D3pd\t{%2, %0|%0, %2}"
21425 [(set_attr "type" "ssecmp")
21426 (set_attr "mode" "V2DF")])
21427
21428 (define_insn "maskncmpv2df3"
21429 [(set (match_operand:V2DI 0 "register_operand" "=x")
21430 (not:V2DI
21431 (match_operator:V2DI 3 "sse_comparison_operator"
21432 [(match_operand:V2DF 1 "register_operand" "0")
21433 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21434 "TARGET_SSE2"
21435 {
21436 if (GET_CODE (operands[3]) == UNORDERED)
21437 return "cmpordps\t{%2, %0|%0, %2}";
21438 else
21439 return "cmpn%D3pd\t{%2, %0|%0, %2}";
21440 }
21441 [(set_attr "type" "ssecmp")
21442 (set_attr "mode" "V2DF")])
21443
21444 (define_insn "vmmaskcmpv2df3"
21445 [(set (match_operand:V2DI 0 "register_operand" "=x")
21446 (vec_merge:V2DI
21447 (match_operator:V2DI 3 "sse_comparison_operator"
21448 [(match_operand:V2DF 1 "register_operand" "0")
21449 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21450 (subreg:V2DI (match_dup 1) 0)
21451 (const_int 1)))]
21452 "TARGET_SSE2"
21453 "cmp%D3sd\t{%2, %0|%0, %2}"
21454 [(set_attr "type" "ssecmp")
21455 (set_attr "mode" "DF")])
21456
21457 (define_insn "vmmaskncmpv2df3"
21458 [(set (match_operand:V2DI 0 "register_operand" "=x")
21459 (vec_merge:V2DI
21460 (not:V2DI
21461 (match_operator:V2DI 3 "sse_comparison_operator"
21462 [(match_operand:V2DF 1 "register_operand" "0")
21463 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21464 (subreg:V2DI (match_dup 1) 0)
21465 (const_int 1)))]
21466 "TARGET_SSE2"
21467 {
21468 if (GET_CODE (operands[3]) == UNORDERED)
21469 return "cmpordsd\t{%2, %0|%0, %2}";
21470 else
21471 return "cmpn%D3sd\t{%2, %0|%0, %2}";
21472 }
21473 [(set_attr "type" "ssecmp")
21474 (set_attr "mode" "DF")])
21475
21476 (define_insn "sse2_comi"
21477 [(set (reg:CCFP 17)
21478 (compare:CCFP (vec_select:DF
21479 (match_operand:V2DF 0 "register_operand" "x")
21480 (parallel [(const_int 0)]))
21481 (vec_select:DF
21482 (match_operand:V2DF 1 "register_operand" "x")
21483 (parallel [(const_int 0)]))))]
21484 "TARGET_SSE2"
21485 "comisd\t{%1, %0|%0, %1}"
21486 [(set_attr "type" "ssecomi")
21487 (set_attr "mode" "DF")])
21488
21489 (define_insn "sse2_ucomi"
21490 [(set (reg:CCFPU 17)
21491 (compare:CCFPU (vec_select:DF
21492 (match_operand:V2DF 0 "register_operand" "x")
21493 (parallel [(const_int 0)]))
21494 (vec_select:DF
21495 (match_operand:V2DF 1 "register_operand" "x")
21496 (parallel [(const_int 0)]))))]
21497 "TARGET_SSE2"
21498 "ucomisd\t{%1, %0|%0, %1}"
21499 [(set_attr "type" "ssecomi")
21500 (set_attr "mode" "DF")])
21501
21502 ;; SSE Strange Moves.
21503
21504 (define_insn "sse2_movmskpd"
21505 [(set (match_operand:SI 0 "register_operand" "=r")
21506 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21507 UNSPEC_MOVMSK))]
21508 "TARGET_SSE2"
21509 "movmskpd\t{%1, %0|%0, %1}"
21510 [(set_attr "type" "ssecvt")
21511 (set_attr "mode" "V2DF")])
21512
21513 (define_insn "sse2_pmovmskb"
21514 [(set (match_operand:SI 0 "register_operand" "=r")
21515 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21516 UNSPEC_MOVMSK))]
21517 "TARGET_SSE2"
21518 "pmovmskb\t{%1, %0|%0, %1}"
21519 [(set_attr "type" "ssecvt")
21520 (set_attr "mode" "V2DF")])
21521
21522 (define_insn "sse2_maskmovdqu"
21523 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21524 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21525 (match_operand:V16QI 2 "register_operand" "x")]
21526 UNSPEC_MASKMOV))]
21527 "TARGET_SSE2"
21528 ;; @@@ check ordering of operands in intel/nonintel syntax
21529 "maskmovdqu\t{%2, %1|%1, %2}"
21530 [(set_attr "type" "ssecvt")
21531 (set_attr "mode" "TI")])
21532
21533 (define_insn "sse2_maskmovdqu_rex64"
21534 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
21535 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
21536 (match_operand:V16QI 2 "register_operand" "x")]
21537 UNSPEC_MASKMOV))]
21538 "TARGET_SSE2"
21539 ;; @@@ check ordering of operands in intel/nonintel syntax
21540 "maskmovdqu\t{%2, %1|%1, %2}"
21541 [(set_attr "type" "ssecvt")
21542 (set_attr "mode" "TI")])
21543
21544 (define_insn "sse2_movntv2df"
21545 [(set (match_operand:V2DF 0 "memory_operand" "=m")
21546 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
21547 UNSPEC_MOVNT))]
21548 "TARGET_SSE2"
21549 "movntpd\t{%1, %0|%0, %1}"
21550 [(set_attr "type" "ssecvt")
21551 (set_attr "mode" "V2DF")])
21552
21553 (define_insn "sse2_movntv2di"
21554 [(set (match_operand:V2DI 0 "memory_operand" "=m")
21555 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
21556 UNSPEC_MOVNT))]
21557 "TARGET_SSE2"
21558 "movntdq\t{%1, %0|%0, %1}"
21559 [(set_attr "type" "ssecvt")
21560 (set_attr "mode" "TI")])
21561
21562 (define_insn "sse2_movntsi"
21563 [(set (match_operand:SI 0 "memory_operand" "=m")
21564 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
21565 UNSPEC_MOVNT))]
21566 "TARGET_SSE2"
21567 "movnti\t{%1, %0|%0, %1}"
21568 [(set_attr "type" "ssecvt")
21569 (set_attr "mode" "V2DF")])
21570
21571 ;; SSE <-> integer/MMX conversions
21572
21573 ;; Conversions between SI and SF
21574
21575 (define_insn "cvtdq2ps"
21576 [(set (match_operand:V4SF 0 "register_operand" "=x")
21577 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
21578 "TARGET_SSE2"
21579 "cvtdq2ps\t{%1, %0|%0, %1}"
21580 [(set_attr "type" "ssecvt")
21581 (set_attr "mode" "V2DF")])
21582
21583 (define_insn "cvtps2dq"
21584 [(set (match_operand:V4SI 0 "register_operand" "=x")
21585 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21586 "TARGET_SSE2"
21587 "cvtps2dq\t{%1, %0|%0, %1}"
21588 [(set_attr "type" "ssecvt")
21589 (set_attr "mode" "TI")])
21590
21591 (define_insn "cvttps2dq"
21592 [(set (match_operand:V4SI 0 "register_operand" "=x")
21593 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21594 UNSPEC_FIX))]
21595 "TARGET_SSE2"
21596 "cvttps2dq\t{%1, %0|%0, %1}"
21597 [(set_attr "type" "ssecvt")
21598 (set_attr "mode" "TI")])
21599
21600 ;; Conversions between SI and DF
21601
21602 (define_insn "cvtdq2pd"
21603 [(set (match_operand:V2DF 0 "register_operand" "=x")
21604 (float:V2DF (vec_select:V2SI
21605 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
21606 (parallel
21607 [(const_int 0)
21608 (const_int 1)]))))]
21609 "TARGET_SSE2"
21610 "cvtdq2pd\t{%1, %0|%0, %1}"
21611 [(set_attr "type" "ssecvt")
21612 (set_attr "mode" "V2DF")])
21613
21614 (define_insn "cvtpd2dq"
21615 [(set (match_operand:V4SI 0 "register_operand" "=x")
21616 (vec_concat:V4SI
21617 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
21618 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21619 "TARGET_SSE2"
21620 "cvtpd2dq\t{%1, %0|%0, %1}"
21621 [(set_attr "type" "ssecvt")
21622 (set_attr "mode" "TI")])
21623
21624 (define_insn "cvttpd2dq"
21625 [(set (match_operand:V4SI 0 "register_operand" "=x")
21626 (vec_concat:V4SI
21627 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21628 UNSPEC_FIX)
21629 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
21630 "TARGET_SSE2"
21631 "cvttpd2dq\t{%1, %0|%0, %1}"
21632 [(set_attr "type" "ssecvt")
21633 (set_attr "mode" "TI")])
21634
21635 (define_insn "cvtpd2pi"
21636 [(set (match_operand:V2SI 0 "register_operand" "=y")
21637 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
21638 "TARGET_SSE2"
21639 "cvtpd2pi\t{%1, %0|%0, %1}"
21640 [(set_attr "type" "ssecvt")
21641 (set_attr "mode" "TI")])
21642
21643 (define_insn "cvttpd2pi"
21644 [(set (match_operand:V2SI 0 "register_operand" "=y")
21645 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
21646 UNSPEC_FIX))]
21647 "TARGET_SSE2"
21648 "cvttpd2pi\t{%1, %0|%0, %1}"
21649 [(set_attr "type" "ssecvt")
21650 (set_attr "mode" "TI")])
21651
21652 (define_insn "cvtpi2pd"
21653 [(set (match_operand:V2DF 0 "register_operand" "=x")
21654 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21655 "TARGET_SSE2"
21656 "cvtpi2pd\t{%1, %0|%0, %1}"
21657 [(set_attr "type" "ssecvt")
21658 (set_attr "mode" "TI")])
21659
21660 ;; Conversions between SI and DF
21661
21662 (define_insn "cvtsd2si"
21663 [(set (match_operand:SI 0 "register_operand" "=r,r")
21664 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21665 (parallel [(const_int 0)]))))]
21666 "TARGET_SSE2"
21667 "cvtsd2si\t{%1, %0|%0, %1}"
21668 [(set_attr "type" "sseicvt")
21669 (set_attr "athlon_decode" "double,vector")
21670 (set_attr "mode" "SI")])
21671
21672 (define_insn "cvtsd2siq"
21673 [(set (match_operand:DI 0 "register_operand" "=r,r")
21674 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
21675 (parallel [(const_int 0)]))))]
21676 "TARGET_SSE2 && TARGET_64BIT"
21677 "cvtsd2siq\t{%1, %0|%0, %1}"
21678 [(set_attr "type" "sseicvt")
21679 (set_attr "athlon_decode" "double,vector")
21680 (set_attr "mode" "DI")])
21681
21682 (define_insn "cvttsd2si"
21683 [(set (match_operand:SI 0 "register_operand" "=r,r")
21684 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21685 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21686 "TARGET_SSE2"
21687 "cvttsd2si\t{%1, %0|%0, %1}"
21688 [(set_attr "type" "sseicvt")
21689 (set_attr "mode" "SI")
21690 (set_attr "athlon_decode" "double,vector")])
21691
21692 (define_insn "cvttsd2siq"
21693 [(set (match_operand:DI 0 "register_operand" "=r,r")
21694 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
21695 (parallel [(const_int 0)]))] UNSPEC_FIX))]
21696 "TARGET_SSE2 && TARGET_64BIT"
21697 "cvttsd2siq\t{%1, %0|%0, %1}"
21698 [(set_attr "type" "sseicvt")
21699 (set_attr "mode" "DI")
21700 (set_attr "athlon_decode" "double,vector")])
21701
21702 (define_insn "cvtsi2sd"
21703 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21704 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21705 (vec_duplicate:V2DF
21706 (float:DF
21707 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21708 (const_int 2)))]
21709 "TARGET_SSE2"
21710 "cvtsi2sd\t{%2, %0|%0, %2}"
21711 [(set_attr "type" "sseicvt")
21712 (set_attr "mode" "DF")
21713 (set_attr "athlon_decode" "double,direct")])
21714
21715 (define_insn "cvtsi2sdq"
21716 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
21717 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
21718 (vec_duplicate:V2DF
21719 (float:DF
21720 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21721 (const_int 2)))]
21722 "TARGET_SSE2 && TARGET_64BIT"
21723 "cvtsi2sdq\t{%2, %0|%0, %2}"
21724 [(set_attr "type" "sseicvt")
21725 (set_attr "mode" "DF")
21726 (set_attr "athlon_decode" "double,direct")])
21727
21728 ;; Conversions between SF and DF
21729
21730 (define_insn "cvtsd2ss"
21731 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21732 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
21733 (vec_duplicate:V4SF
21734 (float_truncate:V2SF
21735 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
21736 (const_int 14)))]
21737 "TARGET_SSE2"
21738 "cvtsd2ss\t{%2, %0|%0, %2}"
21739 [(set_attr "type" "ssecvt")
21740 (set_attr "athlon_decode" "vector,double")
21741 (set_attr "mode" "SF")])
21742
21743 (define_insn "cvtss2sd"
21744 [(set (match_operand:V2DF 0 "register_operand" "=x")
21745 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
21746 (float_extend:V2DF
21747 (vec_select:V2SF
21748 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
21749 (parallel [(const_int 0)
21750 (const_int 1)])))
21751 (const_int 2)))]
21752 "TARGET_SSE2"
21753 "cvtss2sd\t{%2, %0|%0, %2}"
21754 [(set_attr "type" "ssecvt")
21755 (set_attr "mode" "DF")])
21756
21757 (define_insn "cvtpd2ps"
21758 [(set (match_operand:V4SF 0 "register_operand" "=x")
21759 (subreg:V4SF
21760 (vec_concat:V4SI
21761 (subreg:V2SI (float_truncate:V2SF
21762 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
21763 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
21764 "TARGET_SSE2"
21765 "cvtpd2ps\t{%1, %0|%0, %1}"
21766 [(set_attr "type" "ssecvt")
21767 (set_attr "mode" "V4SF")])
21768
21769 (define_insn "cvtps2pd"
21770 [(set (match_operand:V2DF 0 "register_operand" "=x")
21771 (float_extend:V2DF
21772 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
21773 (parallel [(const_int 0)
21774 (const_int 1)]))))]
21775 "TARGET_SSE2"
21776 "cvtps2pd\t{%1, %0|%0, %1}"
21777 [(set_attr "type" "ssecvt")
21778 (set_attr "mode" "V2DF")])
21779
21780 ;; SSE2 variants of MMX insns
21781
21782 ;; MMX arithmetic
21783
21784 (define_insn "addv16qi3"
21785 [(set (match_operand:V16QI 0 "register_operand" "=x")
21786 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21787 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21788 "TARGET_SSE2"
21789 "paddb\t{%2, %0|%0, %2}"
21790 [(set_attr "type" "sseiadd")
21791 (set_attr "mode" "TI")])
21792
21793 (define_insn "addv8hi3"
21794 [(set (match_operand:V8HI 0 "register_operand" "=x")
21795 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21796 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21797 "TARGET_SSE2"
21798 "paddw\t{%2, %0|%0, %2}"
21799 [(set_attr "type" "sseiadd")
21800 (set_attr "mode" "TI")])
21801
21802 (define_insn "addv4si3"
21803 [(set (match_operand:V4SI 0 "register_operand" "=x")
21804 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
21805 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21806 "TARGET_SSE2"
21807 "paddd\t{%2, %0|%0, %2}"
21808 [(set_attr "type" "sseiadd")
21809 (set_attr "mode" "TI")])
21810
21811 (define_insn "addv2di3"
21812 [(set (match_operand:V2DI 0 "register_operand" "=x")
21813 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
21814 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21815 "TARGET_SSE2"
21816 "paddq\t{%2, %0|%0, %2}"
21817 [(set_attr "type" "sseiadd")
21818 (set_attr "mode" "TI")])
21819
21820 (define_insn "ssaddv16qi3"
21821 [(set (match_operand:V16QI 0 "register_operand" "=x")
21822 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21823 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21824 "TARGET_SSE2"
21825 "paddsb\t{%2, %0|%0, %2}"
21826 [(set_attr "type" "sseiadd")
21827 (set_attr "mode" "TI")])
21828
21829 (define_insn "ssaddv8hi3"
21830 [(set (match_operand:V8HI 0 "register_operand" "=x")
21831 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21832 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21833 "TARGET_SSE2"
21834 "paddsw\t{%2, %0|%0, %2}"
21835 [(set_attr "type" "sseiadd")
21836 (set_attr "mode" "TI")])
21837
21838 (define_insn "usaddv16qi3"
21839 [(set (match_operand:V16QI 0 "register_operand" "=x")
21840 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
21841 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21842 "TARGET_SSE2"
21843 "paddusb\t{%2, %0|%0, %2}"
21844 [(set_attr "type" "sseiadd")
21845 (set_attr "mode" "TI")])
21846
21847 (define_insn "usaddv8hi3"
21848 [(set (match_operand:V8HI 0 "register_operand" "=x")
21849 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
21850 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21851 "TARGET_SSE2"
21852 "paddusw\t{%2, %0|%0, %2}"
21853 [(set_attr "type" "sseiadd")
21854 (set_attr "mode" "TI")])
21855
21856 (define_insn "subv16qi3"
21857 [(set (match_operand:V16QI 0 "register_operand" "=x")
21858 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21859 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21860 "TARGET_SSE2"
21861 "psubb\t{%2, %0|%0, %2}"
21862 [(set_attr "type" "sseiadd")
21863 (set_attr "mode" "TI")])
21864
21865 (define_insn "subv8hi3"
21866 [(set (match_operand:V8HI 0 "register_operand" "=x")
21867 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21868 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21869 "TARGET_SSE2"
21870 "psubw\t{%2, %0|%0, %2}"
21871 [(set_attr "type" "sseiadd")
21872 (set_attr "mode" "TI")])
21873
21874 (define_insn "subv4si3"
21875 [(set (match_operand:V4SI 0 "register_operand" "=x")
21876 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
21877 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
21878 "TARGET_SSE2"
21879 "psubd\t{%2, %0|%0, %2}"
21880 [(set_attr "type" "sseiadd")
21881 (set_attr "mode" "TI")])
21882
21883 (define_insn "subv2di3"
21884 [(set (match_operand:V2DI 0 "register_operand" "=x")
21885 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
21886 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21887 "TARGET_SSE2"
21888 "psubq\t{%2, %0|%0, %2}"
21889 [(set_attr "type" "sseiadd")
21890 (set_attr "mode" "TI")])
21891
21892 (define_insn "sssubv16qi3"
21893 [(set (match_operand:V16QI 0 "register_operand" "=x")
21894 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21895 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21896 "TARGET_SSE2"
21897 "psubsb\t{%2, %0|%0, %2}"
21898 [(set_attr "type" "sseiadd")
21899 (set_attr "mode" "TI")])
21900
21901 (define_insn "sssubv8hi3"
21902 [(set (match_operand:V8HI 0 "register_operand" "=x")
21903 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21904 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21905 "TARGET_SSE2"
21906 "psubsw\t{%2, %0|%0, %2}"
21907 [(set_attr "type" "sseiadd")
21908 (set_attr "mode" "TI")])
21909
21910 (define_insn "ussubv16qi3"
21911 [(set (match_operand:V16QI 0 "register_operand" "=x")
21912 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
21913 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
21914 "TARGET_SSE2"
21915 "psubusb\t{%2, %0|%0, %2}"
21916 [(set_attr "type" "sseiadd")
21917 (set_attr "mode" "TI")])
21918
21919 (define_insn "ussubv8hi3"
21920 [(set (match_operand:V8HI 0 "register_operand" "=x")
21921 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
21922 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21923 "TARGET_SSE2"
21924 "psubusw\t{%2, %0|%0, %2}"
21925 [(set_attr "type" "sseiadd")
21926 (set_attr "mode" "TI")])
21927
21928 (define_insn "mulv8hi3"
21929 [(set (match_operand:V8HI 0 "register_operand" "=x")
21930 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
21931 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
21932 "TARGET_SSE2"
21933 "pmullw\t{%2, %0|%0, %2}"
21934 [(set_attr "type" "sseimul")
21935 (set_attr "mode" "TI")])
21936
21937 (define_insn "smulv8hi3_highpart"
21938 [(set (match_operand:V8HI 0 "register_operand" "=x")
21939 (truncate:V8HI
21940 (lshiftrt:V8SI
21941 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21942 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21943 (const_int 16))))]
21944 "TARGET_SSE2"
21945 "pmulhw\t{%2, %0|%0, %2}"
21946 [(set_attr "type" "sseimul")
21947 (set_attr "mode" "TI")])
21948
21949 (define_insn "umulv8hi3_highpart"
21950 [(set (match_operand:V8HI 0 "register_operand" "=x")
21951 (truncate:V8HI
21952 (lshiftrt:V8SI
21953 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
21954 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
21955 (const_int 16))))]
21956 "TARGET_SSE2"
21957 "pmulhuw\t{%2, %0|%0, %2}"
21958 [(set_attr "type" "sseimul")
21959 (set_attr "mode" "TI")])
21960
21961 (define_insn "sse2_umulsidi3"
21962 [(set (match_operand:DI 0 "register_operand" "=y")
21963 (mult:DI (zero_extend:DI (vec_select:SI
21964 (match_operand:V2SI 1 "register_operand" "0")
21965 (parallel [(const_int 0)])))
21966 (zero_extend:DI (vec_select:SI
21967 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
21968 (parallel [(const_int 0)])))))]
21969 "TARGET_SSE2"
21970 "pmuludq\t{%2, %0|%0, %2}"
21971 [(set_attr "type" "sseimul")
21972 (set_attr "mode" "TI")])
21973
21974 (define_insn "sse2_umulv2siv2di3"
21975 [(set (match_operand:V2DI 0 "register_operand" "=x")
21976 (mult:V2DI (zero_extend:V2DI
21977 (vec_select:V2SI
21978 (match_operand:V4SI 1 "register_operand" "0")
21979 (parallel [(const_int 0) (const_int 2)])))
21980 (zero_extend:V2DI
21981 (vec_select:V2SI
21982 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
21983 (parallel [(const_int 0) (const_int 2)])))))]
21984 "TARGET_SSE2"
21985 "pmuludq\t{%2, %0|%0, %2}"
21986 [(set_attr "type" "sseimul")
21987 (set_attr "mode" "TI")])
21988
21989 (define_insn "sse2_pmaddwd"
21990 [(set (match_operand:V4SI 0 "register_operand" "=x")
21991 (plus:V4SI
21992 (mult:V4SI
21993 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
21994 (parallel [(const_int 0)
21995 (const_int 2)
21996 (const_int 4)
21997 (const_int 6)])))
21998 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
21999 (parallel [(const_int 0)
22000 (const_int 2)
22001 (const_int 4)
22002 (const_int 6)]))))
22003 (mult:V4SI
22004 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22005 (parallel [(const_int 1)
22006 (const_int 3)
22007 (const_int 5)
22008 (const_int 7)])))
22009 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22010 (parallel [(const_int 1)
22011 (const_int 3)
22012 (const_int 5)
22013 (const_int 7)]))))))]
22014 "TARGET_SSE2"
22015 "pmaddwd\t{%2, %0|%0, %2}"
22016 [(set_attr "type" "sseiadd")
22017 (set_attr "mode" "TI")])
22018
22019 ;; Same as pxor, but don't show input operands so that we don't think
22020 ;; they are live.
22021 (define_insn "sse2_clrti"
22022 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22023 "TARGET_SSE2"
22024 {
22025 if (get_attr_mode (insn) == MODE_TI)
22026 return "pxor\t%0, %0";
22027 else
22028 return "xorps\t%0, %0";
22029 }
22030 [(set_attr "type" "ssemov")
22031 (set_attr "memory" "none")
22032 (set (attr "mode")
22033 (if_then_else
22034 (ne (symbol_ref "optimize_size")
22035 (const_int 0))
22036 (const_string "V4SF")
22037 (const_string "TI")))])
22038
22039 ;; MMX unsigned averages/sum of absolute differences
22040
22041 (define_insn "sse2_uavgv16qi3"
22042 [(set (match_operand:V16QI 0 "register_operand" "=x")
22043 (ashiftrt:V16QI
22044 (plus:V16QI (plus:V16QI
22045 (match_operand:V16QI 1 "register_operand" "0")
22046 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22047 (const_vector:V16QI [(const_int 1) (const_int 1)
22048 (const_int 1) (const_int 1)
22049 (const_int 1) (const_int 1)
22050 (const_int 1) (const_int 1)
22051 (const_int 1) (const_int 1)
22052 (const_int 1) (const_int 1)
22053 (const_int 1) (const_int 1)
22054 (const_int 1) (const_int 1)]))
22055 (const_int 1)))]
22056 "TARGET_SSE2"
22057 "pavgb\t{%2, %0|%0, %2}"
22058 [(set_attr "type" "sseiadd")
22059 (set_attr "mode" "TI")])
22060
22061 (define_insn "sse2_uavgv8hi3"
22062 [(set (match_operand:V8HI 0 "register_operand" "=x")
22063 (ashiftrt:V8HI
22064 (plus:V8HI (plus:V8HI
22065 (match_operand:V8HI 1 "register_operand" "0")
22066 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22067 (const_vector:V8HI [(const_int 1) (const_int 1)
22068 (const_int 1) (const_int 1)
22069 (const_int 1) (const_int 1)
22070 (const_int 1) (const_int 1)]))
22071 (const_int 1)))]
22072 "TARGET_SSE2"
22073 "pavgw\t{%2, %0|%0, %2}"
22074 [(set_attr "type" "sseiadd")
22075 (set_attr "mode" "TI")])
22076
22077 ;; @@@ this isn't the right representation.
22078 (define_insn "sse2_psadbw"
22079 [(set (match_operand:V2DI 0 "register_operand" "=x")
22080 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22081 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22082 UNSPEC_PSADBW))]
22083 "TARGET_SSE2"
22084 "psadbw\t{%2, %0|%0, %2}"
22085 [(set_attr "type" "sseiadd")
22086 (set_attr "mode" "TI")])
22087
22088
22089 ;; MMX insert/extract/shuffle
22090
22091 (define_insn "sse2_pinsrw"
22092 [(set (match_operand:V8HI 0 "register_operand" "=x")
22093 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22094 (vec_duplicate:V8HI
22095 (truncate:HI
22096 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22097 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
22098 "TARGET_SSE2"
22099 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22100 [(set_attr "type" "ssecvt")
22101 (set_attr "mode" "TI")])
22102
22103 (define_insn "sse2_pextrw"
22104 [(set (match_operand:SI 0 "register_operand" "=r")
22105 (zero_extend:SI
22106 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22107 (parallel
22108 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
22109 "TARGET_SSE2"
22110 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22111 [(set_attr "type" "ssecvt")
22112 (set_attr "mode" "TI")])
22113
22114 (define_insn "sse2_pshufd"
22115 [(set (match_operand:V4SI 0 "register_operand" "=x")
22116 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22117 (match_operand:SI 2 "immediate_operand" "i")]
22118 UNSPEC_SHUFFLE))]
22119 "TARGET_SSE2"
22120 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22121 [(set_attr "type" "ssecvt")
22122 (set_attr "mode" "TI")])
22123
22124 (define_insn "sse2_pshuflw"
22125 [(set (match_operand:V8HI 0 "register_operand" "=x")
22126 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22127 (match_operand:SI 2 "immediate_operand" "i")]
22128 UNSPEC_PSHUFLW))]
22129 "TARGET_SSE2"
22130 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22131 [(set_attr "type" "ssecvt")
22132 (set_attr "mode" "TI")])
22133
22134 (define_insn "sse2_pshufhw"
22135 [(set (match_operand:V8HI 0 "register_operand" "=x")
22136 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22137 (match_operand:SI 2 "immediate_operand" "i")]
22138 UNSPEC_PSHUFHW))]
22139 "TARGET_SSE2"
22140 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22141 [(set_attr "type" "ssecvt")
22142 (set_attr "mode" "TI")])
22143
22144 ;; MMX mask-generating comparisons
22145
22146 (define_insn "eqv16qi3"
22147 [(set (match_operand:V16QI 0 "register_operand" "=x")
22148 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22149 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22150 "TARGET_SSE2"
22151 "pcmpeqb\t{%2, %0|%0, %2}"
22152 [(set_attr "type" "ssecmp")
22153 (set_attr "mode" "TI")])
22154
22155 (define_insn "eqv8hi3"
22156 [(set (match_operand:V8HI 0 "register_operand" "=x")
22157 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22158 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22159 "TARGET_SSE2"
22160 "pcmpeqw\t{%2, %0|%0, %2}"
22161 [(set_attr "type" "ssecmp")
22162 (set_attr "mode" "TI")])
22163
22164 (define_insn "eqv4si3"
22165 [(set (match_operand:V4SI 0 "register_operand" "=x")
22166 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22167 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22168 "TARGET_SSE2"
22169 "pcmpeqd\t{%2, %0|%0, %2}"
22170 [(set_attr "type" "ssecmp")
22171 (set_attr "mode" "TI")])
22172
22173 (define_insn "gtv16qi3"
22174 [(set (match_operand:V16QI 0 "register_operand" "=x")
22175 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22176 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22177 "TARGET_SSE2"
22178 "pcmpgtb\t{%2, %0|%0, %2}"
22179 [(set_attr "type" "ssecmp")
22180 (set_attr "mode" "TI")])
22181
22182 (define_insn "gtv8hi3"
22183 [(set (match_operand:V8HI 0 "register_operand" "=x")
22184 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22185 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22186 "TARGET_SSE2"
22187 "pcmpgtw\t{%2, %0|%0, %2}"
22188 [(set_attr "type" "ssecmp")
22189 (set_attr "mode" "TI")])
22190
22191 (define_insn "gtv4si3"
22192 [(set (match_operand:V4SI 0 "register_operand" "=x")
22193 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22194 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22195 "TARGET_SSE2"
22196 "pcmpgtd\t{%2, %0|%0, %2}"
22197 [(set_attr "type" "ssecmp")
22198 (set_attr "mode" "TI")])
22199
22200
22201 ;; MMX max/min insns
22202
22203 (define_insn "umaxv16qi3"
22204 [(set (match_operand:V16QI 0 "register_operand" "=x")
22205 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22206 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22207 "TARGET_SSE2"
22208 "pmaxub\t{%2, %0|%0, %2}"
22209 [(set_attr "type" "sseiadd")
22210 (set_attr "mode" "TI")])
22211
22212 (define_insn "smaxv8hi3"
22213 [(set (match_operand:V8HI 0 "register_operand" "=x")
22214 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22215 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22216 "TARGET_SSE2"
22217 "pmaxsw\t{%2, %0|%0, %2}"
22218 [(set_attr "type" "sseiadd")
22219 (set_attr "mode" "TI")])
22220
22221 (define_insn "uminv16qi3"
22222 [(set (match_operand:V16QI 0 "register_operand" "=x")
22223 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22224 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22225 "TARGET_SSE2"
22226 "pminub\t{%2, %0|%0, %2}"
22227 [(set_attr "type" "sseiadd")
22228 (set_attr "mode" "TI")])
22229
22230 (define_insn "sminv8hi3"
22231 [(set (match_operand:V8HI 0 "register_operand" "=x")
22232 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22233 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22234 "TARGET_SSE2"
22235 "pminsw\t{%2, %0|%0, %2}"
22236 [(set_attr "type" "sseiadd")
22237 (set_attr "mode" "TI")])
22238
22239
22240 ;; MMX shifts
22241
22242 (define_insn "ashrv8hi3"
22243 [(set (match_operand:V8HI 0 "register_operand" "=x")
22244 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22245 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22246 "TARGET_SSE2"
22247 "psraw\t{%2, %0|%0, %2}"
22248 [(set_attr "type" "sseishft")
22249 (set_attr "mode" "TI")])
22250
22251 (define_insn "ashrv4si3"
22252 [(set (match_operand:V4SI 0 "register_operand" "=x")
22253 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22254 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22255 "TARGET_SSE2"
22256 "psrad\t{%2, %0|%0, %2}"
22257 [(set_attr "type" "sseishft")
22258 (set_attr "mode" "TI")])
22259
22260 (define_insn "lshrv8hi3"
22261 [(set (match_operand:V8HI 0 "register_operand" "=x")
22262 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22263 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22264 "TARGET_SSE2"
22265 "psrlw\t{%2, %0|%0, %2}"
22266 [(set_attr "type" "sseishft")
22267 (set_attr "mode" "TI")])
22268
22269 (define_insn "lshrv4si3"
22270 [(set (match_operand:V4SI 0 "register_operand" "=x")
22271 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22272 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22273 "TARGET_SSE2"
22274 "psrld\t{%2, %0|%0, %2}"
22275 [(set_attr "type" "sseishft")
22276 (set_attr "mode" "TI")])
22277
22278 (define_insn "lshrv2di3"
22279 [(set (match_operand:V2DI 0 "register_operand" "=x")
22280 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22281 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22282 "TARGET_SSE2"
22283 "psrlq\t{%2, %0|%0, %2}"
22284 [(set_attr "type" "sseishft")
22285 (set_attr "mode" "TI")])
22286
22287 (define_insn "ashlv8hi3"
22288 [(set (match_operand:V8HI 0 "register_operand" "=x")
22289 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22290 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22291 "TARGET_SSE2"
22292 "psllw\t{%2, %0|%0, %2}"
22293 [(set_attr "type" "sseishft")
22294 (set_attr "mode" "TI")])
22295
22296 (define_insn "ashlv4si3"
22297 [(set (match_operand:V4SI 0 "register_operand" "=x")
22298 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22299 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22300 "TARGET_SSE2"
22301 "pslld\t{%2, %0|%0, %2}"
22302 [(set_attr "type" "sseishft")
22303 (set_attr "mode" "TI")])
22304
22305 (define_insn "ashlv2di3"
22306 [(set (match_operand:V2DI 0 "register_operand" "=x")
22307 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22308 (match_operand:SI 2 "nonmemory_operand" "xi")))]
22309 "TARGET_SSE2"
22310 "psllq\t{%2, %0|%0, %2}"
22311 [(set_attr "type" "sseishft")
22312 (set_attr "mode" "TI")])
22313
22314 (define_insn "ashrv8hi3_ti"
22315 [(set (match_operand:V8HI 0 "register_operand" "=x")
22316 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22317 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22318 "TARGET_SSE2"
22319 "psraw\t{%2, %0|%0, %2}"
22320 [(set_attr "type" "sseishft")
22321 (set_attr "mode" "TI")])
22322
22323 (define_insn "ashrv4si3_ti"
22324 [(set (match_operand:V4SI 0 "register_operand" "=x")
22325 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22326 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22327 "TARGET_SSE2"
22328 "psrad\t{%2, %0|%0, %2}"
22329 [(set_attr "type" "sseishft")
22330 (set_attr "mode" "TI")])
22331
22332 (define_insn "lshrv8hi3_ti"
22333 [(set (match_operand:V8HI 0 "register_operand" "=x")
22334 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22335 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22336 "TARGET_SSE2"
22337 "psrlw\t{%2, %0|%0, %2}"
22338 [(set_attr "type" "sseishft")
22339 (set_attr "mode" "TI")])
22340
22341 (define_insn "lshrv4si3_ti"
22342 [(set (match_operand:V4SI 0 "register_operand" "=x")
22343 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22344 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22345 "TARGET_SSE2"
22346 "psrld\t{%2, %0|%0, %2}"
22347 [(set_attr "type" "sseishft")
22348 (set_attr "mode" "TI")])
22349
22350 (define_insn "lshrv2di3_ti"
22351 [(set (match_operand:V2DI 0 "register_operand" "=x")
22352 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22353 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22354 "TARGET_SSE2"
22355 "psrlq\t{%2, %0|%0, %2}"
22356 [(set_attr "type" "sseishft")
22357 (set_attr "mode" "TI")])
22358
22359 (define_insn "ashlv8hi3_ti"
22360 [(set (match_operand:V8HI 0 "register_operand" "=x")
22361 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22362 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22363 "TARGET_SSE2"
22364 "psllw\t{%2, %0|%0, %2}"
22365 [(set_attr "type" "sseishft")
22366 (set_attr "mode" "TI")])
22367
22368 (define_insn "ashlv4si3_ti"
22369 [(set (match_operand:V4SI 0 "register_operand" "=x")
22370 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22371 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22372 "TARGET_SSE2"
22373 "pslld\t{%2, %0|%0, %2}"
22374 [(set_attr "type" "sseishft")
22375 (set_attr "mode" "TI")])
22376
22377 (define_insn "ashlv2di3_ti"
22378 [(set (match_operand:V2DI 0 "register_operand" "=x")
22379 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22380 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22381 "TARGET_SSE2"
22382 "psllq\t{%2, %0|%0, %2}"
22383 [(set_attr "type" "sseishft")
22384 (set_attr "mode" "TI")])
22385
22386 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
22387 ;; we wouldn't need here it since we never generate TImode arithmetic.
22388
22389 ;; There has to be some kind of prize for the weirdest new instruction...
22390 (define_insn "sse2_ashlti3"
22391 [(set (match_operand:TI 0 "register_operand" "=x")
22392 (unspec:TI
22393 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22394 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22395 (const_int 8)))] UNSPEC_NOP))]
22396 "TARGET_SSE2"
22397 "pslldq\t{%2, %0|%0, %2}"
22398 [(set_attr "type" "sseishft")
22399 (set_attr "mode" "TI")])
22400
22401 (define_insn "sse2_lshrti3"
22402 [(set (match_operand:TI 0 "register_operand" "=x")
22403 (unspec:TI
22404 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22405 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22406 (const_int 8)))] UNSPEC_NOP))]
22407 "TARGET_SSE2"
22408 "psrldq\t{%2, %0|%0, %2}"
22409 [(set_attr "type" "sseishft")
22410 (set_attr "mode" "TI")])
22411
22412 ;; SSE unpack
22413
22414 (define_insn "sse2_unpckhpd"
22415 [(set (match_operand:V2DF 0 "register_operand" "=x")
22416 (vec_concat:V2DF
22417 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22418 (parallel [(const_int 1)]))
22419 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22420 (parallel [(const_int 1)]))))]
22421 "TARGET_SSE2"
22422 "unpckhpd\t{%2, %0|%0, %2}"
22423 [(set_attr "type" "ssecvt")
22424 (set_attr "mode" "V2DF")])
22425
22426 (define_insn "sse2_unpcklpd"
22427 [(set (match_operand:V2DF 0 "register_operand" "=x")
22428 (vec_concat:V2DF
22429 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22430 (parallel [(const_int 0)]))
22431 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22432 (parallel [(const_int 0)]))))]
22433 "TARGET_SSE2"
22434 "unpcklpd\t{%2, %0|%0, %2}"
22435 [(set_attr "type" "ssecvt")
22436 (set_attr "mode" "V2DF")])
22437
22438 ;; MMX pack/unpack insns.
22439
22440 (define_insn "sse2_packsswb"
22441 [(set (match_operand:V16QI 0 "register_operand" "=x")
22442 (vec_concat:V16QI
22443 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22444 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22445 "TARGET_SSE2"
22446 "packsswb\t{%2, %0|%0, %2}"
22447 [(set_attr "type" "ssecvt")
22448 (set_attr "mode" "TI")])
22449
22450 (define_insn "sse2_packssdw"
22451 [(set (match_operand:V8HI 0 "register_operand" "=x")
22452 (vec_concat:V8HI
22453 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22454 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22455 "TARGET_SSE2"
22456 "packssdw\t{%2, %0|%0, %2}"
22457 [(set_attr "type" "ssecvt")
22458 (set_attr "mode" "TI")])
22459
22460 (define_insn "sse2_packuswb"
22461 [(set (match_operand:V16QI 0 "register_operand" "=x")
22462 (vec_concat:V16QI
22463 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22464 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22465 "TARGET_SSE2"
22466 "packuswb\t{%2, %0|%0, %2}"
22467 [(set_attr "type" "ssecvt")
22468 (set_attr "mode" "TI")])
22469
22470 (define_insn "sse2_punpckhbw"
22471 [(set (match_operand:V16QI 0 "register_operand" "=x")
22472 (vec_merge:V16QI
22473 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22474 (parallel [(const_int 8) (const_int 0)
22475 (const_int 9) (const_int 1)
22476 (const_int 10) (const_int 2)
22477 (const_int 11) (const_int 3)
22478 (const_int 12) (const_int 4)
22479 (const_int 13) (const_int 5)
22480 (const_int 14) (const_int 6)
22481 (const_int 15) (const_int 7)]))
22482 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22483 (parallel [(const_int 0) (const_int 8)
22484 (const_int 1) (const_int 9)
22485 (const_int 2) (const_int 10)
22486 (const_int 3) (const_int 11)
22487 (const_int 4) (const_int 12)
22488 (const_int 5) (const_int 13)
22489 (const_int 6) (const_int 14)
22490 (const_int 7) (const_int 15)]))
22491 (const_int 21845)))]
22492 "TARGET_SSE2"
22493 "punpckhbw\t{%2, %0|%0, %2}"
22494 [(set_attr "type" "ssecvt")
22495 (set_attr "mode" "TI")])
22496
22497 (define_insn "sse2_punpckhwd"
22498 [(set (match_operand:V8HI 0 "register_operand" "=x")
22499 (vec_merge:V8HI
22500 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22501 (parallel [(const_int 4) (const_int 0)
22502 (const_int 5) (const_int 1)
22503 (const_int 6) (const_int 2)
22504 (const_int 7) (const_int 3)]))
22505 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22506 (parallel [(const_int 0) (const_int 4)
22507 (const_int 1) (const_int 5)
22508 (const_int 2) (const_int 6)
22509 (const_int 3) (const_int 7)]))
22510 (const_int 85)))]
22511 "TARGET_SSE2"
22512 "punpckhwd\t{%2, %0|%0, %2}"
22513 [(set_attr "type" "ssecvt")
22514 (set_attr "mode" "TI")])
22515
22516 (define_insn "sse2_punpckhdq"
22517 [(set (match_operand:V4SI 0 "register_operand" "=x")
22518 (vec_merge:V4SI
22519 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22520 (parallel [(const_int 2) (const_int 0)
22521 (const_int 3) (const_int 1)]))
22522 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22523 (parallel [(const_int 0) (const_int 2)
22524 (const_int 1) (const_int 3)]))
22525 (const_int 5)))]
22526 "TARGET_SSE2"
22527 "punpckhdq\t{%2, %0|%0, %2}"
22528 [(set_attr "type" "ssecvt")
22529 (set_attr "mode" "TI")])
22530
22531 (define_insn "sse2_punpcklbw"
22532 [(set (match_operand:V16QI 0 "register_operand" "=x")
22533 (vec_merge:V16QI
22534 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22535 (parallel [(const_int 0) (const_int 8)
22536 (const_int 1) (const_int 9)
22537 (const_int 2) (const_int 10)
22538 (const_int 3) (const_int 11)
22539 (const_int 4) (const_int 12)
22540 (const_int 5) (const_int 13)
22541 (const_int 6) (const_int 14)
22542 (const_int 7) (const_int 15)]))
22543 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22544 (parallel [(const_int 8) (const_int 0)
22545 (const_int 9) (const_int 1)
22546 (const_int 10) (const_int 2)
22547 (const_int 11) (const_int 3)
22548 (const_int 12) (const_int 4)
22549 (const_int 13) (const_int 5)
22550 (const_int 14) (const_int 6)
22551 (const_int 15) (const_int 7)]))
22552 (const_int 21845)))]
22553 "TARGET_SSE2"
22554 "punpcklbw\t{%2, %0|%0, %2}"
22555 [(set_attr "type" "ssecvt")
22556 (set_attr "mode" "TI")])
22557
22558 (define_insn "sse2_punpcklwd"
22559 [(set (match_operand:V8HI 0 "register_operand" "=x")
22560 (vec_merge:V8HI
22561 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22562 (parallel [(const_int 0) (const_int 4)
22563 (const_int 1) (const_int 5)
22564 (const_int 2) (const_int 6)
22565 (const_int 3) (const_int 7)]))
22566 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22567 (parallel [(const_int 4) (const_int 0)
22568 (const_int 5) (const_int 1)
22569 (const_int 6) (const_int 2)
22570 (const_int 7) (const_int 3)]))
22571 (const_int 85)))]
22572 "TARGET_SSE2"
22573 "punpcklwd\t{%2, %0|%0, %2}"
22574 [(set_attr "type" "ssecvt")
22575 (set_attr "mode" "TI")])
22576
22577 (define_insn "sse2_punpckldq"
22578 [(set (match_operand:V4SI 0 "register_operand" "=x")
22579 (vec_merge:V4SI
22580 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22581 (parallel [(const_int 0) (const_int 2)
22582 (const_int 1) (const_int 3)]))
22583 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22584 (parallel [(const_int 2) (const_int 0)
22585 (const_int 3) (const_int 1)]))
22586 (const_int 5)))]
22587 "TARGET_SSE2"
22588 "punpckldq\t{%2, %0|%0, %2}"
22589 [(set_attr "type" "ssecvt")
22590 (set_attr "mode" "TI")])
22591
22592 (define_insn "sse2_punpcklqdq"
22593 [(set (match_operand:V2DI 0 "register_operand" "=x")
22594 (vec_merge:V2DI
22595 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22596 (parallel [(const_int 1)
22597 (const_int 0)]))
22598 (match_operand:V2DI 1 "register_operand" "0")
22599 (const_int 1)))]
22600 "TARGET_SSE2"
22601 "punpcklqdq\t{%2, %0|%0, %2}"
22602 [(set_attr "type" "ssecvt")
22603 (set_attr "mode" "TI")])
22604
22605 (define_insn "sse2_punpckhqdq"
22606 [(set (match_operand:V2DI 0 "register_operand" "=x")
22607 (vec_merge:V2DI
22608 (match_operand:V2DI 1 "register_operand" "0")
22609 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
22610 (parallel [(const_int 1)
22611 (const_int 0)]))
22612 (const_int 1)))]
22613 "TARGET_SSE2"
22614 "punpckhqdq\t{%2, %0|%0, %2}"
22615 [(set_attr "type" "ssecvt")
22616 (set_attr "mode" "TI")])
22617
22618 ;; SSE2 moves
22619
22620 (define_insn "sse2_movapd"
22621 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22622 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22623 UNSPEC_MOVA))]
22624 "TARGET_SSE2
22625 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22626 "movapd\t{%1, %0|%0, %1}"
22627 [(set_attr "type" "ssemov")
22628 (set_attr "mode" "V2DF")])
22629
22630 (define_insn "sse2_movupd"
22631 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22632 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
22633 UNSPEC_MOVU))]
22634 "TARGET_SSE2
22635 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22636 "movupd\t{%1, %0|%0, %1}"
22637 [(set_attr "type" "ssecvt")
22638 (set_attr "mode" "V2DF")])
22639
22640 (define_insn "sse2_movdqa"
22641 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22642 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22643 UNSPEC_MOVA))]
22644 "TARGET_SSE2
22645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22646 "movdqa\t{%1, %0|%0, %1}"
22647 [(set_attr "type" "ssemov")
22648 (set_attr "mode" "TI")])
22649
22650 (define_insn "sse2_movdqu"
22651 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
22652 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
22653 UNSPEC_MOVU))]
22654 "TARGET_SSE2
22655 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
22656 "movdqu\t{%1, %0|%0, %1}"
22657 [(set_attr "type" "ssecvt")
22658 (set_attr "mode" "TI")])
22659
22660 (define_insn "sse2_movdq2q"
22661 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
22662 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
22663 (parallel [(const_int 0)])))]
22664 "TARGET_SSE2 && !TARGET_64BIT"
22665 "@
22666 movq\t{%1, %0|%0, %1}
22667 movdq2q\t{%1, %0|%0, %1}"
22668 [(set_attr "type" "ssecvt")
22669 (set_attr "mode" "TI")])
22670
22671 (define_insn "sse2_movdq2q_rex64"
22672 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
22673 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
22674 (parallel [(const_int 0)])))]
22675 "TARGET_SSE2 && TARGET_64BIT"
22676 "@
22677 movq\t{%1, %0|%0, %1}
22678 movdq2q\t{%1, %0|%0, %1}
22679 movd\t{%1, %0|%0, %1}"
22680 [(set_attr "type" "ssecvt")
22681 (set_attr "mode" "TI")])
22682
22683 (define_insn "sse2_movq2dq"
22684 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
22685 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
22686 (const_int 0)))]
22687 "TARGET_SSE2 && !TARGET_64BIT"
22688 "@
22689 movq\t{%1, %0|%0, %1}
22690 movq2dq\t{%1, %0|%0, %1}"
22691 [(set_attr "type" "ssecvt,ssemov")
22692 (set_attr "mode" "TI")])
22693
22694 (define_insn "sse2_movq2dq_rex64"
22695 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
22696 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
22697 (const_int 0)))]
22698 "TARGET_SSE2 && TARGET_64BIT"
22699 "@
22700 movq\t{%1, %0|%0, %1}
22701 movq2dq\t{%1, %0|%0, %1}
22702 movd\t{%1, %0|%0, %1}"
22703 [(set_attr "type" "ssecvt,ssemov,ssecvt")
22704 (set_attr "mode" "TI")])
22705
22706 (define_insn "sse2_movq"
22707 [(set (match_operand:V2DI 0 "register_operand" "=x")
22708 (vec_concat:V2DI (vec_select:DI
22709 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
22710 (parallel [(const_int 0)]))
22711 (const_int 0)))]
22712 "TARGET_SSE2"
22713 "movq\t{%1, %0|%0, %1}"
22714 [(set_attr "type" "ssemov")
22715 (set_attr "mode" "TI")])
22716
22717 (define_insn "sse2_loadd"
22718 [(set (match_operand:V4SI 0 "register_operand" "=x")
22719 (vec_merge:V4SI
22720 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
22721 (const_vector:V4SI [(const_int 0)
22722 (const_int 0)
22723 (const_int 0)
22724 (const_int 0)])
22725 (const_int 1)))]
22726 "TARGET_SSE2"
22727 "movd\t{%1, %0|%0, %1}"
22728 [(set_attr "type" "ssemov")
22729 (set_attr "mode" "TI")])
22730
22731 (define_insn "sse2_stored"
22732 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
22733 (vec_select:SI
22734 (match_operand:V4SI 1 "register_operand" "x")
22735 (parallel [(const_int 0)])))]
22736 "TARGET_SSE2"
22737 "movd\t{%1, %0|%0, %1}"
22738 [(set_attr "type" "ssemov")
22739 (set_attr "mode" "TI")])
22740
22741 (define_insn "sse2_movhpd"
22742 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
22743 (vec_merge:V2DF
22744 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
22745 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
22746 (const_int 2)))]
22747 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
22748 "movhpd\t{%2, %0|%0, %2}"
22749 [(set_attr "type" "ssecvt")
22750 (set_attr "mode" "V2DF")])
22751
22752 (define_expand "sse2_loadsd"
22753 [(match_operand:V2DF 0 "register_operand" "")
22754 (match_operand:DF 1 "memory_operand" "")]
22755 "TARGET_SSE2"
22756 {
22757 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
22758 CONST0_RTX (V2DFmode)));
22759 DONE;
22760 })
22761
22762 (define_insn "sse2_loadsd_1"
22763 [(set (match_operand:V2DF 0 "register_operand" "=x")
22764 (vec_merge:V2DF
22765 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
22766 (match_operand:V2DF 2 "const0_operand" "X")
22767 (const_int 1)))]
22768 "TARGET_SSE2"
22769 "movsd\t{%1, %0|%0, %1}"
22770 [(set_attr "type" "ssecvt")
22771 (set_attr "mode" "DF")])
22772
22773 (define_insn "sse2_movsd"
22774 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
22775 (vec_merge:V2DF
22776 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
22777 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
22778 (const_int 1)))]
22779 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
22780 "@movsd\t{%2, %0|%0, %2}
22781 movlpd\t{%2, %0|%0, %2}
22782 movlpd\t{%2, %0|%0, %2}"
22783 [(set_attr "type" "ssecvt")
22784 (set_attr "mode" "DF,V2DF,V2DF")])
22785
22786 (define_insn "sse2_storesd"
22787 [(set (match_operand:DF 0 "memory_operand" "=m")
22788 (vec_select:DF
22789 (match_operand:V2DF 1 "register_operand" "x")
22790 (parallel [(const_int 0)])))]
22791 "TARGET_SSE2"
22792 "movsd\t{%1, %0|%0, %1}"
22793 [(set_attr "type" "ssecvt")
22794 (set_attr "mode" "DF")])
22795
22796 (define_insn "sse2_shufpd"
22797 [(set (match_operand:V2DF 0 "register_operand" "=x")
22798 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22799 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
22800 (match_operand:SI 3 "immediate_operand" "i")]
22801 UNSPEC_SHUFFLE))]
22802 "TARGET_SSE2"
22803 ;; @@@ check operand order for intel/nonintel syntax
22804 "shufpd\t{%3, %2, %0|%0, %2, %3}"
22805 [(set_attr "type" "ssecvt")
22806 (set_attr "mode" "V2DF")])
22807
22808 (define_insn "sse2_clflush"
22809 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
22810 UNSPECV_CLFLUSH)]
22811 "TARGET_SSE2"
22812 "clflush %0"
22813 [(set_attr "type" "sse")
22814 (set_attr "memory" "unknown")])
22815
22816 (define_expand "sse2_mfence"
22817 [(set (match_dup 0)
22818 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22819 "TARGET_SSE2"
22820 {
22821 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22822 MEM_VOLATILE_P (operands[0]) = 1;
22823 })
22824
22825 (define_insn "*mfence_insn"
22826 [(set (match_operand:BLK 0 "" "")
22827 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
22828 "TARGET_SSE2"
22829 "mfence"
22830 [(set_attr "type" "sse")
22831 (set_attr "memory" "unknown")])
22832
22833 (define_expand "sse2_lfence"
22834 [(set (match_dup 0)
22835 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22836 "TARGET_SSE2"
22837 {
22838 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22839 MEM_VOLATILE_P (operands[0]) = 1;
22840 })
22841
22842 (define_insn "*lfence_insn"
22843 [(set (match_operand:BLK 0 "" "")
22844 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
22845 "TARGET_SSE2"
22846 "lfence"
22847 [(set_attr "type" "sse")
22848 (set_attr "memory" "unknown")])
22849
22850 ;; PNI
22851
22852 (define_insn "mwait"
22853 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22854 (match_operand:SI 1 "register_operand" "c")]
22855 UNSPECV_MWAIT)]
22856 "TARGET_PNI"
22857 "mwait\t%0, %1"
22858 [(set_attr "length" "3")])
22859
22860 (define_insn "monitor"
22861 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
22862 (match_operand:SI 1 "register_operand" "c")
22863 (match_operand:SI 2 "register_operand" "d")]
22864 UNSPECV_MONITOR)]
22865 "TARGET_PNI"
22866 "monitor\t%0, %1, %2"
22867 [(set_attr "length" "3")])
22868
22869 ;; PNI arithmetic
22870
22871 (define_insn "addsubv4sf3"
22872 [(set (match_operand:V4SF 0 "register_operand" "=x")
22873 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22874 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22875 UNSPEC_ADDSUB))]
22876 "TARGET_PNI"
22877 "addsubps\t{%2, %0|%0, %2}"
22878 [(set_attr "type" "sseadd")
22879 (set_attr "mode" "V4SF")])
22880
22881 (define_insn "addsubv2df3"
22882 [(set (match_operand:V2DF 0 "register_operand" "=x")
22883 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22884 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22885 UNSPEC_ADDSUB))]
22886 "TARGET_PNI"
22887 "addsubpd\t{%2, %0|%0, %2}"
22888 [(set_attr "type" "sseadd")
22889 (set_attr "mode" "V2DF")])
22890
22891 (define_insn "haddv4sf3"
22892 [(set (match_operand:V4SF 0 "register_operand" "=x")
22893 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22894 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22895 UNSPEC_HADD))]
22896 "TARGET_PNI"
22897 "haddps\t{%2, %0|%0, %2}"
22898 [(set_attr "type" "sseadd")
22899 (set_attr "mode" "V4SF")])
22900
22901 (define_insn "haddv2df3"
22902 [(set (match_operand:V2DF 0 "register_operand" "=x")
22903 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22904 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22905 UNSPEC_HADD))]
22906 "TARGET_PNI"
22907 "haddpd\t{%2, %0|%0, %2}"
22908 [(set_attr "type" "sseadd")
22909 (set_attr "mode" "V2DF")])
22910
22911 (define_insn "hsubv4sf3"
22912 [(set (match_operand:V4SF 0 "register_operand" "=x")
22913 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
22914 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
22915 UNSPEC_HSUB))]
22916 "TARGET_PNI"
22917 "hsubps\t{%2, %0|%0, %2}"
22918 [(set_attr "type" "sseadd")
22919 (set_attr "mode" "V4SF")])
22920
22921 (define_insn "hsubv2df3"
22922 [(set (match_operand:V2DF 0 "register_operand" "=x")
22923 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
22924 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
22925 UNSPEC_HSUB))]
22926 "TARGET_PNI"
22927 "hsubpd\t{%2, %0|%0, %2}"
22928 [(set_attr "type" "sseadd")
22929 (set_attr "mode" "V2DF")])
22930
22931 (define_insn "movshdup"
22932 [(set (match_operand:V4SF 0 "register_operand" "=x")
22933 (unspec:V4SF
22934 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
22935 "TARGET_PNI"
22936 "movshdup\t{%1, %0|%0, %1}"
22937 [(set_attr "type" "sse")
22938 (set_attr "mode" "V4SF")])
22939
22940 (define_insn "movsldup"
22941 [(set (match_operand:V4SF 0 "register_operand" "=x")
22942 (unspec:V4SF
22943 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
22944 "TARGET_PNI"
22945 "movsldup\t{%1, %0|%0, %1}"
22946 [(set_attr "type" "sse")
22947 (set_attr "mode" "V4SF")])
22948
22949 (define_insn "lddqu"
22950 [(set (match_operand:V16QI 0 "register_operand" "=x")
22951 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
22952 UNSPEC_LDQQU))]
22953 "TARGET_PNI"
22954 "lddqu\t{%1, %0|%0, %1}"
22955 [(set_attr "type" "ssecvt")
22956 (set_attr "mode" "TI")])
22957
22958 (define_insn "loadddup"
22959 [(set (match_operand:V2DF 0 "register_operand" "=x")
22960 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
22961 "TARGET_PNI"
22962 "movddup\t{%1, %0|%0, %1}"
22963 [(set_attr "type" "ssecvt")
22964 (set_attr "mode" "DF")])
22965
22966 (define_insn "movddup"
22967 [(set (match_operand:V2DF 0 "register_operand" "=x")
22968 (vec_duplicate:V2DF
22969 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
22970 (parallel [(const_int 0)]))))]
22971 "TARGET_PNI"
22972 "movddup\t{%1, %0|%0, %1}"
22973 [(set_attr "type" "ssecvt")
22974 (set_attr "mode" "DF")])