extend.texi: Document new builtin functions for Intel Prescott New Intrunctions.
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GNU CC.
9 ;;
10 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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 #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;; operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;; %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57 [; Relocation specifiers
58 (UNSPEC_GOT 0)
59 (UNSPEC_GOTOFF 1)
60 (UNSPEC_GOTPCREL 2)
61 (UNSPEC_GOTTPOFF 3)
62 (UNSPEC_TPOFF 4)
63 (UNSPEC_NTPOFF 5)
64 (UNSPEC_DTPOFF 6)
65 (UNSPEC_GOTNTPOFF 7)
66 (UNSPEC_INDNTPOFF 8)
67
68 ; Prologue support
69 (UNSPEC_STACK_PROBE 10)
70 (UNSPEC_STACK_ALLOC 11)
71 (UNSPEC_SET_GOT 12)
72 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73
74 ; TLS support
75 (UNSPEC_TP 15)
76 (UNSPEC_TLS_GD 16)
77 (UNSPEC_TLS_LD_BASE 17)
78
79 ; Other random patterns
80 (UNSPEC_SCAS 20)
81 (UNSPEC_SIN 21)
82 (UNSPEC_COS 22)
83 (UNSPEC_FNSTSW 24)
84 (UNSPEC_SAHF 25)
85 (UNSPEC_FSTCW 26)
86 (UNSPEC_ADD_CARRY 27)
87 (UNSPEC_FLDCW 28)
88
89 ; For SSE/MMX support:
90 (UNSPEC_FIX 30)
91 (UNSPEC_MASKMOV 32)
92 (UNSPEC_MOVMSK 33)
93 (UNSPEC_MOVNT 34)
94 (UNSPEC_MOVA 38)
95 (UNSPEC_MOVU 39)
96 (UNSPEC_SHUFFLE 41)
97 (UNSPEC_RCP 42)
98 (UNSPEC_RSQRT 43)
99 (UNSPEC_SFENCE 44)
100 (UNSPEC_NOP 45) ; prevents combiner cleverness
101 (UNSPEC_PAVGUSB 49)
102 (UNSPEC_PFRCP 50)
103 (UNSPEC_PFRCPIT1 51)
104 (UNSPEC_PFRCPIT2 52)
105 (UNSPEC_PFRSQRT 53)
106 (UNSPEC_PFRSQIT1 54)
107 (UNSPEC_PSHUFLW 55)
108 (UNSPEC_PSHUFHW 56)
109 (UNSPEC_MFENCE 59)
110 (UNSPEC_LFENCE 60)
111 (UNSPEC_PSADBW 61)
112 (UNSPEC_ADDSUB 71)
113 (UNSPEC_HADD 72)
114 (UNSPEC_HSUB 73)
115 (UNSPEC_MOVSHDUP 74)
116 (UNSPEC_MOVSLDUP 75)
117 (UNSPEC_LDQQU 76)
118 (UNSPEC_MOVDDUP 77)
119
120 ; x87 Floating point
121 (UNSPEC_FPATAN 65)
122 (UNSPEC_FYL2X 66)
123 (UNSPEC_FSCALE 67)
124 (UNSPEC_FRNDINT 68)
125 (UNSPEC_F2XM1 69)
126
127 ; REP instruction
128 (UNSPEC_REP 75)
129 ])
130
131 (define_constants
132 [(UNSPECV_BLOCKAGE 0)
133 (UNSPECV_EH_RETURN 13)
134 (UNSPECV_EMMS 31)
135 (UNSPECV_LDMXCSR 37)
136 (UNSPECV_STMXCSR 40)
137 (UNSPECV_FEMMS 46)
138 (UNSPECV_CLFLUSH 57)
139 (UNSPECV_ALIGN 68)
140 (UNSPECV_MONITOR 69)
141 (UNSPECV_MWAIT 70)
142 ])
143
144 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
145 ;; from i386.c.
146
147 ;; In C guard expressions, put expressions which may be compile-time
148 ;; constants first. This allows for better optimization. For
149 ;; example, write "TARGET_64BIT && reload_completed", not
150 ;; "reload_completed && TARGET_64BIT".
151
152 \f
153 ;; Processor type. This attribute must exactly match the processor_type
154 ;; enumeration in i386.h.
155 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
156 (const (symbol_ref "ix86_tune")))
157
158 ;; A basic instruction type. Refinements due to arguments to be
159 ;; provided in other attributes.
160 (define_attr "type"
161 "other,multi,
162 alu,alu1,negnot,imov,imovx,lea,
163 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
164 icmp,test,ibr,setcc,icmov,
165 push,pop,call,callv,leave,
166 str,cld,
167 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
168 sselog,sseiadd,sseishft,sseimul,
169 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
170 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
171 (const_string "other"))
172
173 ;; Main data type used by the insn
174 (define_attr "mode"
175 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
176 (const_string "unknown"))
177
178 ;; The CPU unit operations uses.
179 (define_attr "unit" "integer,i387,sse,mmx,unknown"
180 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
181 (const_string "i387")
182 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
183 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
184 (const_string "sse")
185 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
186 (const_string "mmx")
187 (eq_attr "type" "other")
188 (const_string "unknown")]
189 (const_string "integer")))
190
191 ;; The (bounding maximum) length of an instruction immediate.
192 (define_attr "length_immediate" ""
193 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
194 (const_int 0)
195 (eq_attr "unit" "i387,sse,mmx")
196 (const_int 0)
197 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
198 imul,icmp,push,pop")
199 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
200 (eq_attr "type" "imov,test")
201 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
202 (eq_attr "type" "call")
203 (if_then_else (match_operand 0 "constant_call_address_operand" "")
204 (const_int 4)
205 (const_int 0))
206 (eq_attr "type" "callv")
207 (if_then_else (match_operand 1 "constant_call_address_operand" "")
208 (const_int 4)
209 (const_int 0))
210 ;; We don't know the size before shorten_branches. Expect
211 ;; the instruction to fit for better scheduling.
212 (eq_attr "type" "ibr")
213 (const_int 1)
214 ]
215 (symbol_ref "/* Update immediate_length and other attributes! */
216 abort(),1")))
217
218 ;; The (bounding maximum) length of an instruction address.
219 (define_attr "length_address" ""
220 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
221 (const_int 0)
222 (and (eq_attr "type" "call")
223 (match_operand 0 "constant_call_address_operand" ""))
224 (const_int 0)
225 (and (eq_attr "type" "callv")
226 (match_operand 1 "constant_call_address_operand" ""))
227 (const_int 0)
228 ]
229 (symbol_ref "ix86_attr_length_address_default (insn)")))
230
231 ;; Set when length prefix is used.
232 (define_attr "prefix_data16" ""
233 (if_then_else (ior (eq_attr "mode" "HI")
234 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
235 (const_int 1)
236 (const_int 0)))
237
238 ;; Set when string REP prefix is used.
239 (define_attr "prefix_rep" ""
240 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
241 (const_int 1)
242 (const_int 0)))
243
244 ;; Set when 0f opcode prefix is used.
245 (define_attr "prefix_0f" ""
246 (if_then_else
247 (ior (eq_attr "type" "imovx,setcc,icmov")
248 (eq_attr "unit" "sse,mmx"))
249 (const_int 1)
250 (const_int 0)))
251
252 ;; Set when 0f opcode prefix is used.
253 (define_attr "prefix_rex" ""
254 (cond [(and (eq_attr "mode" "DI")
255 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
256 (const_int 1)
257 (and (eq_attr "mode" "QI")
258 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
259 (const_int 0)))
260 (const_int 1)
261 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
262 (const_int 0))
263 (const_int 1)
264 ]
265 (const_int 0)))
266
267 ;; Set when modrm byte is used.
268 (define_attr "modrm" ""
269 (cond [(eq_attr "type" "str,cld,leave")
270 (const_int 0)
271 (eq_attr "unit" "i387")
272 (const_int 0)
273 (and (eq_attr "type" "incdec")
274 (ior (match_operand:SI 1 "register_operand" "")
275 (match_operand:HI 1 "register_operand" "")))
276 (const_int 0)
277 (and (eq_attr "type" "push")
278 (not (match_operand 1 "memory_operand" "")))
279 (const_int 0)
280 (and (eq_attr "type" "pop")
281 (not (match_operand 0 "memory_operand" "")))
282 (const_int 0)
283 (and (eq_attr "type" "imov")
284 (and (match_operand 0 "register_operand" "")
285 (match_operand 1 "immediate_operand" "")))
286 (const_int 0)
287 (and (eq_attr "type" "call")
288 (match_operand 0 "constant_call_address_operand" ""))
289 (const_int 0)
290 (and (eq_attr "type" "callv")
291 (match_operand 1 "constant_call_address_operand" ""))
292 (const_int 0)
293 ]
294 (const_int 1)))
295
296 ;; The (bounding maximum) length of an instruction in bytes.
297 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
298 ;; to split it and compute proper length as for other insns.
299 (define_attr "length" ""
300 (cond [(eq_attr "type" "other,multi,fistp")
301 (const_int 16)
302 (eq_attr "type" "fcmp")
303 (const_int 4)
304 (eq_attr "unit" "i387")
305 (plus (const_int 2)
306 (plus (attr "prefix_data16")
307 (attr "length_address")))]
308 (plus (plus (attr "modrm")
309 (plus (attr "prefix_0f")
310 (plus (attr "prefix_rex")
311 (const_int 1))))
312 (plus (attr "prefix_rep")
313 (plus (attr "prefix_data16")
314 (plus (attr "length_immediate")
315 (attr "length_address")))))))
316
317 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
318 ;; `store' if there is a simple memory reference therein, or `unknown'
319 ;; if the instruction is complex.
320
321 (define_attr "memory" "none,load,store,both,unknown"
322 (cond [(eq_attr "type" "other,multi,str")
323 (const_string "unknown")
324 (eq_attr "type" "lea,fcmov,fpspc,cld")
325 (const_string "none")
326 (eq_attr "type" "fistp,leave")
327 (const_string "both")
328 (eq_attr "type" "push")
329 (if_then_else (match_operand 1 "memory_operand" "")
330 (const_string "both")
331 (const_string "store"))
332 (eq_attr "type" "pop")
333 (if_then_else (match_operand 0 "memory_operand" "")
334 (const_string "both")
335 (const_string "load"))
336 (eq_attr "type" "setcc")
337 (if_then_else (match_operand 0 "memory_operand" "")
338 (const_string "store")
339 (const_string "none"))
340 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
341 (if_then_else (ior (match_operand 0 "memory_operand" "")
342 (match_operand 1 "memory_operand" ""))
343 (const_string "load")
344 (const_string "none"))
345 (eq_attr "type" "ibr")
346 (if_then_else (match_operand 0 "memory_operand" "")
347 (const_string "load")
348 (const_string "none"))
349 (eq_attr "type" "call")
350 (if_then_else (match_operand 0 "constant_call_address_operand" "")
351 (const_string "none")
352 (const_string "load"))
353 (eq_attr "type" "callv")
354 (if_then_else (match_operand 1 "constant_call_address_operand" "")
355 (const_string "none")
356 (const_string "load"))
357 (and (eq_attr "type" "alu1,negnot")
358 (match_operand 1 "memory_operand" ""))
359 (const_string "both")
360 (and (match_operand 0 "memory_operand" "")
361 (match_operand 1 "memory_operand" ""))
362 (const_string "both")
363 (match_operand 0 "memory_operand" "")
364 (const_string "store")
365 (match_operand 1 "memory_operand" "")
366 (const_string "load")
367 (and (eq_attr "type"
368 "!alu1,negnot,
369 imov,imovx,icmp,test,
370 fmov,fcmp,fsgn,
371 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
372 mmx,mmxmov,mmxcmp,mmxcvt")
373 (match_operand 2 "memory_operand" ""))
374 (const_string "load")
375 (and (eq_attr "type" "icmov")
376 (match_operand 3 "memory_operand" ""))
377 (const_string "load")
378 ]
379 (const_string "none")))
380
381 ;; Indicates if an instruction has both an immediate and a displacement.
382
383 (define_attr "imm_disp" "false,true,unknown"
384 (cond [(eq_attr "type" "other,multi")
385 (const_string "unknown")
386 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
387 (and (match_operand 0 "memory_displacement_operand" "")
388 (match_operand 1 "immediate_operand" "")))
389 (const_string "true")
390 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
391 (and (match_operand 0 "memory_displacement_operand" "")
392 (match_operand 2 "immediate_operand" "")))
393 (const_string "true")
394 ]
395 (const_string "false")))
396
397 ;; Indicates if an FP operation has an integer source.
398
399 (define_attr "fp_int_src" "false,true"
400 (const_string "false"))
401
402 ;; Describe a user's asm statement.
403 (define_asm_attributes
404 [(set_attr "length" "128")
405 (set_attr "type" "multi")])
406 \f
407 (include "pentium.md")
408 (include "ppro.md")
409 (include "k6.md")
410 (include "athlon.md")
411 \f
412 ;; Compare instructions.
413
414 ;; All compare insns have expanders that save the operands away without
415 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
416 ;; after the cmp) will actually emit the cmpM.
417
418 (define_expand "cmpdi"
419 [(set (reg:CC 17)
420 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
421 (match_operand:DI 1 "x86_64_general_operand" "")))]
422 ""
423 {
424 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
425 operands[0] = force_reg (DImode, operands[0]);
426 ix86_compare_op0 = operands[0];
427 ix86_compare_op1 = operands[1];
428 DONE;
429 })
430
431 (define_expand "cmpsi"
432 [(set (reg:CC 17)
433 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
434 (match_operand:SI 1 "general_operand" "")))]
435 ""
436 {
437 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
438 operands[0] = force_reg (SImode, operands[0]);
439 ix86_compare_op0 = operands[0];
440 ix86_compare_op1 = operands[1];
441 DONE;
442 })
443
444 (define_expand "cmphi"
445 [(set (reg:CC 17)
446 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
447 (match_operand:HI 1 "general_operand" "")))]
448 ""
449 {
450 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
451 operands[0] = force_reg (HImode, operands[0]);
452 ix86_compare_op0 = operands[0];
453 ix86_compare_op1 = operands[1];
454 DONE;
455 })
456
457 (define_expand "cmpqi"
458 [(set (reg:CC 17)
459 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
460 (match_operand:QI 1 "general_operand" "")))]
461 "TARGET_QIMODE_MATH"
462 {
463 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
464 operands[0] = force_reg (QImode, operands[0]);
465 ix86_compare_op0 = operands[0];
466 ix86_compare_op1 = operands[1];
467 DONE;
468 })
469
470 (define_insn "cmpdi_ccno_1_rex64"
471 [(set (reg 17)
472 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
473 (match_operand:DI 1 "const0_operand" "n,n")))]
474 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
475 "@
476 test{q}\t{%0, %0|%0, %0}
477 cmp{q}\t{%1, %0|%0, %1}"
478 [(set_attr "type" "test,icmp")
479 (set_attr "length_immediate" "0,1")
480 (set_attr "mode" "DI")])
481
482 (define_insn "*cmpdi_minus_1_rex64"
483 [(set (reg 17)
484 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
485 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
486 (const_int 0)))]
487 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
488 "cmp{q}\t{%1, %0|%0, %1}"
489 [(set_attr "type" "icmp")
490 (set_attr "mode" "DI")])
491
492 (define_expand "cmpdi_1_rex64"
493 [(set (reg:CC 17)
494 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
495 (match_operand:DI 1 "general_operand" "")))]
496 "TARGET_64BIT"
497 "")
498
499 (define_insn "cmpdi_1_insn_rex64"
500 [(set (reg 17)
501 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
502 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
503 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
504 "cmp{q}\t{%1, %0|%0, %1}"
505 [(set_attr "type" "icmp")
506 (set_attr "mode" "DI")])
507
508
509 (define_insn "*cmpsi_ccno_1"
510 [(set (reg 17)
511 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
512 (match_operand:SI 1 "const0_operand" "n,n")))]
513 "ix86_match_ccmode (insn, CCNOmode)"
514 "@
515 test{l}\t{%0, %0|%0, %0}
516 cmp{l}\t{%1, %0|%0, %1}"
517 [(set_attr "type" "test,icmp")
518 (set_attr "length_immediate" "0,1")
519 (set_attr "mode" "SI")])
520
521 (define_insn "*cmpsi_minus_1"
522 [(set (reg 17)
523 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
524 (match_operand:SI 1 "general_operand" "ri,mr"))
525 (const_int 0)))]
526 "ix86_match_ccmode (insn, CCGOCmode)"
527 "cmp{l}\t{%1, %0|%0, %1}"
528 [(set_attr "type" "icmp")
529 (set_attr "mode" "SI")])
530
531 (define_expand "cmpsi_1"
532 [(set (reg:CC 17)
533 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
534 (match_operand:SI 1 "general_operand" "ri,mr")))]
535 ""
536 "")
537
538 (define_insn "*cmpsi_1_insn"
539 [(set (reg 17)
540 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
541 (match_operand:SI 1 "general_operand" "ri,mr")))]
542 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
543 && ix86_match_ccmode (insn, CCmode)"
544 "cmp{l}\t{%1, %0|%0, %1}"
545 [(set_attr "type" "icmp")
546 (set_attr "mode" "SI")])
547
548 (define_insn "*cmphi_ccno_1"
549 [(set (reg 17)
550 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
551 (match_operand:HI 1 "const0_operand" "n,n")))]
552 "ix86_match_ccmode (insn, CCNOmode)"
553 "@
554 test{w}\t{%0, %0|%0, %0}
555 cmp{w}\t{%1, %0|%0, %1}"
556 [(set_attr "type" "test,icmp")
557 (set_attr "length_immediate" "0,1")
558 (set_attr "mode" "HI")])
559
560 (define_insn "*cmphi_minus_1"
561 [(set (reg 17)
562 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
563 (match_operand:HI 1 "general_operand" "ri,mr"))
564 (const_int 0)))]
565 "ix86_match_ccmode (insn, CCGOCmode)"
566 "cmp{w}\t{%1, %0|%0, %1}"
567 [(set_attr "type" "icmp")
568 (set_attr "mode" "HI")])
569
570 (define_insn "*cmphi_1"
571 [(set (reg 17)
572 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
573 (match_operand:HI 1 "general_operand" "ri,mr")))]
574 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
575 && ix86_match_ccmode (insn, CCmode)"
576 "cmp{w}\t{%1, %0|%0, %1}"
577 [(set_attr "type" "icmp")
578 (set_attr "mode" "HI")])
579
580 (define_insn "*cmpqi_ccno_1"
581 [(set (reg 17)
582 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
583 (match_operand:QI 1 "const0_operand" "n,n")))]
584 "ix86_match_ccmode (insn, CCNOmode)"
585 "@
586 test{b}\t{%0, %0|%0, %0}
587 cmp{b}\t{$0, %0|%0, 0}"
588 [(set_attr "type" "test,icmp")
589 (set_attr "length_immediate" "0,1")
590 (set_attr "mode" "QI")])
591
592 (define_insn "*cmpqi_1"
593 [(set (reg 17)
594 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
595 (match_operand:QI 1 "general_operand" "qi,mq")))]
596 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
597 && ix86_match_ccmode (insn, CCmode)"
598 "cmp{b}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "icmp")
600 (set_attr "mode" "QI")])
601
602 (define_insn "*cmpqi_minus_1"
603 [(set (reg 17)
604 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
605 (match_operand:QI 1 "general_operand" "qi,mq"))
606 (const_int 0)))]
607 "ix86_match_ccmode (insn, CCGOCmode)"
608 "cmp{b}\t{%1, %0|%0, %1}"
609 [(set_attr "type" "icmp")
610 (set_attr "mode" "QI")])
611
612 (define_insn "*cmpqi_ext_1"
613 [(set (reg 17)
614 (compare
615 (match_operand:QI 0 "general_operand" "Qm")
616 (subreg:QI
617 (zero_extract:SI
618 (match_operand 1 "ext_register_operand" "Q")
619 (const_int 8)
620 (const_int 8)) 0)))]
621 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
622 "cmp{b}\t{%h1, %0|%0, %h1}"
623 [(set_attr "type" "icmp")
624 (set_attr "mode" "QI")])
625
626 (define_insn "*cmpqi_ext_1_rex64"
627 [(set (reg 17)
628 (compare
629 (match_operand:QI 0 "register_operand" "Q")
630 (subreg:QI
631 (zero_extract:SI
632 (match_operand 1 "ext_register_operand" "Q")
633 (const_int 8)
634 (const_int 8)) 0)))]
635 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
636 "cmp{b}\t{%h1, %0|%0, %h1}"
637 [(set_attr "type" "icmp")
638 (set_attr "mode" "QI")])
639
640 (define_insn "*cmpqi_ext_2"
641 [(set (reg 17)
642 (compare
643 (subreg:QI
644 (zero_extract:SI
645 (match_operand 0 "ext_register_operand" "Q")
646 (const_int 8)
647 (const_int 8)) 0)
648 (match_operand:QI 1 "const0_operand" "n")))]
649 "ix86_match_ccmode (insn, CCNOmode)"
650 "test{b}\t%h0, %h0"
651 [(set_attr "type" "test")
652 (set_attr "length_immediate" "0")
653 (set_attr "mode" "QI")])
654
655 (define_expand "cmpqi_ext_3"
656 [(set (reg:CC 17)
657 (compare:CC
658 (subreg:QI
659 (zero_extract:SI
660 (match_operand 0 "ext_register_operand" "")
661 (const_int 8)
662 (const_int 8)) 0)
663 (match_operand:QI 1 "general_operand" "")))]
664 ""
665 "")
666
667 (define_insn "cmpqi_ext_3_insn"
668 [(set (reg 17)
669 (compare
670 (subreg:QI
671 (zero_extract:SI
672 (match_operand 0 "ext_register_operand" "Q")
673 (const_int 8)
674 (const_int 8)) 0)
675 (match_operand:QI 1 "general_operand" "Qmn")))]
676 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
677 "cmp{b}\t{%1, %h0|%h0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "QI")])
680
681 (define_insn "cmpqi_ext_3_insn_rex64"
682 [(set (reg 17)
683 (compare
684 (subreg:QI
685 (zero_extract:SI
686 (match_operand 0 "ext_register_operand" "Q")
687 (const_int 8)
688 (const_int 8)) 0)
689 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
691 "cmp{b}\t{%1, %h0|%h0, %1}"
692 [(set_attr "type" "icmp")
693 (set_attr "mode" "QI")])
694
695 (define_insn "*cmpqi_ext_4"
696 [(set (reg 17)
697 (compare
698 (subreg:QI
699 (zero_extract:SI
700 (match_operand 0 "ext_register_operand" "Q")
701 (const_int 8)
702 (const_int 8)) 0)
703 (subreg:QI
704 (zero_extract:SI
705 (match_operand 1 "ext_register_operand" "Q")
706 (const_int 8)
707 (const_int 8)) 0)))]
708 "ix86_match_ccmode (insn, CCmode)"
709 "cmp{b}\t{%h1, %h0|%h0, %h1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "QI")])
712
713 ;; These implement float point compares.
714 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
715 ;; which would allow mix and match FP modes on the compares. Which is what
716 ;; the old patterns did, but with many more of them.
717
718 (define_expand "cmpxf"
719 [(set (reg:CC 17)
720 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
721 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
722 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
723 {
724 ix86_compare_op0 = operands[0];
725 ix86_compare_op1 = operands[1];
726 DONE;
727 })
728
729 (define_expand "cmptf"
730 [(set (reg:CC 17)
731 (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
732 (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
733 "TARGET_80387"
734 {
735 ix86_compare_op0 = operands[0];
736 ix86_compare_op1 = operands[1];
737 DONE;
738 })
739
740 (define_expand "cmpdf"
741 [(set (reg:CC 17)
742 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
743 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
744 "TARGET_80387 || TARGET_SSE2"
745 {
746 ix86_compare_op0 = operands[0];
747 ix86_compare_op1 = operands[1];
748 DONE;
749 })
750
751 (define_expand "cmpsf"
752 [(set (reg:CC 17)
753 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
754 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
755 "TARGET_80387 || TARGET_SSE"
756 {
757 ix86_compare_op0 = operands[0];
758 ix86_compare_op1 = operands[1];
759 DONE;
760 })
761
762 ;; FP compares, step 1:
763 ;; Set the FP condition codes.
764 ;;
765 ;; CCFPmode compare with exceptions
766 ;; CCFPUmode compare with no exceptions
767
768 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
769 ;; and that fp moves clobber the condition codes, and that there is
770 ;; currently no way to describe this fact to reg-stack. So there are
771 ;; no splitters yet for this.
772
773 ;; %%% YIKES! This scheme does not retain a strong connection between
774 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
775 ;; work! Only allow tos/mem with tos in op 0.
776 ;;
777 ;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
778 ;; things aren't as bad as they sound...
779
780 (define_insn "*cmpfp_0"
781 [(set (match_operand:HI 0 "register_operand" "=a")
782 (unspec:HI
783 [(compare:CCFP (match_operand 1 "register_operand" "f")
784 (match_operand 2 "const0_operand" "X"))]
785 UNSPEC_FNSTSW))]
786 "TARGET_80387
787 && FLOAT_MODE_P (GET_MODE (operands[1]))
788 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
789 {
790 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
791 return "ftst\;fnstsw\t%0\;fstp\t%y0";
792 else
793 return "ftst\;fnstsw\t%0";
794 }
795 [(set_attr "type" "multi")
796 (set (attr "mode")
797 (cond [(match_operand:SF 1 "" "")
798 (const_string "SF")
799 (match_operand:DF 1 "" "")
800 (const_string "DF")
801 ]
802 (const_string "XF")))])
803
804 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
805 ;; used to manage the reg stack popping would not be preserved.
806
807 (define_insn "*cmpfp_2_sf"
808 [(set (reg:CCFP 18)
809 (compare:CCFP
810 (match_operand:SF 0 "register_operand" "f")
811 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
812 "TARGET_80387"
813 "* return output_fp_compare (insn, operands, 0, 0);"
814 [(set_attr "type" "fcmp")
815 (set_attr "mode" "SF")])
816
817 (define_insn "*cmpfp_2_sf_1"
818 [(set (match_operand:HI 0 "register_operand" "=a")
819 (unspec:HI
820 [(compare:CCFP
821 (match_operand:SF 1 "register_operand" "f")
822 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
823 UNSPEC_FNSTSW))]
824 "TARGET_80387"
825 "* return output_fp_compare (insn, operands, 2, 0);"
826 [(set_attr "type" "fcmp")
827 (set_attr "mode" "SF")])
828
829 (define_insn "*cmpfp_2_df"
830 [(set (reg:CCFP 18)
831 (compare:CCFP
832 (match_operand:DF 0 "register_operand" "f")
833 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
834 "TARGET_80387"
835 "* return output_fp_compare (insn, operands, 0, 0);"
836 [(set_attr "type" "fcmp")
837 (set_attr "mode" "DF")])
838
839 (define_insn "*cmpfp_2_df_1"
840 [(set (match_operand:HI 0 "register_operand" "=a")
841 (unspec:HI
842 [(compare:CCFP
843 (match_operand:DF 1 "register_operand" "f")
844 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
845 UNSPEC_FNSTSW))]
846 "TARGET_80387"
847 "* return output_fp_compare (insn, operands, 2, 0);"
848 [(set_attr "type" "multi")
849 (set_attr "mode" "DF")])
850
851 (define_insn "*cmpfp_2_xf"
852 [(set (reg:CCFP 18)
853 (compare:CCFP
854 (match_operand:XF 0 "register_operand" "f")
855 (match_operand:XF 1 "register_operand" "f")))]
856 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
857 "* return output_fp_compare (insn, operands, 0, 0);"
858 [(set_attr "type" "fcmp")
859 (set_attr "mode" "XF")])
860
861 (define_insn "*cmpfp_2_tf"
862 [(set (reg:CCFP 18)
863 (compare:CCFP
864 (match_operand:TF 0 "register_operand" "f")
865 (match_operand:TF 1 "register_operand" "f")))]
866 "TARGET_80387"
867 "* return output_fp_compare (insn, operands, 0, 0);"
868 [(set_attr "type" "fcmp")
869 (set_attr "mode" "XF")])
870
871 (define_insn "*cmpfp_2_xf_1"
872 [(set (match_operand:HI 0 "register_operand" "=a")
873 (unspec:HI
874 [(compare:CCFP
875 (match_operand:XF 1 "register_operand" "f")
876 (match_operand:XF 2 "register_operand" "f"))]
877 UNSPEC_FNSTSW))]
878 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
879 "* return output_fp_compare (insn, operands, 2, 0);"
880 [(set_attr "type" "multi")
881 (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_2_tf_1"
884 [(set (match_operand:HI 0 "register_operand" "=a")
885 (unspec:HI
886 [(compare:CCFP
887 (match_operand:TF 1 "register_operand" "f")
888 (match_operand:TF 2 "register_operand" "f"))]
889 UNSPEC_FNSTSW))]
890 "TARGET_80387"
891 "* return output_fp_compare (insn, operands, 2, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "mode" "XF")])
894
895 (define_insn "*cmpfp_2u"
896 [(set (reg:CCFPU 18)
897 (compare:CCFPU
898 (match_operand 0 "register_operand" "f")
899 (match_operand 1 "register_operand" "f")))]
900 "TARGET_80387
901 && FLOAT_MODE_P (GET_MODE (operands[0]))
902 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
903 "* return output_fp_compare (insn, operands, 0, 1);"
904 [(set_attr "type" "fcmp")
905 (set (attr "mode")
906 (cond [(match_operand:SF 1 "" "")
907 (const_string "SF")
908 (match_operand:DF 1 "" "")
909 (const_string "DF")
910 ]
911 (const_string "XF")))])
912
913 (define_insn "*cmpfp_2u_1"
914 [(set (match_operand:HI 0 "register_operand" "=a")
915 (unspec:HI
916 [(compare:CCFPU
917 (match_operand 1 "register_operand" "f")
918 (match_operand 2 "register_operand" "f"))]
919 UNSPEC_FNSTSW))]
920 "TARGET_80387
921 && FLOAT_MODE_P (GET_MODE (operands[1]))
922 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923 "* return output_fp_compare (insn, operands, 2, 1);"
924 [(set_attr "type" "multi")
925 (set (attr "mode")
926 (cond [(match_operand:SF 1 "" "")
927 (const_string "SF")
928 (match_operand:DF 1 "" "")
929 (const_string "DF")
930 ]
931 (const_string "XF")))])
932
933 ;; Patterns to match the SImode-in-memory ficom instructions.
934 ;;
935 ;; %%% Play games with accepting gp registers, as otherwise we have to
936 ;; force them to memory during rtl generation, which is no good. We
937 ;; can get rid of this once we teach reload to do memory input reloads
938 ;; via pushes.
939
940 (define_insn "*ficom_1"
941 [(set (reg:CCFP 18)
942 (compare:CCFP
943 (match_operand 0 "register_operand" "f,f")
944 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
945 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
946 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
947 "#")
948
949 ;; Split the not-really-implemented gp register case into a
950 ;; push-op-pop sequence.
951 ;;
952 ;; %%% This is most efficient, but am I gonna get in trouble
953 ;; for separating cc0_setter and cc0_user?
954
955 (define_split
956 [(set (reg:CCFP 18)
957 (compare:CCFP
958 (match_operand:SF 0 "register_operand" "")
959 (float (match_operand:SI 1 "register_operand" ""))))]
960 "0 && TARGET_80387 && reload_completed"
961 [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
962 (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
963 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
964 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
965 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
966 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
967
968 ;; FP compares, step 2
969 ;; Move the fpsw to ax.
970
971 (define_insn "*x86_fnstsw_1"
972 [(set (match_operand:HI 0 "register_operand" "=a")
973 (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
974 "TARGET_80387"
975 "fnstsw\t%0"
976 [(set_attr "length" "2")
977 (set_attr "mode" "SI")
978 (set_attr "unit" "i387")
979 (set_attr "ppro_uops" "few")])
980
981 ;; FP compares, step 3
982 ;; Get ax into flags, general case.
983
984 (define_insn "x86_sahf_1"
985 [(set (reg:CC 17)
986 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
987 "!TARGET_64BIT"
988 "sahf"
989 [(set_attr "length" "1")
990 (set_attr "athlon_decode" "vector")
991 (set_attr "mode" "SI")
992 (set_attr "ppro_uops" "one")])
993
994 ;; Pentium Pro can do steps 1 through 3 in one go.
995
996 (define_insn "*cmpfp_i"
997 [(set (reg:CCFP 17)
998 (compare:CCFP (match_operand 0 "register_operand" "f")
999 (match_operand 1 "register_operand" "f")))]
1000 "TARGET_80387 && TARGET_CMOVE
1001 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && FLOAT_MODE_P (GET_MODE (operands[0]))
1003 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1004 "* return output_fp_compare (insn, operands, 1, 0);"
1005 [(set_attr "type" "fcmp")
1006 (set (attr "mode")
1007 (cond [(match_operand:SF 1 "" "")
1008 (const_string "SF")
1009 (match_operand:DF 1 "" "")
1010 (const_string "DF")
1011 ]
1012 (const_string "XF")))
1013 (set_attr "athlon_decode" "vector")])
1014
1015 (define_insn "*cmpfp_i_sse"
1016 [(set (reg:CCFP 17)
1017 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1018 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019 "TARGET_80387
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "fcmp,ssecomi")
1024 (set (attr "mode")
1025 (if_then_else (match_operand:SF 1 "" "")
1026 (const_string "SF")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")])
1029
1030 (define_insn "*cmpfp_i_sse_only"
1031 [(set (reg:CCFP 17)
1032 (compare:CCFP (match_operand 0 "register_operand" "x")
1033 (match_operand 1 "nonimmediate_operand" "xm")))]
1034 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1035 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1036 "* return output_fp_compare (insn, operands, 1, 0);"
1037 [(set_attr "type" "ssecomi")
1038 (set (attr "mode")
1039 (if_then_else (match_operand:SF 1 "" "")
1040 (const_string "SF")
1041 (const_string "DF")))
1042 (set_attr "athlon_decode" "vector")])
1043
1044 (define_insn "*cmpfp_iu"
1045 [(set (reg:CCFPU 17)
1046 (compare:CCFPU (match_operand 0 "register_operand" "f")
1047 (match_operand 1 "register_operand" "f")))]
1048 "TARGET_80387 && TARGET_CMOVE
1049 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1050 && FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp")
1054 (set (attr "mode")
1055 (cond [(match_operand:SF 1 "" "")
1056 (const_string "SF")
1057 (match_operand:DF 1 "" "")
1058 (const_string "DF")
1059 ]
1060 (const_string "XF")))
1061 (set_attr "athlon_decode" "vector")])
1062
1063 (define_insn "*cmpfp_iu_sse"
1064 [(set (reg:CCFPU 17)
1065 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1066 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1067 "TARGET_80387
1068 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1069 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070 "* return output_fp_compare (insn, operands, 1, 1);"
1071 [(set_attr "type" "fcmp,ssecomi")
1072 (set (attr "mode")
1073 (if_then_else (match_operand:SF 1 "" "")
1074 (const_string "SF")
1075 (const_string "DF")))
1076 (set_attr "athlon_decode" "vector")])
1077
1078 (define_insn "*cmpfp_iu_sse_only"
1079 [(set (reg:CCFPU 17)
1080 (compare:CCFPU (match_operand 0 "register_operand" "x")
1081 (match_operand 1 "nonimmediate_operand" "xm")))]
1082 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1083 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1084 "* return output_fp_compare (insn, operands, 1, 1);"
1085 [(set_attr "type" "ssecomi")
1086 (set (attr "mode")
1087 (if_then_else (match_operand:SF 1 "" "")
1088 (const_string "SF")
1089 (const_string "DF")))
1090 (set_attr "athlon_decode" "vector")])
1091 \f
1092 ;; Move instructions.
1093
1094 ;; General case of fullword move.
1095
1096 (define_expand "movsi"
1097 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1098 (match_operand:SI 1 "general_operand" ""))]
1099 ""
1100 "ix86_expand_move (SImode, operands); DONE;")
1101
1102 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1103 ;; general_operand.
1104 ;;
1105 ;; %%% We don't use a post-inc memory reference because x86 is not a
1106 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1107 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1108 ;; targets without our curiosities, and it is just as easy to represent
1109 ;; this differently.
1110
1111 (define_insn "*pushsi2"
1112 [(set (match_operand:SI 0 "push_operand" "=<")
1113 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1114 "!TARGET_64BIT"
1115 "push{l}\t%1"
1116 [(set_attr "type" "push")
1117 (set_attr "mode" "SI")])
1118
1119 ;; For 64BIT abi we always round up to 8 bytes.
1120 (define_insn "*pushsi2_rex64"
1121 [(set (match_operand:SI 0 "push_operand" "=X")
1122 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1123 "TARGET_64BIT"
1124 "push{q}\t%q1"
1125 [(set_attr "type" "push")
1126 (set_attr "mode" "SI")])
1127
1128 (define_insn "*pushsi2_prologue"
1129 [(set (match_operand:SI 0 "push_operand" "=<")
1130 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1131 (clobber (mem:BLK (scratch)))]
1132 "!TARGET_64BIT"
1133 "push{l}\t%1"
1134 [(set_attr "type" "push")
1135 (set_attr "mode" "SI")])
1136
1137 (define_insn "*popsi1_epilogue"
1138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139 (mem:SI (reg:SI 7)))
1140 (set (reg:SI 7)
1141 (plus:SI (reg:SI 7) (const_int 4)))
1142 (clobber (mem:BLK (scratch)))]
1143 "!TARGET_64BIT"
1144 "pop{l}\t%0"
1145 [(set_attr "type" "pop")
1146 (set_attr "mode" "SI")])
1147
1148 (define_insn "popsi1"
1149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150 (mem:SI (reg:SI 7)))
1151 (set (reg:SI 7)
1152 (plus:SI (reg:SI 7) (const_int 4)))]
1153 "!TARGET_64BIT"
1154 "pop{l}\t%0"
1155 [(set_attr "type" "pop")
1156 (set_attr "mode" "SI")])
1157
1158 (define_insn "*movsi_xor"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (match_operand:SI 1 "const0_operand" "i"))
1161 (clobber (reg:CC 17))]
1162 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1163 "xor{l}\t{%0, %0|%0, %0}"
1164 [(set_attr "type" "alu1")
1165 (set_attr "mode" "SI")
1166 (set_attr "length_immediate" "0")])
1167
1168 (define_insn "*movsi_or"
1169 [(set (match_operand:SI 0 "register_operand" "=r")
1170 (match_operand:SI 1 "immediate_operand" "i"))
1171 (clobber (reg:CC 17))]
1172 "reload_completed && GET_CODE (operands[1]) == CONST_INT
1173 && INTVAL (operands[1]) == -1
1174 && (TARGET_PENTIUM || optimize_size)"
1175 {
1176 operands[1] = constm1_rtx;
1177 return "or{l}\t{%1, %0|%0, %1}";
1178 }
1179 [(set_attr "type" "alu1")
1180 (set_attr "mode" "SI")
1181 (set_attr "length_immediate" "1")])
1182
1183 (define_insn "*movsi_1"
1184 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1185 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1186 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1187 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1188 {
1189 switch (get_attr_type (insn))
1190 {
1191 case TYPE_SSEMOV:
1192 if (get_attr_mode (insn) == MODE_TI)
1193 return "movdqa\t{%1, %0|%0, %1}";
1194 return "movd\t{%1, %0|%0, %1}";
1195
1196 case TYPE_MMXMOV:
1197 if (get_attr_mode (insn) == MODE_DI)
1198 return "movq\t{%1, %0|%0, %1}";
1199 return "movd\t{%1, %0|%0, %1}";
1200
1201 case TYPE_LEA:
1202 return "lea{l}\t{%1, %0|%0, %1}";
1203
1204 default:
1205 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1206 abort();
1207 return "mov{l}\t{%1, %0|%0, %1}";
1208 }
1209 }
1210 [(set (attr "type")
1211 (cond [(eq_attr "alternative" "2,3,4")
1212 (const_string "mmxmov")
1213 (eq_attr "alternative" "5,6,7")
1214 (const_string "ssemov")
1215 (and (ne (symbol_ref "flag_pic") (const_int 0))
1216 (match_operand:SI 1 "symbolic_operand" ""))
1217 (const_string "lea")
1218 ]
1219 (const_string "imov")))
1220 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1221
1222 (define_insn "*movsi_1_nointernunit"
1223 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1224 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1225 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1226 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1227 {
1228 switch (get_attr_type (insn))
1229 {
1230 case TYPE_SSEMOV:
1231 if (get_attr_mode (insn) == MODE_TI)
1232 return "movdqa\t{%1, %0|%0, %1}";
1233 return "movd\t{%1, %0|%0, %1}";
1234
1235 case TYPE_MMXMOV:
1236 if (get_attr_mode (insn) == MODE_DI)
1237 return "movq\t{%1, %0|%0, %1}";
1238 return "movd\t{%1, %0|%0, %1}";
1239
1240 case TYPE_LEA:
1241 return "lea{l}\t{%1, %0|%0, %1}";
1242
1243 default:
1244 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1245 abort();
1246 return "mov{l}\t{%1, %0|%0, %1}";
1247 }
1248 }
1249 [(set (attr "type")
1250 (cond [(eq_attr "alternative" "2,3,4")
1251 (const_string "mmxmov")
1252 (eq_attr "alternative" "5,6,7")
1253 (const_string "ssemov")
1254 (and (ne (symbol_ref "flag_pic") (const_int 0))
1255 (match_operand:SI 1 "symbolic_operand" ""))
1256 (const_string "lea")
1257 ]
1258 (const_string "imov")))
1259 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1260
1261 ;; Stores and loads of ax to arbitrary constant address.
1262 ;; We fake an second form of instruction to force reload to load address
1263 ;; into register when rax is not available
1264 (define_insn "*movabssi_1_rex64"
1265 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1266 (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1267 "TARGET_64BIT"
1268 "@
1269 movabs{l}\t{%1, %P0|%P0, %1}
1270 mov{l}\t{%1, %a0|%a0, %1}
1271 movabs{l}\t{%1, %a0|%a0, %1}"
1272 [(set_attr "type" "imov")
1273 (set_attr "modrm" "0,*,*")
1274 (set_attr "length_address" "8,0,0")
1275 (set_attr "length_immediate" "0,*,*")
1276 (set_attr "memory" "store")
1277 (set_attr "mode" "SI")])
1278
1279 (define_insn "*movabssi_2_rex64"
1280 [(set (match_operand:SI 0 "register_operand" "=a,r")
1281 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1282 "TARGET_64BIT"
1283 "@
1284 movabs{l}\t{%P1, %0|%0, %P1}
1285 mov{l}\t{%a1, %0|%0, %a1}"
1286 [(set_attr "type" "imov")
1287 (set_attr "modrm" "0,*")
1288 (set_attr "length_address" "8,0")
1289 (set_attr "length_immediate" "0")
1290 (set_attr "memory" "load")
1291 (set_attr "mode" "SI")])
1292
1293 (define_insn "*swapsi"
1294 [(set (match_operand:SI 0 "register_operand" "+r")
1295 (match_operand:SI 1 "register_operand" "+r"))
1296 (set (match_dup 1)
1297 (match_dup 0))]
1298 ""
1299 "xchg{l}\t%1, %0"
1300 [(set_attr "type" "imov")
1301 (set_attr "pent_pair" "np")
1302 (set_attr "athlon_decode" "vector")
1303 (set_attr "mode" "SI")
1304 (set_attr "modrm" "0")
1305 (set_attr "ppro_uops" "few")])
1306
1307 (define_expand "movhi"
1308 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1309 (match_operand:HI 1 "general_operand" ""))]
1310 ""
1311 "ix86_expand_move (HImode, operands); DONE;")
1312
1313 (define_insn "*pushhi2"
1314 [(set (match_operand:HI 0 "push_operand" "=<,<")
1315 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1316 "!TARGET_64BIT"
1317 "@
1318 push{w}\t{|WORD PTR }%1
1319 push{w}\t%1"
1320 [(set_attr "type" "push")
1321 (set_attr "mode" "HI")])
1322
1323 ;; For 64BIT abi we always round up to 8 bytes.
1324 (define_insn "*pushhi2_rex64"
1325 [(set (match_operand:HI 0 "push_operand" "=X")
1326 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1327 "TARGET_64BIT"
1328 "push{q}\t%q1"
1329 [(set_attr "type" "push")
1330 (set_attr "mode" "QI")])
1331
1332 (define_insn "*movhi_1"
1333 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1334 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1335 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1336 {
1337 switch (get_attr_type (insn))
1338 {
1339 case TYPE_IMOVX:
1340 /* movzwl is faster than movw on p2 due to partial word stalls,
1341 though not as fast as an aligned movl. */
1342 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1343 default:
1344 if (get_attr_mode (insn) == MODE_SI)
1345 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1346 else
1347 return "mov{w}\t{%1, %0|%0, %1}";
1348 }
1349 }
1350 [(set (attr "type")
1351 (cond [(and (eq_attr "alternative" "0")
1352 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1353 (const_int 0))
1354 (eq (symbol_ref "TARGET_HIMODE_MATH")
1355 (const_int 0))))
1356 (const_string "imov")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1359 (const_string "imov")
1360 (and (ne (symbol_ref "TARGET_MOVX")
1361 (const_int 0))
1362 (eq_attr "alternative" "0,2"))
1363 (const_string "imovx")
1364 ]
1365 (const_string "imov")))
1366 (set (attr "mode")
1367 (cond [(eq_attr "type" "imovx")
1368 (const_string "SI")
1369 (and (eq_attr "alternative" "1,2")
1370 (match_operand:HI 1 "aligned_operand" ""))
1371 (const_string "SI")
1372 (and (eq_attr "alternative" "0")
1373 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1374 (const_int 0))
1375 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_int 0))))
1377 (const_string "SI")
1378 ]
1379 (const_string "HI")))])
1380
1381 ;; Stores and loads of ax to arbitrary constant address.
1382 ;; We fake an second form of instruction to force reload to load address
1383 ;; into register when rax is not available
1384 (define_insn "*movabshi_1_rex64"
1385 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1386 (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1387 "TARGET_64BIT"
1388 "@
1389 movabs{w}\t{%1, %P0|%P0, %1}
1390 mov{w}\t{%1, %a0|%a0, %1}
1391 movabs{w}\t{%1, %a0|%a0, %1}"
1392 [(set_attr "type" "imov")
1393 (set_attr "modrm" "0,*,*")
1394 (set_attr "length_address" "8,0,0")
1395 (set_attr "length_immediate" "0,*,*")
1396 (set_attr "memory" "store")
1397 (set_attr "mode" "HI")])
1398
1399 (define_insn "*movabshi_2_rex64"
1400 [(set (match_operand:HI 0 "register_operand" "=a,r")
1401 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1402 "TARGET_64BIT"
1403 "@
1404 movabs{w}\t{%P1, %0|%0, %P1}
1405 mov{w}\t{%a1, %0|%0, %a1}"
1406 [(set_attr "type" "imov")
1407 (set_attr "modrm" "0,*")
1408 (set_attr "length_address" "8,0")
1409 (set_attr "length_immediate" "0")
1410 (set_attr "memory" "load")
1411 (set_attr "mode" "HI")])
1412
1413 (define_insn "*swaphi_1"
1414 [(set (match_operand:HI 0 "register_operand" "+r")
1415 (match_operand:HI 1 "register_operand" "+r"))
1416 (set (match_dup 1)
1417 (match_dup 0))]
1418 "TARGET_PARTIAL_REG_STALL"
1419 "xchg{w}\t%1, %0"
1420 [(set_attr "type" "imov")
1421 (set_attr "pent_pair" "np")
1422 (set_attr "mode" "HI")
1423 (set_attr "modrm" "0")
1424 (set_attr "ppro_uops" "few")])
1425
1426 (define_insn "*swaphi_2"
1427 [(set (match_operand:HI 0 "register_operand" "+r")
1428 (match_operand:HI 1 "register_operand" "+r"))
1429 (set (match_dup 1)
1430 (match_dup 0))]
1431 "! TARGET_PARTIAL_REG_STALL"
1432 "xchg{l}\t%k1, %k0"
1433 [(set_attr "type" "imov")
1434 (set_attr "pent_pair" "np")
1435 (set_attr "mode" "SI")
1436 (set_attr "modrm" "0")
1437 (set_attr "ppro_uops" "few")])
1438
1439 (define_expand "movstricthi"
1440 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1441 (match_operand:HI 1 "general_operand" ""))]
1442 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1443 {
1444 /* Don't generate memory->memory moves, go through a register */
1445 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1446 operands[1] = force_reg (HImode, operands[1]);
1447 })
1448
1449 (define_insn "*movstricthi_1"
1450 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1451 (match_operand:HI 1 "general_operand" "rn,m"))]
1452 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1453 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1454 "mov{w}\t{%1, %0|%0, %1}"
1455 [(set_attr "type" "imov")
1456 (set_attr "mode" "HI")])
1457
1458 (define_insn "*movstricthi_xor"
1459 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1460 (match_operand:HI 1 "const0_operand" "i"))
1461 (clobber (reg:CC 17))]
1462 "reload_completed
1463 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1464 "xor{w}\t{%0, %0|%0, %0}"
1465 [(set_attr "type" "alu1")
1466 (set_attr "mode" "HI")
1467 (set_attr "length_immediate" "0")])
1468
1469 (define_expand "movqi"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1471 (match_operand:QI 1 "general_operand" ""))]
1472 ""
1473 "ix86_expand_move (QImode, operands); DONE;")
1474
1475 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1476 ;; "push a byte". But actually we use pushw, which has the effect
1477 ;; of rounding the amount pushed up to a halfword.
1478
1479 (define_insn "*pushqi2"
1480 [(set (match_operand:QI 0 "push_operand" "=X,X")
1481 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1482 "!TARGET_64BIT"
1483 "@
1484 push{w}\t{|word ptr }%1
1485 push{w}\t%w1"
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "HI")])
1488
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491 [(set (match_operand:QI 0 "push_operand" "=X")
1492 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1493 "TARGET_64BIT"
1494 "push{q}\t%q1"
1495 [(set_attr "type" "push")
1496 (set_attr "mode" "QI")])
1497
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1503 ;; instruction).
1504 ;;
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there. Then we use movzx.
1508 (define_insn "*movqi_1"
1509 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1511 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1512 {
1513 switch (get_attr_type (insn))
1514 {
1515 case TYPE_IMOVX:
1516 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1517 abort ();
1518 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1519 default:
1520 if (get_attr_mode (insn) == MODE_SI)
1521 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1522 else
1523 return "mov{b}\t{%1, %0|%0, %1}";
1524 }
1525 }
1526 [(set (attr "type")
1527 (cond [(and (eq_attr "alternative" "3")
1528 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1529 (const_int 0))
1530 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_int 0))))
1532 (const_string "imov")
1533 (eq_attr "alternative" "3,5")
1534 (const_string "imovx")
1535 (and (ne (symbol_ref "TARGET_MOVX")
1536 (const_int 0))
1537 (eq_attr "alternative" "2"))
1538 (const_string "imovx")
1539 ]
1540 (const_string "imov")))
1541 (set (attr "mode")
1542 (cond [(eq_attr "alternative" "3,4,5")
1543 (const_string "SI")
1544 (eq_attr "alternative" "6")
1545 (const_string "QI")
1546 (eq_attr "type" "imovx")
1547 (const_string "SI")
1548 (and (eq_attr "type" "imov")
1549 (and (eq_attr "alternative" "0,1,2")
1550 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1551 (const_int 0))))
1552 (const_string "SI")
1553 ;; Avoid partial register stalls when not using QImode arithmetic
1554 (and (eq_attr "type" "imov")
1555 (and (eq_attr "alternative" "0,1,2")
1556 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1557 (const_int 0))
1558 (eq (symbol_ref "TARGET_QIMODE_MATH")
1559 (const_int 0)))))
1560 (const_string "SI")
1561 ]
1562 (const_string "QI")))])
1563
1564 (define_expand "reload_outqi"
1565 [(parallel [(match_operand:QI 0 "" "=m")
1566 (match_operand:QI 1 "register_operand" "r")
1567 (match_operand:QI 2 "register_operand" "=&q")])]
1568 ""
1569 {
1570 rtx op0, op1, op2;
1571 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1572
1573 if (reg_overlap_mentioned_p (op2, op0))
1574 abort ();
1575 if (! q_regs_operand (op1, QImode))
1576 {
1577 emit_insn (gen_movqi (op2, op1));
1578 op1 = op2;
1579 }
1580 emit_insn (gen_movqi (op0, op1));
1581 DONE;
1582 })
1583
1584 (define_insn "*swapqi"
1585 [(set (match_operand:QI 0 "register_operand" "+r")
1586 (match_operand:QI 1 "register_operand" "+r"))
1587 (set (match_dup 1)
1588 (match_dup 0))]
1589 ""
1590 "xchg{b}\t%1, %0"
1591 [(set_attr "type" "imov")
1592 (set_attr "pent_pair" "np")
1593 (set_attr "mode" "QI")
1594 (set_attr "modrm" "0")
1595 (set_attr "ppro_uops" "few")])
1596
1597 (define_expand "movstrictqi"
1598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1599 (match_operand:QI 1 "general_operand" ""))]
1600 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1601 {
1602 /* Don't generate memory->memory moves, go through a register. */
1603 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1604 operands[1] = force_reg (QImode, operands[1]);
1605 })
1606
1607 (define_insn "*movstrictqi_1"
1608 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1609 (match_operand:QI 1 "general_operand" "*qn,m"))]
1610 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1611 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1612 "mov{b}\t{%1, %0|%0, %1}"
1613 [(set_attr "type" "imov")
1614 (set_attr "mode" "QI")])
1615
1616 (define_insn "*movstrictqi_xor"
1617 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1618 (match_operand:QI 1 "const0_operand" "i"))
1619 (clobber (reg:CC 17))]
1620 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1621 "xor{b}\t{%0, %0|%0, %0}"
1622 [(set_attr "type" "alu1")
1623 (set_attr "mode" "QI")
1624 (set_attr "length_immediate" "0")])
1625
1626 (define_insn "*movsi_extv_1"
1627 [(set (match_operand:SI 0 "register_operand" "=R")
1628 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1629 (const_int 8)
1630 (const_int 8)))]
1631 ""
1632 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1633 [(set_attr "type" "imovx")
1634 (set_attr "mode" "SI")])
1635
1636 (define_insn "*movhi_extv_1"
1637 [(set (match_operand:HI 0 "register_operand" "=R")
1638 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1639 (const_int 8)
1640 (const_int 8)))]
1641 ""
1642 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1643 [(set_attr "type" "imovx")
1644 (set_attr "mode" "SI")])
1645
1646 (define_insn "*movqi_extv_1"
1647 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1648 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1649 (const_int 8)
1650 (const_int 8)))]
1651 "!TARGET_64BIT"
1652 {
1653 switch (get_attr_type (insn))
1654 {
1655 case TYPE_IMOVX:
1656 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1657 default:
1658 return "mov{b}\t{%h1, %0|%0, %h1}";
1659 }
1660 }
1661 [(set (attr "type")
1662 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1663 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1664 (ne (symbol_ref "TARGET_MOVX")
1665 (const_int 0))))
1666 (const_string "imovx")
1667 (const_string "imov")))
1668 (set (attr "mode")
1669 (if_then_else (eq_attr "type" "imovx")
1670 (const_string "SI")
1671 (const_string "QI")))])
1672
1673 (define_insn "*movqi_extv_1_rex64"
1674 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1675 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1676 (const_int 8)
1677 (const_int 8)))]
1678 "TARGET_64BIT"
1679 {
1680 switch (get_attr_type (insn))
1681 {
1682 case TYPE_IMOVX:
1683 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1684 default:
1685 return "mov{b}\t{%h1, %0|%0, %h1}";
1686 }
1687 }
1688 [(set (attr "type")
1689 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1690 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1691 (ne (symbol_ref "TARGET_MOVX")
1692 (const_int 0))))
1693 (const_string "imovx")
1694 (const_string "imov")))
1695 (set (attr "mode")
1696 (if_then_else (eq_attr "type" "imovx")
1697 (const_string "SI")
1698 (const_string "QI")))])
1699
1700 ;; Stores and loads of ax to arbitrary constant address.
1701 ;; We fake an second form of instruction to force reload to load address
1702 ;; into register when rax is not available
1703 (define_insn "*movabsqi_1_rex64"
1704 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1705 (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1706 "TARGET_64BIT"
1707 "@
1708 movabs{b}\t{%1, %P0|%P0, %1}
1709 mov{b}\t{%1, %a0|%a0, %1}
1710 movabs{b}\t{%1, %a0|%a0, %1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*,*")
1713 (set_attr "length_address" "8,0,0")
1714 (set_attr "length_immediate" "0,*,*")
1715 (set_attr "memory" "store")
1716 (set_attr "mode" "QI")])
1717
1718 (define_insn "*movabsqi_2_rex64"
1719 [(set (match_operand:QI 0 "register_operand" "=a,r")
1720 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1721 "TARGET_64BIT"
1722 "@
1723 movabs{b}\t{%P1, %0|%0, %P1}
1724 mov{b}\t{%a1, %0|%0, %a1}"
1725 [(set_attr "type" "imov")
1726 (set_attr "modrm" "0,*")
1727 (set_attr "length_address" "8,0")
1728 (set_attr "length_immediate" "0")
1729 (set_attr "memory" "load")
1730 (set_attr "mode" "QI")])
1731
1732 (define_insn "*movsi_extzv_1"
1733 [(set (match_operand:SI 0 "register_operand" "=R")
1734 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1735 (const_int 8)
1736 (const_int 8)))]
1737 ""
1738 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1739 [(set_attr "type" "imovx")
1740 (set_attr "mode" "SI")])
1741
1742 (define_insn "*movqi_extzv_2"
1743 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1744 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1745 (const_int 8)
1746 (const_int 8)) 0))]
1747 "!TARGET_64BIT"
1748 {
1749 switch (get_attr_type (insn))
1750 {
1751 case TYPE_IMOVX:
1752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1753 default:
1754 return "mov{b}\t{%h1, %0|%0, %h1}";
1755 }
1756 }
1757 [(set (attr "type")
1758 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1759 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1760 (ne (symbol_ref "TARGET_MOVX")
1761 (const_int 0))))
1762 (const_string "imovx")
1763 (const_string "imov")))
1764 (set (attr "mode")
1765 (if_then_else (eq_attr "type" "imovx")
1766 (const_string "SI")
1767 (const_string "QI")))])
1768
1769 (define_insn "*movqi_extzv_2_rex64"
1770 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1771 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 (const_int 8)
1773 (const_int 8)) 0))]
1774 "TARGET_64BIT"
1775 {
1776 switch (get_attr_type (insn))
1777 {
1778 case TYPE_IMOVX:
1779 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1780 default:
1781 return "mov{b}\t{%h1, %0|%0, %h1}";
1782 }
1783 }
1784 [(set (attr "type")
1785 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1786 (ne (symbol_ref "TARGET_MOVX")
1787 (const_int 0)))
1788 (const_string "imovx")
1789 (const_string "imov")))
1790 (set (attr "mode")
1791 (if_then_else (eq_attr "type" "imovx")
1792 (const_string "SI")
1793 (const_string "QI")))])
1794
1795 (define_insn "movsi_insv_1"
1796 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1797 (const_int 8)
1798 (const_int 8))
1799 (match_operand:SI 1 "general_operand" "Qmn"))]
1800 "!TARGET_64BIT"
1801 "mov{b}\t{%b1, %h0|%h0, %b1}"
1802 [(set_attr "type" "imov")
1803 (set_attr "mode" "QI")])
1804
1805 (define_insn "*movsi_insv_1_rex64"
1806 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (const_int 8)
1808 (const_int 8))
1809 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1810 "TARGET_64BIT"
1811 "mov{b}\t{%b1, %h0|%h0, %b1}"
1812 [(set_attr "type" "imov")
1813 (set_attr "mode" "QI")])
1814
1815 (define_insn "*movqi_insv_2"
1816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1817 (const_int 8)
1818 (const_int 8))
1819 (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1820 (const_int 8))
1821 (const_int 255)))]
1822 ""
1823 "mov{b}\t{%h1, %h0|%h0, %h1}"
1824 [(set_attr "type" "imov")
1825 (set_attr "mode" "QI")])
1826
1827 (define_expand "movdi"
1828 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1829 (match_operand:DI 1 "general_operand" ""))]
1830 ""
1831 "ix86_expand_move (DImode, operands); DONE;")
1832
1833 (define_insn "*pushdi"
1834 [(set (match_operand:DI 0 "push_operand" "=<")
1835 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1836 "!TARGET_64BIT"
1837 "#")
1838
1839 (define_insn "pushdi2_rex64"
1840 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1841 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1842 "TARGET_64BIT"
1843 "@
1844 push{q}\t%1
1845 #"
1846 [(set_attr "type" "push,multi")
1847 (set_attr "mode" "DI")])
1848
1849 ;; Convert impossible pushes of immediate to existing instructions.
1850 ;; First try to get scratch register and go through it. In case this
1851 ;; fails, push sign extended lower part first and then overwrite
1852 ;; upper part by 32bit move.
1853 (define_peephole2
1854 [(match_scratch:DI 2 "r")
1855 (set (match_operand:DI 0 "push_operand" "")
1856 (match_operand:DI 1 "immediate_operand" ""))]
1857 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1858 && !x86_64_immediate_operand (operands[1], DImode)"
1859 [(set (match_dup 2) (match_dup 1))
1860 (set (match_dup 0) (match_dup 2))]
1861 "")
1862
1863 ;; We need to define this as both peepholer and splitter for case
1864 ;; peephole2 pass is not run.
1865 (define_peephole2
1866 [(set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1870 [(set (match_dup 0) (match_dup 1))
1871 (set (match_dup 2) (match_dup 3))]
1872 "split_di (operands + 1, 1, operands + 2, operands + 3);
1873 operands[1] = gen_lowpart (DImode, operands[2]);
1874 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1875 GEN_INT (4)));
1876 ")
1877
1878 (define_split
1879 [(set (match_operand:DI 0 "push_operand" "")
1880 (match_operand:DI 1 "immediate_operand" ""))]
1881 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1882 && !symbolic_operand (operands[1], DImode)
1883 && !x86_64_immediate_operand (operands[1], DImode)"
1884 [(set (match_dup 0) (match_dup 1))
1885 (set (match_dup 2) (match_dup 3))]
1886 "split_di (operands + 1, 1, operands + 2, operands + 3);
1887 operands[1] = gen_lowpart (DImode, operands[2]);
1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889 GEN_INT (4)));
1890 ")
1891
1892 (define_insn "*pushdi2_prologue_rex64"
1893 [(set (match_operand:DI 0 "push_operand" "=<")
1894 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1895 (clobber (mem:BLK (scratch)))]
1896 "TARGET_64BIT"
1897 "push{q}\t%1"
1898 [(set_attr "type" "push")
1899 (set_attr "mode" "DI")])
1900
1901 (define_insn "*popdi1_epilogue_rex64"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI 7)))
1904 (set (reg:DI 7)
1905 (plus:DI (reg:DI 7) (const_int 8)))
1906 (clobber (mem:BLK (scratch)))]
1907 "TARGET_64BIT"
1908 "pop{q}\t%0"
1909 [(set_attr "type" "pop")
1910 (set_attr "mode" "DI")])
1911
1912 (define_insn "popdi1"
1913 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1914 (mem:DI (reg:DI 7)))
1915 (set (reg:DI 7)
1916 (plus:DI (reg:DI 7) (const_int 8)))]
1917 "TARGET_64BIT"
1918 "pop{q}\t%0"
1919 [(set_attr "type" "pop")
1920 (set_attr "mode" "DI")])
1921
1922 (define_insn "*movdi_xor_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const0_operand" "i"))
1925 (clobber (reg:CC 17))]
1926 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1927 && reload_completed"
1928 "xor{l}\t{%k0, %k0|%k0, %k0}"
1929 [(set_attr "type" "alu1")
1930 (set_attr "mode" "SI")
1931 (set_attr "length_immediate" "0")])
1932
1933 (define_insn "*movdi_or_rex64"
1934 [(set (match_operand:DI 0 "register_operand" "=r")
1935 (match_operand:DI 1 "const_int_operand" "i"))
1936 (clobber (reg:CC 17))]
1937 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1938 && reload_completed
1939 && GET_CODE (operands[1]) == CONST_INT
1940 && INTVAL (operands[1]) == -1"
1941 {
1942 operands[1] = constm1_rtx;
1943 return "or{q}\t{%1, %0|%0, %1}";
1944 }
1945 [(set_attr "type" "alu1")
1946 (set_attr "mode" "DI")
1947 (set_attr "length_immediate" "1")])
1948
1949 (define_insn "*movdi_2"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1951 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1952 "!TARGET_64BIT
1953 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1954 "@
1955 #
1956 #
1957 movq\t{%1, %0|%0, %1}
1958 movq\t{%1, %0|%0, %1}
1959 movq\t{%1, %0|%0, %1}
1960 movdqa\t{%1, %0|%0, %1}
1961 movq\t{%1, %0|%0, %1}"
1962 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1963 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1964
1965 (define_split
1966 [(set (match_operand:DI 0 "push_operand" "")
1967 (match_operand:DI 1 "general_operand" ""))]
1968 "!TARGET_64BIT && reload_completed
1969 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1970 [(const_int 0)]
1971 "ix86_split_long_move (operands); DONE;")
1972
1973 ;; %%% This multiword shite has got to go.
1974 (define_split
1975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1976 (match_operand:DI 1 "general_operand" ""))]
1977 "!TARGET_64BIT && reload_completed
1978 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1979 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980 [(const_int 0)]
1981 "ix86_split_long_move (operands); DONE;")
1982
1983 (define_insn "*movdi_1_rex64"
1984 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1985 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1986 "TARGET_64BIT
1987 && (TARGET_INTER_UNIT_MOVES || optimize_size)
1988 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1989 {
1990 switch (get_attr_type (insn))
1991 {
1992 case TYPE_SSEMOV:
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1995 /* FALLTHRU */
1996 case TYPE_MMXMOV:
1997 /* Moves from and into integer register is done using movd opcode with
1998 REX prefix. */
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2002 case TYPE_MULTI:
2003 return "#";
2004 case TYPE_LEA:
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2006 default:
2007 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2008 abort ();
2009 if (get_attr_mode (insn) == MODE_SI)
2010 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2011 else if (which_alternative == 2)
2012 return "movabs{q}\t{%1, %0|%0, %1}";
2013 else
2014 return "mov{q}\t{%1, %0|%0, %1}";
2015 }
2016 }
2017 [(set (attr "type")
2018 (cond [(eq_attr "alternative" "5,6,7")
2019 (const_string "mmxmov")
2020 (eq_attr "alternative" "8,9,10")
2021 (const_string "ssemov")
2022 (eq_attr "alternative" "4")
2023 (const_string "multi")
2024 (and (ne (symbol_ref "flag_pic") (const_int 0))
2025 (match_operand:DI 1 "symbolic_operand" ""))
2026 (const_string "lea")
2027 ]
2028 (const_string "imov")))
2029 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2030 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2031 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2032
2033 (define_insn "*movdi_1_rex64_nointerunit"
2034 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2035 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2036 "TARGET_64BIT
2037 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2038 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2039 {
2040 switch (get_attr_type (insn))
2041 {
2042 case TYPE_SSEMOV:
2043 if (get_attr_mode (insn) == MODE_TI)
2044 return "movdqa\t{%1, %0|%0, %1}";
2045 /* FALLTHRU */
2046 case TYPE_MMXMOV:
2047 return "movq\t{%1, %0|%0, %1}";
2048 case TYPE_MULTI:
2049 return "#";
2050 case TYPE_LEA:
2051 return "lea{q}\t{%a1, %0|%0, %a1}";
2052 default:
2053 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2054 abort ();
2055 if (get_attr_mode (insn) == MODE_SI)
2056 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2057 else if (which_alternative == 2)
2058 return "movabs{q}\t{%1, %0|%0, %1}";
2059 else
2060 return "mov{q}\t{%1, %0|%0, %1}";
2061 }
2062 }
2063 [(set (attr "type")
2064 (cond [(eq_attr "alternative" "5,6,7")
2065 (const_string "mmxmov")
2066 (eq_attr "alternative" "8,9,10")
2067 (const_string "ssemov")
2068 (eq_attr "alternative" "4")
2069 (const_string "multi")
2070 (and (ne (symbol_ref "flag_pic") (const_int 0))
2071 (match_operand:DI 1 "symbolic_operand" ""))
2072 (const_string "lea")
2073 ]
2074 (const_string "imov")))
2075 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2076 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2077 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2078
2079 ;; Stores and loads of ax to arbitrary constant address.
2080 ;; We fake an second form of instruction to force reload to load address
2081 ;; into register when rax is not available
2082 (define_insn "*movabsdi_1_rex64"
2083 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2084 (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2085 "TARGET_64BIT"
2086 "@
2087 movabs{q}\t{%1, %P0|%P0, %1}
2088 mov{q}\t{%1, %a0|%a0, %1}
2089 movabs{q}\t{%1, %a0|%a0, %1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "modrm" "0,*,*")
2092 (set_attr "length_address" "8,0,0")
2093 (set_attr "length_immediate" "0,*,*")
2094 (set_attr "memory" "store")
2095 (set_attr "mode" "DI")])
2096
2097 (define_insn "*movabsdi_2_rex64"
2098 [(set (match_operand:DI 0 "register_operand" "=a,r")
2099 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2100 "TARGET_64BIT"
2101 "@
2102 movabs{q}\t{%P1, %0|%0, %P1}
2103 mov{q}\t{%a1, %0|%0, %a1}"
2104 [(set_attr "type" "imov")
2105 (set_attr "modrm" "0,*")
2106 (set_attr "length_address" "8,0")
2107 (set_attr "length_immediate" "0")
2108 (set_attr "memory" "load")
2109 (set_attr "mode" "DI")])
2110
2111 ;; Convert impossible stores of immediate to existing instructions.
2112 ;; First try to get scratch register and go through it. In case this
2113 ;; fails, move by 32bit parts.
2114 (define_peephole2
2115 [(match_scratch:DI 2 "r")
2116 (set (match_operand:DI 0 "memory_operand" "")
2117 (match_operand:DI 1 "immediate_operand" ""))]
2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119 && !x86_64_immediate_operand (operands[1], DImode)"
2120 [(set (match_dup 2) (match_dup 1))
2121 (set (match_dup 0) (match_dup 2))]
2122 "")
2123
2124 ;; We need to define this as both peepholer and splitter for case
2125 ;; peephole2 pass is not run.
2126 (define_peephole2
2127 [(set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2131 [(set (match_dup 2) (match_dup 3))
2132 (set (match_dup 4) (match_dup 5))]
2133 "split_di (operands, 2, operands + 2, operands + 4);")
2134
2135 (define_split
2136 [(set (match_operand:DI 0 "memory_operand" "")
2137 (match_operand:DI 1 "immediate_operand" ""))]
2138 "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_di (operands, 2, operands + 2, operands + 4);")
2144
2145 (define_insn "*swapdi_rex64"
2146 [(set (match_operand:DI 0 "register_operand" "+r")
2147 (match_operand:DI 1 "register_operand" "+r"))
2148 (set (match_dup 1)
2149 (match_dup 0))]
2150 "TARGET_64BIT"
2151 "xchg{q}\t%1, %0"
2152 [(set_attr "type" "imov")
2153 (set_attr "pent_pair" "np")
2154 (set_attr "athlon_decode" "vector")
2155 (set_attr "mode" "DI")
2156 (set_attr "modrm" "0")
2157 (set_attr "ppro_uops" "few")])
2158
2159
2160 (define_expand "movsf"
2161 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2162 (match_operand:SF 1 "general_operand" ""))]
2163 ""
2164 "ix86_expand_move (SFmode, operands); DONE;")
2165
2166 (define_insn "*pushsf"
2167 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2168 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2169 "!TARGET_64BIT"
2170 {
2171 switch (which_alternative)
2172 {
2173 case 1:
2174 return "push{l}\t%1";
2175
2176 default:
2177 /* This insn should be already splitted before reg-stack. */
2178 abort ();
2179 }
2180 }
2181 [(set_attr "type" "multi,push,multi")
2182 (set_attr "mode" "SF,SI,SF")])
2183
2184 (define_insn "*pushsf_rex64"
2185 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2186 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2187 "TARGET_64BIT"
2188 {
2189 switch (which_alternative)
2190 {
2191 case 1:
2192 return "push{q}\t%q1";
2193
2194 default:
2195 /* This insn should be already splitted before reg-stack. */
2196 abort ();
2197 }
2198 }
2199 [(set_attr "type" "multi,push,multi")
2200 (set_attr "mode" "SF,DI,SF")])
2201
2202 (define_split
2203 [(set (match_operand:SF 0 "push_operand" "")
2204 (match_operand:SF 1 "memory_operand" ""))]
2205 "reload_completed
2206 && GET_CODE (operands[1]) == MEM
2207 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2208 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2209 [(set (match_dup 0)
2210 (match_dup 1))]
2211 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2212
2213
2214 ;; %%% Kill this when call knows how to work this out.
2215 (define_split
2216 [(set (match_operand:SF 0 "push_operand" "")
2217 (match_operand:SF 1 "any_fp_register_operand" ""))]
2218 "!TARGET_64BIT"
2219 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2220 (set (mem:SF (reg:SI 7)) (match_dup 1))])
2221
2222 (define_split
2223 [(set (match_operand:SF 0 "push_operand" "")
2224 (match_operand:SF 1 "any_fp_register_operand" ""))]
2225 "TARGET_64BIT"
2226 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2227 (set (mem:SF (reg:DI 7)) (match_dup 1))])
2228
2229 (define_insn "*movsf_1"
2230 [(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")
2231 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2232 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2234 && (reload_in_progress || reload_completed
2235 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2236 || GET_CODE (operands[1]) != CONST_DOUBLE
2237 || memory_operand (operands[0], SFmode))"
2238 {
2239 switch (which_alternative)
2240 {
2241 case 0:
2242 if (REG_P (operands[1])
2243 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2244 return "fstp\t%y0";
2245 else if (STACK_TOP_P (operands[0]))
2246 return "fld%z1\t%y1";
2247 else
2248 return "fst\t%y0";
2249
2250 case 1:
2251 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2252 return "fstp%z0\t%y0";
2253 else
2254 return "fst%z0\t%y0";
2255
2256 case 2:
2257 return standard_80387_constant_opcode (operands[1]);
2258
2259 case 3:
2260 case 4:
2261 return "mov{l}\t{%1, %0|%0, %1}";
2262 case 5:
2263 if (get_attr_mode (insn) == MODE_TI)
2264 return "pxor\t%0, %0";
2265 else
2266 return "xorps\t%0, %0";
2267 case 6:
2268 if (get_attr_mode (insn) == MODE_V4SF)
2269 return "movaps\t{%1, %0|%0, %1}";
2270 else
2271 return "movss\t{%1, %0|%0, %1}";
2272 case 7:
2273 case 8:
2274 return "movss\t{%1, %0|%0, %1}";
2275
2276 case 9:
2277 case 10:
2278 return "movd\t{%1, %0|%0, %1}";
2279
2280 case 11:
2281 return "movq\t{%1, %0|%0, %1}";
2282
2283 default:
2284 abort();
2285 }
2286 }
2287 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2288 (set (attr "mode")
2289 (cond [(eq_attr "alternative" "3,4,9,10")
2290 (const_string "SI")
2291 (eq_attr "alternative" "5")
2292 (if_then_else
2293 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2294 (const_int 0))
2295 (ne (symbol_ref "TARGET_SSE2")
2296 (const_int 0)))
2297 (eq (symbol_ref "optimize_size")
2298 (const_int 0)))
2299 (const_string "TI")
2300 (const_string "V4SF"))
2301 /* For architectures resolving dependencies on
2302 whole SSE registers use APS move to break dependency
2303 chains, otherwise use short move to avoid extra work.
2304
2305 Do the same for architectures resolving dependencies on
2306 the parts. While in DF mode it is better to always handle
2307 just register parts, the SF mode is different due to lack
2308 of instructions to load just part of the register. It is
2309 better to maintain the whole registers in single format
2310 to avoid problems on using packed logical operations. */
2311 (eq_attr "alternative" "6")
2312 (if_then_else
2313 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2314 (const_int 0))
2315 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2316 (const_int 0)))
2317 (const_string "V4SF")
2318 (const_string "SF"))
2319 (eq_attr "alternative" "11")
2320 (const_string "DI")]
2321 (const_string "SF")))])
2322
2323 (define_insn "*movsf_1_nointerunit"
2324 [(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")
2325 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2326 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2327 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2328 && (reload_in_progress || reload_completed
2329 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2330 || GET_CODE (operands[1]) != CONST_DOUBLE
2331 || memory_operand (operands[0], SFmode))"
2332 {
2333 switch (which_alternative)
2334 {
2335 case 0:
2336 if (REG_P (operands[1])
2337 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2338 {
2339 if (REGNO (operands[0]) == FIRST_STACK_REG
2340 && TARGET_USE_FFREEP)
2341 return "ffreep\t%y0";
2342 return "fstp\t%y0";
2343 }
2344 else if (STACK_TOP_P (operands[0]))
2345 return "fld%z1\t%y1";
2346 else
2347 return "fst\t%y0";
2348
2349 case 1:
2350 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2351 return "fstp%z0\t%y0";
2352 else
2353 return "fst%z0\t%y0";
2354
2355 case 2:
2356 return standard_80387_constant_opcode (operands[1]);
2357
2358 case 3:
2359 case 4:
2360 return "mov{l}\t{%1, %0|%0, %1}";
2361 case 5:
2362 if (get_attr_mode (insn) == MODE_TI)
2363 return "pxor\t%0, %0";
2364 else
2365 return "xorps\t%0, %0";
2366 case 6:
2367 if (get_attr_mode (insn) == MODE_V4SF)
2368 return "movaps\t{%1, %0|%0, %1}";
2369 else
2370 return "movss\t{%1, %0|%0, %1}";
2371 case 7:
2372 case 8:
2373 return "movss\t{%1, %0|%0, %1}";
2374
2375 case 9:
2376 case 10:
2377 return "movd\t{%1, %0|%0, %1}";
2378
2379 case 11:
2380 return "movq\t{%1, %0|%0, %1}";
2381
2382 default:
2383 abort();
2384 }
2385 }
2386 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2387 (set (attr "mode")
2388 (cond [(eq_attr "alternative" "3,4,9,10")
2389 (const_string "SI")
2390 (eq_attr "alternative" "5")
2391 (if_then_else
2392 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2393 (const_int 0))
2394 (ne (symbol_ref "TARGET_SSE2")
2395 (const_int 0)))
2396 (eq (symbol_ref "optimize_size")
2397 (const_int 0)))
2398 (const_string "TI")
2399 (const_string "V4SF"))
2400 /* For architectures resolving dependencies on
2401 whole SSE registers use APS move to break dependency
2402 chains, otherwise use short move to avoid extra work.
2403
2404 Do the same for architectures resolving dependencies on
2405 the parts. While in DF mode it is better to always handle
2406 just register parts, the SF mode is different due to lack
2407 of instructions to load just part of the register. It is
2408 better to maintain the whole registers in single format
2409 to avoid problems on using packed logical operations. */
2410 (eq_attr "alternative" "6")
2411 (if_then_else
2412 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2413 (const_int 0))
2414 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2415 (const_int 0)))
2416 (const_string "V4SF")
2417 (const_string "SF"))
2418 (eq_attr "alternative" "11")
2419 (const_string "DI")]
2420 (const_string "SF")))])
2421
2422 (define_insn "*swapsf"
2423 [(set (match_operand:SF 0 "register_operand" "+f")
2424 (match_operand:SF 1 "register_operand" "+f"))
2425 (set (match_dup 1)
2426 (match_dup 0))]
2427 "reload_completed || !TARGET_SSE"
2428 {
2429 if (STACK_TOP_P (operands[0]))
2430 return "fxch\t%1";
2431 else
2432 return "fxch\t%0";
2433 }
2434 [(set_attr "type" "fxch")
2435 (set_attr "mode" "SF")])
2436
2437 (define_expand "movdf"
2438 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2439 (match_operand:DF 1 "general_operand" ""))]
2440 ""
2441 "ix86_expand_move (DFmode, operands); DONE;")
2442
2443 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2444 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2445 ;; On the average, pushdf using integers can be still shorter. Allow this
2446 ;; pattern for optimize_size too.
2447
2448 (define_insn "*pushdf_nointeger"
2449 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2450 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2451 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2452 {
2453 /* This insn should be already splitted before reg-stack. */
2454 abort ();
2455 }
2456 [(set_attr "type" "multi")
2457 (set_attr "mode" "DF,SI,SI,DF")])
2458
2459 (define_insn "*pushdf_integer"
2460 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2461 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2462 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2463 {
2464 /* This insn should be already splitted before reg-stack. */
2465 abort ();
2466 }
2467 [(set_attr "type" "multi")
2468 (set_attr "mode" "DF,SI,DF")])
2469
2470 ;; %%% Kill this when call knows how to work this out.
2471 (define_split
2472 [(set (match_operand:DF 0 "push_operand" "")
2473 (match_operand:DF 1 "any_fp_register_operand" ""))]
2474 "!TARGET_64BIT && reload_completed"
2475 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2476 (set (mem:DF (reg:SI 7)) (match_dup 1))]
2477 "")
2478
2479 (define_split
2480 [(set (match_operand:DF 0 "push_operand" "")
2481 (match_operand:DF 1 "any_fp_register_operand" ""))]
2482 "TARGET_64BIT && reload_completed"
2483 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2484 (set (mem:DF (reg:DI 7)) (match_dup 1))]
2485 "")
2486
2487 (define_split
2488 [(set (match_operand:DF 0 "push_operand" "")
2489 (match_operand:DF 1 "general_operand" ""))]
2490 "reload_completed"
2491 [(const_int 0)]
2492 "ix86_split_long_move (operands); DONE;")
2493
2494 ;; Moving is usually shorter when only FP registers are used. This separate
2495 ;; movdf pattern avoids the use of integer registers for FP operations
2496 ;; when optimizing for size.
2497
2498 (define_insn "*movdf_nointeger"
2499 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2500 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2501 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2502 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2503 && (reload_in_progress || reload_completed
2504 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2505 || GET_CODE (operands[1]) != CONST_DOUBLE
2506 || memory_operand (operands[0], DFmode))"
2507 {
2508 switch (which_alternative)
2509 {
2510 case 0:
2511 if (REG_P (operands[1])
2512 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2513 {
2514 if (REGNO (operands[0]) == FIRST_STACK_REG
2515 && TARGET_USE_FFREEP)
2516 return "ffreep\t%y0";
2517 return "fstp\t%y0";
2518 }
2519 else if (STACK_TOP_P (operands[0]))
2520 return "fld%z1\t%y1";
2521 else
2522 return "fst\t%y0";
2523
2524 case 1:
2525 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2526 return "fstp%z0\t%y0";
2527 else
2528 return "fst%z0\t%y0";
2529
2530 case 2:
2531 return standard_80387_constant_opcode (operands[1]);
2532
2533 case 3:
2534 case 4:
2535 return "#";
2536 case 5:
2537 switch (get_attr_mode (insn))
2538 {
2539 case MODE_V4SF:
2540 return "xorps\t%0, %0";
2541 case MODE_V2DF:
2542 return "xorpd\t%0, %0";
2543 case MODE_TI:
2544 return "pxor\t%0, %0";
2545 default:
2546 abort ();
2547 }
2548 case 6:
2549 switch (get_attr_mode (insn))
2550 {
2551 case MODE_V4SF:
2552 return "movaps\t{%1, %0|%0, %1}";
2553 case MODE_V2DF:
2554 return "movapd\t{%1, %0|%0, %1}";
2555 case MODE_DF:
2556 return "movsd\t{%1, %0|%0, %1}";
2557 default:
2558 abort ();
2559 }
2560 case 7:
2561 if (get_attr_mode (insn) == MODE_V2DF)
2562 return "movlpd\t{%1, %0|%0, %1}";
2563 else
2564 return "movsd\t{%1, %0|%0, %1}";
2565 case 8:
2566 return "movsd\t{%1, %0|%0, %1}";
2567
2568 default:
2569 abort();
2570 }
2571 }
2572 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2573 (set (attr "mode")
2574 (cond [(eq_attr "alternative" "3,4")
2575 (const_string "SI")
2576 /* xorps is one byte shorter. */
2577 (eq_attr "alternative" "5")
2578 (cond [(ne (symbol_ref "optimize_size")
2579 (const_int 0))
2580 (const_string "V4SF")
2581 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2582 (const_int 0))
2583 (const_string "TI")]
2584 (const_string "V2DF"))
2585 /* For architectures resolving dependencies on
2586 whole SSE registers use APD move to break dependency
2587 chains, otherwise use short move to avoid extra work.
2588
2589 movaps encodes one byte shorter. */
2590 (eq_attr "alternative" "6")
2591 (cond
2592 [(ne (symbol_ref "optimize_size")
2593 (const_int 0))
2594 (const_string "V4SF")
2595 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2596 (const_int 0))
2597 (const_string "V2DF")]
2598 (const_string "DF"))
2599 /* For architectures resolving dependencies on register
2600 parts we may avoid extra work to zero out upper part
2601 of register. */
2602 (eq_attr "alternative" "7")
2603 (if_then_else
2604 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2605 (const_int 0))
2606 (const_string "V2DF")
2607 (const_string "DF"))]
2608 (const_string "DF")))])
2609
2610 (define_insn "*movdf_integer"
2611 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2612 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2613 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2614 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2615 && (reload_in_progress || reload_completed
2616 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2617 || GET_CODE (operands[1]) != CONST_DOUBLE
2618 || memory_operand (operands[0], DFmode))"
2619 {
2620 switch (which_alternative)
2621 {
2622 case 0:
2623 if (REG_P (operands[1])
2624 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2625 {
2626 if (REGNO (operands[0]) == FIRST_STACK_REG
2627 && TARGET_USE_FFREEP)
2628 return "ffreep\t%y0";
2629 return "fstp\t%y0";
2630 }
2631 else if (STACK_TOP_P (operands[0]))
2632 return "fld%z1\t%y1";
2633 else
2634 return "fst\t%y0";
2635
2636 case 1:
2637 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2638 return "fstp%z0\t%y0";
2639 else
2640 return "fst%z0\t%y0";
2641
2642 case 2:
2643 return standard_80387_constant_opcode (operands[1]);
2644
2645 case 3:
2646 case 4:
2647 return "#";
2648
2649 case 5:
2650 switch (get_attr_mode (insn))
2651 {
2652 case MODE_V4SF:
2653 return "xorps\t%0, %0";
2654 case MODE_V2DF:
2655 return "xorpd\t%0, %0";
2656 case MODE_TI:
2657 return "pxor\t%0, %0";
2658 default:
2659 abort ();
2660 }
2661 case 6:
2662 switch (get_attr_mode (insn))
2663 {
2664 case MODE_V4SF:
2665 return "movaps\t{%1, %0|%0, %1}";
2666 case MODE_V2DF:
2667 return "movapd\t{%1, %0|%0, %1}";
2668 case MODE_DF:
2669 return "movsd\t{%1, %0|%0, %1}";
2670 default:
2671 abort ();
2672 }
2673 case 7:
2674 if (get_attr_mode (insn) == MODE_V2DF)
2675 return "movlpd\t{%1, %0|%0, %1}";
2676 else
2677 return "movsd\t{%1, %0|%0, %1}";
2678 case 8:
2679 return "movsd\t{%1, %0|%0, %1}";
2680
2681 default:
2682 abort();
2683 }
2684 }
2685 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2686 (set (attr "mode")
2687 (cond [(eq_attr "alternative" "3,4")
2688 (const_string "SI")
2689 /* xorps is one byte shorter. */
2690 (eq_attr "alternative" "5")
2691 (cond [(ne (symbol_ref "optimize_size")
2692 (const_int 0))
2693 (const_string "V4SF")
2694 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2695 (const_int 0))
2696 (const_string "TI")]
2697 (const_string "V2DF"))
2698 /* For architectures resolving dependencies on
2699 whole SSE registers use APD move to break dependency
2700 chains, otherwise use short move to avoid extra work.
2701
2702 movaps encodes one byte shorter. */
2703 (eq_attr "alternative" "6")
2704 (cond
2705 [(ne (symbol_ref "optimize_size")
2706 (const_int 0))
2707 (const_string "V4SF")
2708 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2709 (const_int 0))
2710 (const_string "V2DF")]
2711 (const_string "DF"))
2712 /* For architectures resolving dependencies on register
2713 parts we may avoid extra work to zero out upper part
2714 of register. */
2715 (eq_attr "alternative" "7")
2716 (if_then_else
2717 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2718 (const_int 0))
2719 (const_string "V2DF")
2720 (const_string "DF"))]
2721 (const_string "DF")))])
2722
2723 (define_split
2724 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2725 (match_operand:DF 1 "general_operand" ""))]
2726 "reload_completed
2727 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2728 && ! (ANY_FP_REG_P (operands[0]) ||
2729 (GET_CODE (operands[0]) == SUBREG
2730 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2731 && ! (ANY_FP_REG_P (operands[1]) ||
2732 (GET_CODE (operands[1]) == SUBREG
2733 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2734 [(const_int 0)]
2735 "ix86_split_long_move (operands); DONE;")
2736
2737 (define_insn "*swapdf"
2738 [(set (match_operand:DF 0 "register_operand" "+f")
2739 (match_operand:DF 1 "register_operand" "+f"))
2740 (set (match_dup 1)
2741 (match_dup 0))]
2742 "reload_completed || !TARGET_SSE2"
2743 {
2744 if (STACK_TOP_P (operands[0]))
2745 return "fxch\t%1";
2746 else
2747 return "fxch\t%0";
2748 }
2749 [(set_attr "type" "fxch")
2750 (set_attr "mode" "DF")])
2751
2752 (define_expand "movxf"
2753 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2754 (match_operand:XF 1 "general_operand" ""))]
2755 "!TARGET_128BIT_LONG_DOUBLE"
2756 "ix86_expand_move (XFmode, operands); DONE;")
2757
2758 (define_expand "movtf"
2759 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2760 (match_operand:TF 1 "general_operand" ""))]
2761 ""
2762 "ix86_expand_move (TFmode, operands); DONE;")
2763
2764 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2765 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2766 ;; Pushing using integer instructions is longer except for constants
2767 ;; and direct memory references.
2768 ;; (assuming that any given constant is pushed only once, but this ought to be
2769 ;; handled elsewhere).
2770
2771 (define_insn "*pushxf_nointeger"
2772 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2773 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2774 "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2775 {
2776 /* This insn should be already splitted before reg-stack. */
2777 abort ();
2778 }
2779 [(set_attr "type" "multi")
2780 (set_attr "mode" "XF,SI,SI")])
2781
2782 (define_insn "*pushtf_nointeger"
2783 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2784 (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2785 "optimize_size"
2786 {
2787 /* This insn should be already splitted before reg-stack. */
2788 abort ();
2789 }
2790 [(set_attr "type" "multi")
2791 (set_attr "mode" "XF,SI,SI")])
2792
2793 (define_insn "*pushxf_integer"
2794 [(set (match_operand:XF 0 "push_operand" "=<,<")
2795 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2796 "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2797 {
2798 /* This insn should be already splitted before reg-stack. */
2799 abort ();
2800 }
2801 [(set_attr "type" "multi")
2802 (set_attr "mode" "XF,SI")])
2803
2804 (define_insn "*pushtf_integer"
2805 [(set (match_operand:TF 0 "push_operand" "=<,<")
2806 (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2807 "!optimize_size"
2808 {
2809 /* This insn should be already splitted before reg-stack. */
2810 abort ();
2811 }
2812 [(set_attr "type" "multi")
2813 (set_attr "mode" "XF,SI")])
2814
2815 (define_split
2816 [(set (match_operand 0 "push_operand" "")
2817 (match_operand 1 "general_operand" ""))]
2818 "reload_completed
2819 && (GET_MODE (operands[0]) == XFmode
2820 || GET_MODE (operands[0]) == TFmode
2821 || GET_MODE (operands[0]) == DFmode)
2822 && !ANY_FP_REG_P (operands[1])"
2823 [(const_int 0)]
2824 "ix86_split_long_move (operands); DONE;")
2825
2826 (define_split
2827 [(set (match_operand:XF 0 "push_operand" "")
2828 (match_operand:XF 1 "any_fp_register_operand" ""))]
2829 "!TARGET_128BIT_LONG_DOUBLE"
2830 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2831 (set (mem:XF (reg:SI 7)) (match_dup 1))])
2832
2833 (define_split
2834 [(set (match_operand:TF 0 "push_operand" "")
2835 (match_operand:TF 1 "any_fp_register_operand" ""))]
2836 "!TARGET_64BIT"
2837 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2838 (set (mem:TF (reg:SI 7)) (match_dup 1))])
2839
2840 (define_split
2841 [(set (match_operand:TF 0 "push_operand" "")
2842 (match_operand:TF 1 "any_fp_register_operand" ""))]
2843 "TARGET_64BIT"
2844 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2845 (set (mem:TF (reg:DI 7)) (match_dup 1))])
2846
2847 ;; Do not use integer registers when optimizing for size
2848 (define_insn "*movxf_nointeger"
2849 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2850 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2851 "!TARGET_128BIT_LONG_DOUBLE
2852 && optimize_size
2853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854 && (reload_in_progress || reload_completed
2855 || GET_CODE (operands[1]) != CONST_DOUBLE
2856 || memory_operand (operands[0], XFmode))"
2857 {
2858 switch (which_alternative)
2859 {
2860 case 0:
2861 if (REG_P (operands[1])
2862 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2863 {
2864 if (REGNO (operands[0]) == FIRST_STACK_REG
2865 && TARGET_USE_FFREEP)
2866 return "ffreep\t%y0";
2867 return "fstp\t%y0";
2868 }
2869 else if (STACK_TOP_P (operands[0]))
2870 return "fld%z1\t%y1";
2871 else
2872 return "fst\t%y0";
2873
2874 case 1:
2875 /* There is no non-popping store to memory for XFmode. So if
2876 we need one, follow the store with a load. */
2877 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2878 return "fstp%z0\t%y0\;fld%z0\t%y0";
2879 else
2880 return "fstp%z0\t%y0";
2881
2882 case 2:
2883 return standard_80387_constant_opcode (operands[1]);
2884
2885 case 3: case 4:
2886 return "#";
2887 }
2888 abort();
2889 }
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2892
2893 (define_insn "*movtf_nointeger"
2894 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2895 (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2896 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2897 && optimize_size
2898 && (reload_in_progress || reload_completed
2899 || GET_CODE (operands[1]) != CONST_DOUBLE
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || memory_operand (operands[0], TFmode))"
2902 {
2903 switch (which_alternative)
2904 {
2905 case 0:
2906 if (REG_P (operands[1])
2907 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2908 {
2909 if (REGNO (operands[0]) == FIRST_STACK_REG
2910 && TARGET_USE_FFREEP)
2911 return "ffreep\t%y0";
2912 return "fstp\t%y0";
2913 }
2914 else if (STACK_TOP_P (operands[0]))
2915 return "fld%z1\t%y1";
2916 else
2917 return "fst\t%y0";
2918
2919 case 1:
2920 /* There is no non-popping store to memory for XFmode. So if
2921 we need one, follow the store with a load. */
2922 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2923 return "fstp%z0\t%y0\;fld%z0\t%y0";
2924 else
2925 return "fstp%z0\t%y0";
2926
2927 case 2:
2928 return standard_80387_constant_opcode (operands[1]);
2929
2930 case 3: case 4:
2931 return "#";
2932 }
2933 abort();
2934 }
2935 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2936 (set_attr "mode" "XF,XF,XF,SI,SI")])
2937
2938 (define_insn "*movxf_integer"
2939 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2940 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2941 "!TARGET_128BIT_LONG_DOUBLE
2942 && !optimize_size
2943 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2944 && (reload_in_progress || reload_completed
2945 || GET_CODE (operands[1]) != CONST_DOUBLE
2946 || memory_operand (operands[0], XFmode))"
2947 {
2948 switch (which_alternative)
2949 {
2950 case 0:
2951 if (REG_P (operands[1])
2952 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2953 {
2954 if (REGNO (operands[0]) == FIRST_STACK_REG
2955 && TARGET_USE_FFREEP)
2956 return "ffreep\t%y0";
2957 return "fstp\t%y0";
2958 }
2959 else if (STACK_TOP_P (operands[0]))
2960 return "fld%z1\t%y1";
2961 else
2962 return "fst\t%y0";
2963
2964 case 1:
2965 /* There is no non-popping store to memory for XFmode. So if
2966 we need one, follow the store with a load. */
2967 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2968 return "fstp%z0\t%y0\;fld%z0\t%y0";
2969 else
2970 return "fstp%z0\t%y0";
2971
2972 case 2:
2973 return standard_80387_constant_opcode (operands[1]);
2974
2975 case 3: case 4:
2976 return "#";
2977 }
2978 abort();
2979 }
2980 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2981 (set_attr "mode" "XF,XF,XF,SI,SI")])
2982
2983 (define_insn "*movtf_integer"
2984 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2985 (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2986 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2987 && !optimize_size
2988 && (reload_in_progress || reload_completed
2989 || GET_CODE (operands[1]) != CONST_DOUBLE
2990 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2991 || memory_operand (operands[0], TFmode))"
2992 {
2993 switch (which_alternative)
2994 {
2995 case 0:
2996 if (REG_P (operands[1])
2997 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2998 {
2999 if (REGNO (operands[0]) == FIRST_STACK_REG
3000 && TARGET_USE_FFREEP)
3001 return "ffreep\t%y0";
3002 return "fstp\t%y0";
3003 }
3004 else if (STACK_TOP_P (operands[0]))
3005 return "fld%z1\t%y1";
3006 else
3007 return "fst\t%y0";
3008
3009 case 1:
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3014 else
3015 return "fstp%z0\t%y0";
3016
3017 case 2:
3018 return standard_80387_constant_opcode (operands[1]);
3019
3020 case 3: case 4:
3021 return "#";
3022 }
3023 abort();
3024 }
3025 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3026 (set_attr "mode" "XF,XF,XF,SI,SI")])
3027
3028 (define_split
3029 [(set (match_operand 0 "nonimmediate_operand" "")
3030 (match_operand 1 "general_operand" ""))]
3031 "reload_completed
3032 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3033 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3034 && ! (ANY_FP_REG_P (operands[0]) ||
3035 (GET_CODE (operands[0]) == SUBREG
3036 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3037 && ! (ANY_FP_REG_P (operands[1]) ||
3038 (GET_CODE (operands[1]) == SUBREG
3039 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3040 [(const_int 0)]
3041 "ix86_split_long_move (operands); DONE;")
3042
3043 (define_split
3044 [(set (match_operand 0 "register_operand" "")
3045 (match_operand 1 "memory_operand" ""))]
3046 "reload_completed
3047 && GET_CODE (operands[1]) == MEM
3048 && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3049 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3050 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3051 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3052 && (!(SSE_REG_P (operands[0]) ||
3053 (GET_CODE (operands[0]) == SUBREG
3054 && SSE_REG_P (SUBREG_REG (operands[0]))))
3055 || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3056 && (!(FP_REG_P (operands[0]) ||
3057 (GET_CODE (operands[0]) == SUBREG
3058 && FP_REG_P (SUBREG_REG (operands[0]))))
3059 || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3060 [(set (match_dup 0)
3061 (match_dup 1))]
3062 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3063
3064 (define_insn "swapxf"
3065 [(set (match_operand:XF 0 "register_operand" "+f")
3066 (match_operand:XF 1 "register_operand" "+f"))
3067 (set (match_dup 1)
3068 (match_dup 0))]
3069 ""
3070 {
3071 if (STACK_TOP_P (operands[0]))
3072 return "fxch\t%1";
3073 else
3074 return "fxch\t%0";
3075 }
3076 [(set_attr "type" "fxch")
3077 (set_attr "mode" "XF")])
3078
3079 (define_insn "swaptf"
3080 [(set (match_operand:TF 0 "register_operand" "+f")
3081 (match_operand:TF 1 "register_operand" "+f"))
3082 (set (match_dup 1)
3083 (match_dup 0))]
3084 ""
3085 {
3086 if (STACK_TOP_P (operands[0]))
3087 return "fxch\t%1";
3088 else
3089 return "fxch\t%0";
3090 }
3091 [(set_attr "type" "fxch")
3092 (set_attr "mode" "XF")])
3093 \f
3094 ;; Zero extension instructions
3095
3096 (define_expand "zero_extendhisi2"
3097 [(set (match_operand:SI 0 "register_operand" "")
3098 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3099 ""
3100 {
3101 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3102 {
3103 operands[1] = force_reg (HImode, operands[1]);
3104 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3105 DONE;
3106 }
3107 })
3108
3109 (define_insn "zero_extendhisi2_and"
3110 [(set (match_operand:SI 0 "register_operand" "=r")
3111 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3112 (clobber (reg:CC 17))]
3113 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3114 "#"
3115 [(set_attr "type" "alu1")
3116 (set_attr "mode" "SI")])
3117
3118 (define_split
3119 [(set (match_operand:SI 0 "register_operand" "")
3120 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3121 (clobber (reg:CC 17))]
3122 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3123 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3124 (clobber (reg:CC 17))])]
3125 "")
3126
3127 (define_insn "*zero_extendhisi2_movzwl"
3128 [(set (match_operand:SI 0 "register_operand" "=r")
3129 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3130 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3131 "movz{wl|x}\t{%1, %0|%0, %1}"
3132 [(set_attr "type" "imovx")
3133 (set_attr "mode" "SI")])
3134
3135 (define_expand "zero_extendqihi2"
3136 [(parallel
3137 [(set (match_operand:HI 0 "register_operand" "")
3138 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3139 (clobber (reg:CC 17))])]
3140 ""
3141 "")
3142
3143 (define_insn "*zero_extendqihi2_and"
3144 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3145 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3146 (clobber (reg:CC 17))]
3147 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3148 "#"
3149 [(set_attr "type" "alu1")
3150 (set_attr "mode" "HI")])
3151
3152 (define_insn "*zero_extendqihi2_movzbw_and"
3153 [(set (match_operand:HI 0 "register_operand" "=r,r")
3154 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3155 (clobber (reg:CC 17))]
3156 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3157 "#"
3158 [(set_attr "type" "imovx,alu1")
3159 (set_attr "mode" "HI")])
3160
3161 (define_insn "*zero_extendqihi2_movzbw"
3162 [(set (match_operand:HI 0 "register_operand" "=r")
3163 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3164 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3165 "movz{bw|x}\t{%1, %0|%0, %1}"
3166 [(set_attr "type" "imovx")
3167 (set_attr "mode" "HI")])
3168
3169 ;; For the movzbw case strip only the clobber
3170 (define_split
3171 [(set (match_operand:HI 0 "register_operand" "")
3172 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3173 (clobber (reg:CC 17))]
3174 "reload_completed
3175 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3176 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3177 [(set (match_operand:HI 0 "register_operand" "")
3178 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3179
3180 ;; When source and destination does not overlap, clear destination
3181 ;; first and then do the movb
3182 (define_split
3183 [(set (match_operand:HI 0 "register_operand" "")
3184 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3185 (clobber (reg:CC 17))]
3186 "reload_completed
3187 && ANY_QI_REG_P (operands[0])
3188 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3189 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3190 [(set (match_dup 0) (const_int 0))
3191 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3192 "operands[2] = gen_lowpart (QImode, operands[0]);")
3193
3194 ;; Rest is handled by single and.
3195 (define_split
3196 [(set (match_operand:HI 0 "register_operand" "")
3197 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3198 (clobber (reg:CC 17))]
3199 "reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3202 (clobber (reg:CC 17))])]
3203 "")
3204
3205 (define_expand "zero_extendqisi2"
3206 [(parallel
3207 [(set (match_operand:SI 0 "register_operand" "")
3208 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3209 (clobber (reg:CC 17))])]
3210 ""
3211 "")
3212
3213 (define_insn "*zero_extendqisi2_and"
3214 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3215 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3216 (clobber (reg:CC 17))]
3217 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3218 "#"
3219 [(set_attr "type" "alu1")
3220 (set_attr "mode" "SI")])
3221
3222 (define_insn "*zero_extendqisi2_movzbw_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r,r")
3224 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3225 (clobber (reg:CC 17))]
3226 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3227 "#"
3228 [(set_attr "type" "imovx,alu1")
3229 (set_attr "mode" "SI")])
3230
3231 (define_insn "*zero_extendqisi2_movzbw"
3232 [(set (match_operand:SI 0 "register_operand" "=r")
3233 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3234 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3235 "movz{bl|x}\t{%1, %0|%0, %1}"
3236 [(set_attr "type" "imovx")
3237 (set_attr "mode" "SI")])
3238
3239 ;; For the movzbl case strip only the clobber
3240 (define_split
3241 [(set (match_operand:SI 0 "register_operand" "")
3242 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3243 (clobber (reg:CC 17))]
3244 "reload_completed
3245 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3246 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3247 [(set (match_dup 0)
3248 (zero_extend:SI (match_dup 1)))])
3249
3250 ;; When source and destination does not overlap, clear destination
3251 ;; first and then do the movb
3252 (define_split
3253 [(set (match_operand:SI 0 "register_operand" "")
3254 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3255 (clobber (reg:CC 17))]
3256 "reload_completed
3257 && ANY_QI_REG_P (operands[0])
3258 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3259 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3260 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3261 [(set (match_dup 0) (const_int 0))
3262 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3263 "operands[2] = gen_lowpart (QImode, operands[0]);")
3264
3265 ;; Rest is handled by single and.
3266 (define_split
3267 [(set (match_operand:SI 0 "register_operand" "")
3268 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3269 (clobber (reg:CC 17))]
3270 "reload_completed
3271 && true_regnum (operands[0]) == true_regnum (operands[1])"
3272 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3273 (clobber (reg:CC 17))])]
3274 "")
3275
3276 ;; %%% Kill me once multi-word ops are sane.
3277 (define_expand "zero_extendsidi2"
3278 [(set (match_operand:DI 0 "register_operand" "=r")
3279 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3280 ""
3281 "if (!TARGET_64BIT)
3282 {
3283 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3284 DONE;
3285 }
3286 ")
3287
3288 (define_insn "zero_extendsidi2_32"
3289 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3290 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3291 (clobber (reg:CC 17))]
3292 "!TARGET_64BIT"
3293 "#"
3294 [(set_attr "mode" "SI")])
3295
3296 (define_insn "zero_extendsidi2_rex64"
3297 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3298 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3299 "TARGET_64BIT"
3300 "@
3301 mov\t{%k1, %k0|%k0, %k1}
3302 #"
3303 [(set_attr "type" "imovx,imov")
3304 (set_attr "mode" "SI,DI")])
3305
3306 (define_split
3307 [(set (match_operand:DI 0 "memory_operand" "")
3308 (zero_extend:DI (match_dup 0)))]
3309 "TARGET_64BIT"
3310 [(set (match_dup 4) (const_int 0))]
3311 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3312
3313 (define_split
3314 [(set (match_operand:DI 0 "register_operand" "")
3315 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3316 (clobber (reg:CC 17))]
3317 "!TARGET_64BIT && reload_completed
3318 && true_regnum (operands[0]) == true_regnum (operands[1])"
3319 [(set (match_dup 4) (const_int 0))]
3320 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3321
3322 (define_split
3323 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3324 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3325 (clobber (reg:CC 17))]
3326 "!TARGET_64BIT && reload_completed"
3327 [(set (match_dup 3) (match_dup 1))
3328 (set (match_dup 4) (const_int 0))]
3329 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3330
3331 (define_insn "zero_extendhidi2"
3332 [(set (match_operand:DI 0 "register_operand" "=r,r")
3333 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3334 "TARGET_64BIT"
3335 "@
3336 movz{wl|x}\t{%1, %k0|%k0, %1}
3337 movz{wq|x}\t{%1, %0|%0, %1}"
3338 [(set_attr "type" "imovx")
3339 (set_attr "mode" "SI,DI")])
3340
3341 (define_insn "zero_extendqidi2"
3342 [(set (match_operand:DI 0 "register_operand" "=r,r")
3343 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3344 "TARGET_64BIT"
3345 "@
3346 movz{bl|x}\t{%1, %k0|%k0, %1}
3347 movz{bq|x}\t{%1, %0|%0, %1}"
3348 [(set_attr "type" "imovx")
3349 (set_attr "mode" "SI,DI")])
3350 \f
3351 ;; Sign extension instructions
3352
3353 (define_expand "extendsidi2"
3354 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3355 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3356 (clobber (reg:CC 17))
3357 (clobber (match_scratch:SI 2 ""))])]
3358 ""
3359 {
3360 if (TARGET_64BIT)
3361 {
3362 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3363 DONE;
3364 }
3365 })
3366
3367 (define_insn "*extendsidi2_1"
3368 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3369 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3370 (clobber (reg:CC 17))
3371 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3372 "!TARGET_64BIT"
3373 "#")
3374
3375 (define_insn "extendsidi2_rex64"
3376 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3377 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3378 "TARGET_64BIT"
3379 "@
3380 {cltq|cdqe}
3381 movs{lq|x}\t{%1,%0|%0, %1}"
3382 [(set_attr "type" "imovx")
3383 (set_attr "mode" "DI")
3384 (set_attr "prefix_0f" "0")
3385 (set_attr "modrm" "0,1")])
3386
3387 (define_insn "extendhidi2"
3388 [(set (match_operand:DI 0 "register_operand" "=r")
3389 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3390 "TARGET_64BIT"
3391 "movs{wq|x}\t{%1,%0|%0, %1}"
3392 [(set_attr "type" "imovx")
3393 (set_attr "mode" "DI")])
3394
3395 (define_insn "extendqidi2"
3396 [(set (match_operand:DI 0 "register_operand" "=r")
3397 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3398 "TARGET_64BIT"
3399 "movs{bq|x}\t{%1,%0|%0, %1}"
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "DI")])
3402
3403 ;; Extend to memory case when source register does die.
3404 (define_split
3405 [(set (match_operand:DI 0 "memory_operand" "")
3406 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3407 (clobber (reg:CC 17))
3408 (clobber (match_operand:SI 2 "register_operand" ""))]
3409 "(reload_completed
3410 && dead_or_set_p (insn, operands[1])
3411 && !reg_mentioned_p (operands[1], operands[0]))"
3412 [(set (match_dup 3) (match_dup 1))
3413 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3414 (clobber (reg:CC 17))])
3415 (set (match_dup 4) (match_dup 1))]
3416 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3417
3418 ;; Extend to memory case when source register does not die.
3419 (define_split
3420 [(set (match_operand:DI 0 "memory_operand" "")
3421 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3422 (clobber (reg:CC 17))
3423 (clobber (match_operand:SI 2 "register_operand" ""))]
3424 "reload_completed"
3425 [(const_int 0)]
3426 {
3427 split_di (&operands[0], 1, &operands[3], &operands[4]);
3428
3429 emit_move_insn (operands[3], operands[1]);
3430
3431 /* Generate a cltd if possible and doing so it profitable. */
3432 if (true_regnum (operands[1]) == 0
3433 && true_regnum (operands[2]) == 1
3434 && (optimize_size || TARGET_USE_CLTD))
3435 {
3436 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3437 }
3438 else
3439 {
3440 emit_move_insn (operands[2], operands[1]);
3441 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3442 }
3443 emit_move_insn (operands[4], operands[2]);
3444 DONE;
3445 })
3446
3447 ;; Extend to register case. Optimize case where source and destination
3448 ;; registers match and cases where we can use cltd.
3449 (define_split
3450 [(set (match_operand:DI 0 "register_operand" "")
3451 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3452 (clobber (reg:CC 17))
3453 (clobber (match_scratch:SI 2 ""))]
3454 "reload_completed"
3455 [(const_int 0)]
3456 {
3457 split_di (&operands[0], 1, &operands[3], &operands[4]);
3458
3459 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3460 emit_move_insn (operands[3], operands[1]);
3461
3462 /* Generate a cltd if possible and doing so it profitable. */
3463 if (true_regnum (operands[3]) == 0
3464 && (optimize_size || TARGET_USE_CLTD))
3465 {
3466 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3467 DONE;
3468 }
3469
3470 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3471 emit_move_insn (operands[4], operands[1]);
3472
3473 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3474 DONE;
3475 })
3476
3477 (define_insn "extendhisi2"
3478 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3479 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3480 ""
3481 {
3482 switch (get_attr_prefix_0f (insn))
3483 {
3484 case 0:
3485 return "{cwtl|cwde}";
3486 default:
3487 return "movs{wl|x}\t{%1,%0|%0, %1}";
3488 }
3489 }
3490 [(set_attr "type" "imovx")
3491 (set_attr "mode" "SI")
3492 (set (attr "prefix_0f")
3493 ;; movsx is short decodable while cwtl is vector decoded.
3494 (if_then_else (and (eq_attr "cpu" "!k6")
3495 (eq_attr "alternative" "0"))
3496 (const_string "0")
3497 (const_string "1")))
3498 (set (attr "modrm")
3499 (if_then_else (eq_attr "prefix_0f" "0")
3500 (const_string "0")
3501 (const_string "1")))])
3502
3503 (define_insn "*extendhisi2_zext"
3504 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3505 (zero_extend:DI
3506 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3507 "TARGET_64BIT"
3508 {
3509 switch (get_attr_prefix_0f (insn))
3510 {
3511 case 0:
3512 return "{cwtl|cwde}";
3513 default:
3514 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3515 }
3516 }
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "SI")
3519 (set (attr "prefix_0f")
3520 ;; movsx is short decodable while cwtl is vector decoded.
3521 (if_then_else (and (eq_attr "cpu" "!k6")
3522 (eq_attr "alternative" "0"))
3523 (const_string "0")
3524 (const_string "1")))
3525 (set (attr "modrm")
3526 (if_then_else (eq_attr "prefix_0f" "0")
3527 (const_string "0")
3528 (const_string "1")))])
3529
3530 (define_insn "extendqihi2"
3531 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3532 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3533 ""
3534 {
3535 switch (get_attr_prefix_0f (insn))
3536 {
3537 case 0:
3538 return "{cbtw|cbw}";
3539 default:
3540 return "movs{bw|x}\t{%1,%0|%0, %1}";
3541 }
3542 }
3543 [(set_attr "type" "imovx")
3544 (set_attr "mode" "HI")
3545 (set (attr "prefix_0f")
3546 ;; movsx is short decodable while cwtl is vector decoded.
3547 (if_then_else (and (eq_attr "cpu" "!k6")
3548 (eq_attr "alternative" "0"))
3549 (const_string "0")
3550 (const_string "1")))
3551 (set (attr "modrm")
3552 (if_then_else (eq_attr "prefix_0f" "0")
3553 (const_string "0")
3554 (const_string "1")))])
3555
3556 (define_insn "extendqisi2"
3557 [(set (match_operand:SI 0 "register_operand" "=r")
3558 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3559 ""
3560 "movs{bl|x}\t{%1,%0|%0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3563
3564 (define_insn "*extendqisi2_zext"
3565 [(set (match_operand:DI 0 "register_operand" "=r")
3566 (zero_extend:DI
3567 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3568 "TARGET_64BIT"
3569 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3570 [(set_attr "type" "imovx")
3571 (set_attr "mode" "SI")])
3572 \f
3573 ;; Conversions between float and double.
3574
3575 ;; These are all no-ops in the model used for the 80387. So just
3576 ;; emit moves.
3577
3578 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3579 (define_insn "*dummy_extendsfdf2"
3580 [(set (match_operand:DF 0 "push_operand" "=<")
3581 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3582 "0"
3583 "#")
3584
3585 (define_split
3586 [(set (match_operand:DF 0 "push_operand" "")
3587 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3588 "!TARGET_64BIT"
3589 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3590 (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3591
3592 (define_split
3593 [(set (match_operand:DF 0 "push_operand" "")
3594 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3595 "TARGET_64BIT"
3596 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3597 (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3598
3599 (define_insn "*dummy_extendsfxf2"
3600 [(set (match_operand:XF 0 "push_operand" "=<")
3601 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3602 "0"
3603 "#")
3604
3605 (define_split
3606 [(set (match_operand:XF 0 "push_operand" "")
3607 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3608 "!TARGET_128BIT_LONG_DOUBLE"
3609 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3610 (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3611
3612 (define_insn "*dummy_extendsftf2"
3613 [(set (match_operand:TF 0 "push_operand" "=<")
3614 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3615 "0"
3616 "#")
3617
3618 (define_split
3619 [(set (match_operand:TF 0 "push_operand" "")
3620 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3621 "!TARGET_64BIT"
3622 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3623 (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3624
3625 (define_split
3626 [(set (match_operand:TF 0 "push_operand" "")
3627 (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3628 "TARGET_64BIT"
3629 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3630 (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3631
3632 (define_insn "*dummy_extenddfxf2"
3633 [(set (match_operand:XF 0 "push_operand" "=<")
3634 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3635 "0"
3636 "#")
3637
3638 (define_split
3639 [(set (match_operand:XF 0 "push_operand" "")
3640 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3641 "!TARGET_128BIT_LONG_DOUBLE"
3642 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3643 (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3644
3645 (define_insn "*dummy_extenddftf2"
3646 [(set (match_operand:TF 0 "push_operand" "=<")
3647 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3648 "0"
3649 "#")
3650
3651 (define_split
3652 [(set (match_operand:TF 0 "push_operand" "")
3653 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3654 "!TARGET_64BIT"
3655 [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3656 (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3657
3658 (define_split
3659 [(set (match_operand:TF 0 "push_operand" "")
3660 (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3661 "TARGET_64BIT"
3662 [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3663 (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3664
3665 (define_expand "extendsfdf2"
3666 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3667 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3668 "TARGET_80387 || TARGET_SSE2"
3669 {
3670 /* ??? Needed for compress_float_constant since all fp constants
3671 are LEGITIMATE_CONSTANT_P. */
3672 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3673 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3674 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3675 operands[1] = force_reg (SFmode, operands[1]);
3676 })
3677
3678 (define_insn "*extendsfdf2_1"
3679 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3680 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3681 "(TARGET_80387 || TARGET_SSE2)
3682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3683 {
3684 switch (which_alternative)
3685 {
3686 case 0:
3687 if (REG_P (operands[1])
3688 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3689 return "fstp\t%y0";
3690 else if (STACK_TOP_P (operands[0]))
3691 return "fld%z1\t%y1";
3692 else
3693 return "fst\t%y0";
3694
3695 case 1:
3696 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3697 return "fstp%z0\t%y0";
3698
3699 else
3700 return "fst%z0\t%y0";
3701 case 2:
3702 return "cvtss2sd\t{%1, %0|%0, %1}";
3703
3704 default:
3705 abort ();
3706 }
3707 }
3708 [(set_attr "type" "fmov,fmov,ssecvt")
3709 (set_attr "mode" "SF,XF,DF")])
3710
3711 (define_insn "*extendsfdf2_1_sse_only"
3712 [(set (match_operand:DF 0 "register_operand" "=Y")
3713 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3714 "!TARGET_80387 && TARGET_SSE2
3715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3716 "cvtss2sd\t{%1, %0|%0, %1}"
3717 [(set_attr "type" "ssecvt")
3718 (set_attr "mode" "DF")])
3719
3720 (define_expand "extendsfxf2"
3721 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3722 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3723 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3724 {
3725 /* ??? Needed for compress_float_constant since all fp constants
3726 are LEGITIMATE_CONSTANT_P. */
3727 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3728 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3729 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3730 operands[1] = force_reg (SFmode, operands[1]);
3731 })
3732
3733 (define_insn "*extendsfxf2_1"
3734 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3735 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3736 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3737 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3738 {
3739 switch (which_alternative)
3740 {
3741 case 0:
3742 if (REG_P (operands[1])
3743 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3744 return "fstp\t%y0";
3745 else if (STACK_TOP_P (operands[0]))
3746 return "fld%z1\t%y1";
3747 else
3748 return "fst\t%y0";
3749
3750 case 1:
3751 /* There is no non-popping store to memory for XFmode. So if
3752 we need one, follow the store with a load. */
3753 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3754 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3755 else
3756 return "fstp%z0\t%y0";
3757
3758 default:
3759 abort ();
3760 }
3761 }
3762 [(set_attr "type" "fmov")
3763 (set_attr "mode" "SF,XF")])
3764
3765 (define_expand "extendsftf2"
3766 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3767 (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3768 "TARGET_80387"
3769 {
3770 /* ??? Needed for compress_float_constant since all fp constants
3771 are LEGITIMATE_CONSTANT_P. */
3772 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3773 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3774 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3775 operands[1] = force_reg (SFmode, operands[1]);
3776 })
3777
3778 (define_insn "*extendsftf2_1"
3779 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3780 (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3781 "TARGET_80387
3782 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3783 {
3784 switch (which_alternative)
3785 {
3786 case 0:
3787 if (REG_P (operands[1])
3788 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789 return "fstp\t%y0";
3790 else if (STACK_TOP_P (operands[0]))
3791 return "fld%z1\t%y1";
3792 else
3793 return "fst\t%y0";
3794
3795 case 1:
3796 /* There is no non-popping store to memory for XFmode. So if
3797 we need one, follow the store with a load. */
3798 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3800 else
3801 return "fstp%z0\t%y0";
3802
3803 default:
3804 abort ();
3805 }
3806 }
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "SF,XF")])
3809
3810 (define_expand "extenddfxf2"
3811 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3812 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3813 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3814 {
3815 /* ??? Needed for compress_float_constant since all fp constants
3816 are LEGITIMATE_CONSTANT_P. */
3817 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3818 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3819 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3820 operands[1] = force_reg (DFmode, operands[1]);
3821 })
3822
3823 (define_insn "*extenddfxf2_1"
3824 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3825 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3826 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3828 {
3829 switch (which_alternative)
3830 {
3831 case 0:
3832 if (REG_P (operands[1])
3833 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp\t%y0";
3835 else if (STACK_TOP_P (operands[0]))
3836 return "fld%z1\t%y1";
3837 else
3838 return "fst\t%y0";
3839
3840 case 1:
3841 /* There is no non-popping store to memory for XFmode. So if
3842 we need one, follow the store with a load. */
3843 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3844 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3845 else
3846 return "fstp%z0\t%y0";
3847
3848 default:
3849 abort ();
3850 }
3851 }
3852 [(set_attr "type" "fmov")
3853 (set_attr "mode" "DF,XF")])
3854
3855 (define_expand "extenddftf2"
3856 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3857 (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3858 "TARGET_80387"
3859 {
3860 /* ??? Needed for compress_float_constant since all fp constants
3861 are LEGITIMATE_CONSTANT_P. */
3862 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3863 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3864 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3865 operands[1] = force_reg (DFmode, operands[1]);
3866 })
3867
3868 (define_insn "*extenddftf2_1"
3869 [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3870 (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3871 "TARGET_80387
3872 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3873 {
3874 switch (which_alternative)
3875 {
3876 case 0:
3877 if (REG_P (operands[1])
3878 && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3879 return "fstp\t%y0";
3880 else if (STACK_TOP_P (operands[0]))
3881 return "fld%z1\t%y1";
3882 else
3883 return "fst\t%y0";
3884
3885 case 1:
3886 /* There is no non-popping store to memory for XFmode. So if
3887 we need one, follow the store with a load. */
3888 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3890 else
3891 return "fstp%z0\t%y0";
3892
3893 default:
3894 abort ();
3895 }
3896 }
3897 [(set_attr "type" "fmov")
3898 (set_attr "mode" "DF,XF")])
3899
3900 ;; %%% This seems bad bad news.
3901 ;; This cannot output into an f-reg because there is no way to be sure
3902 ;; of truncating in that case. Otherwise this is just like a simple move
3903 ;; insn. So we pretend we can output to a reg in order to get better
3904 ;; register preferencing, but we really use a stack slot.
3905
3906 (define_expand "truncdfsf2"
3907 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3908 (float_truncate:SF
3909 (match_operand:DF 1 "register_operand" "")))
3910 (clobber (match_dup 2))])]
3911 "TARGET_80387 || TARGET_SSE2"
3912 "
3913 if (TARGET_80387)
3914 operands[2] = assign_386_stack_local (SFmode, 0);
3915 else
3916 {
3917 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3918 DONE;
3919 }
3920 ")
3921
3922 (define_insn "*truncdfsf2_1"
3923 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3924 (float_truncate:SF
3925 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3926 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3927 "TARGET_80387 && !TARGET_SSE2"
3928 {
3929 switch (which_alternative)
3930 {
3931 case 0:
3932 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933 return "fstp%z0\t%y0";
3934 else
3935 return "fst%z0\t%y0";
3936 default:
3937 abort ();
3938 }
3939 }
3940 [(set_attr "type" "fmov,multi,multi,multi")
3941 (set_attr "mode" "SF,SF,SF,SF")])
3942
3943 (define_insn "*truncdfsf2_1_sse"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3945 (float_truncate:SF
3946 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3947 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3948 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3949 {
3950 switch (which_alternative)
3951 {
3952 case 0:
3953 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954 return "fstp%z0\t%y0";
3955 else
3956 return "fst%z0\t%y0";
3957 case 4:
3958 return "#";
3959 default:
3960 abort ();
3961 }
3962 }
3963 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3964 (set_attr "mode" "SF,SF,SF,SF,DF")])
3965
3966 (define_insn "*truncdfsf2_1_sse_nooverlap"
3967 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3968 (float_truncate:SF
3969 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3970 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3971 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3972 {
3973 switch (which_alternative)
3974 {
3975 case 0:
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3978 else
3979 return "fst%z0\t%y0";
3980 case 4:
3981 return "#";
3982 default:
3983 abort ();
3984 }
3985 }
3986 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3987 (set_attr "mode" "SF,SF,SF,SF,DF")])
3988
3989 (define_insn "*truncdfsf2_2"
3990 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3991 (float_truncate:SF
3992 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3993 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3994 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3995 {
3996 switch (which_alternative)
3997 {
3998 case 0:
3999 case 1:
4000 return "cvtsd2ss\t{%1, %0|%0, %1}";
4001 case 2:
4002 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4003 return "fstp%z0\t%y0";
4004 else
4005 return "fst%z0\t%y0";
4006 default:
4007 abort ();
4008 }
4009 }
4010 [(set_attr "type" "ssecvt,ssecvt,fmov")
4011 (set_attr "athlon_decode" "vector,double,*")
4012 (set_attr "mode" "SF,SF,SF")])
4013
4014 (define_insn "*truncdfsf2_2_nooverlap"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4016 (float_truncate:SF
4017 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4018 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4019 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4020 {
4021 switch (which_alternative)
4022 {
4023 case 0:
4024 return "#";
4025 case 1:
4026 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4027 return "fstp%z0\t%y0";
4028 else
4029 return "fst%z0\t%y0";
4030 default:
4031 abort ();
4032 }
4033 }
4034 [(set_attr "type" "ssecvt,fmov")
4035 (set_attr "mode" "DF,SF")])
4036
4037 (define_insn "*truncdfsf2_3"
4038 [(set (match_operand:SF 0 "memory_operand" "=m")
4039 (float_truncate:SF
4040 (match_operand:DF 1 "register_operand" "f")))]
4041 "TARGET_80387"
4042 {
4043 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4044 return "fstp%z0\t%y0";
4045 else
4046 return "fst%z0\t%y0";
4047 }
4048 [(set_attr "type" "fmov")
4049 (set_attr "mode" "SF")])
4050
4051 (define_insn "truncdfsf2_sse_only"
4052 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4053 (float_truncate:SF
4054 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4055 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4056 "cvtsd2ss\t{%1, %0|%0, %1}"
4057 [(set_attr "type" "ssecvt")
4058 (set_attr "athlon_decode" "vector,double")
4059 (set_attr "mode" "SF")])
4060
4061 (define_insn "*truncdfsf2_sse_only_nooverlap"
4062 [(set (match_operand:SF 0 "register_operand" "=&Y")
4063 (float_truncate:SF
4064 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4065 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4066 "#"
4067 [(set_attr "type" "ssecvt")
4068 (set_attr "mode" "DF")])
4069
4070 (define_split
4071 [(set (match_operand:SF 0 "memory_operand" "")
4072 (float_truncate:SF
4073 (match_operand:DF 1 "register_operand" "")))
4074 (clobber (match_operand:SF 2 "memory_operand" ""))]
4075 "TARGET_80387"
4076 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4077 "")
4078
4079 ; Avoid possible reformatting penalty on the destination by first
4080 ; zeroing it out
4081 (define_split
4082 [(set (match_operand:SF 0 "register_operand" "")
4083 (float_truncate:SF
4084 (match_operand:DF 1 "nonimmediate_operand" "")))
4085 (clobber (match_operand 2 "" ""))]
4086 "TARGET_80387 && reload_completed
4087 && SSE_REG_P (operands[0])
4088 && !STACK_REG_P (operands[1])"
4089 [(const_int 0)]
4090 {
4091 rtx src, dest;
4092 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4093 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4094 else
4095 {
4096 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4097 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4098 /* simplify_gen_subreg refuses to widen memory references. */
4099 if (GET_CODE (src) == SUBREG)
4100 alter_subreg (&src);
4101 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4102 abort ();
4103 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4104 emit_insn (gen_cvtsd2ss (dest, dest, src));
4105 }
4106 DONE;
4107 })
4108
4109 (define_split
4110 [(set (match_operand:SF 0 "register_operand" "")
4111 (float_truncate:SF
4112 (match_operand:DF 1 "nonimmediate_operand" "")))]
4113 "TARGET_80387 && reload_completed
4114 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4115 [(const_int 0)]
4116 {
4117 rtx src, dest;
4118 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4119 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4120 /* simplify_gen_subreg refuses to widen memory references. */
4121 if (GET_CODE (src) == SUBREG)
4122 alter_subreg (&src);
4123 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4124 abort ();
4125 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4126 emit_insn (gen_cvtsd2ss (dest, dest, src));
4127 DONE;
4128 })
4129
4130 (define_split
4131 [(set (match_operand:SF 0 "register_operand" "")
4132 (float_truncate:SF
4133 (match_operand:DF 1 "fp_register_operand" "")))
4134 (clobber (match_operand:SF 2 "memory_operand" ""))]
4135 "TARGET_80387 && reload_completed"
4136 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4137 (set (match_dup 0) (match_dup 2))]
4138 "")
4139
4140 (define_expand "truncxfsf2"
4141 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4142 (float_truncate:SF
4143 (match_operand:XF 1 "register_operand" "")))
4144 (clobber (match_dup 2))])]
4145 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4146 "operands[2] = assign_386_stack_local (SFmode, 0);")
4147
4148 (define_insn "*truncxfsf2_1"
4149 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4150 (float_truncate:SF
4151 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4152 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4153 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4154 {
4155 switch (which_alternative)
4156 {
4157 case 0:
4158 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4159 return "fstp%z0\t%y0";
4160 else
4161 return "fst%z0\t%y0";
4162 default:
4163 abort();
4164 }
4165 }
4166 [(set_attr "type" "fmov,multi,multi,multi")
4167 (set_attr "mode" "SF")])
4168
4169 (define_insn "*truncxfsf2_2"
4170 [(set (match_operand:SF 0 "memory_operand" "=m")
4171 (float_truncate:SF
4172 (match_operand:XF 1 "register_operand" "f")))]
4173 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4174 {
4175 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4176 return "fstp%z0\t%y0";
4177 else
4178 return "fst%z0\t%y0";
4179 }
4180 [(set_attr "type" "fmov")
4181 (set_attr "mode" "SF")])
4182
4183 (define_split
4184 [(set (match_operand:SF 0 "memory_operand" "")
4185 (float_truncate:SF
4186 (match_operand:XF 1 "register_operand" "")))
4187 (clobber (match_operand:SF 2 "memory_operand" ""))]
4188 "TARGET_80387"
4189 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4190 "")
4191
4192 (define_split
4193 [(set (match_operand:SF 0 "register_operand" "")
4194 (float_truncate:SF
4195 (match_operand:XF 1 "register_operand" "")))
4196 (clobber (match_operand:SF 2 "memory_operand" ""))]
4197 "TARGET_80387 && reload_completed"
4198 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4199 (set (match_dup 0) (match_dup 2))]
4200 "")
4201
4202 (define_expand "trunctfsf2"
4203 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4204 (float_truncate:SF
4205 (match_operand:TF 1 "register_operand" "")))
4206 (clobber (match_dup 2))])]
4207 "TARGET_80387"
4208 "operands[2] = assign_386_stack_local (SFmode, 0);")
4209
4210 (define_insn "*trunctfsf2_1"
4211 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4212 (float_truncate:SF
4213 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4214 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4215 "TARGET_80387"
4216 {
4217 switch (which_alternative)
4218 {
4219 case 0:
4220 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4221 return "fstp%z0\t%y0";
4222 else
4223 return "fst%z0\t%y0";
4224 default:
4225 abort();
4226 }
4227 }
4228 [(set_attr "type" "fmov,multi,multi,multi")
4229 (set_attr "mode" "SF")])
4230
4231 (define_insn "*trunctfsf2_2"
4232 [(set (match_operand:SF 0 "memory_operand" "=m")
4233 (float_truncate:SF
4234 (match_operand:TF 1 "register_operand" "f")))]
4235 "TARGET_80387"
4236 {
4237 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4238 return "fstp%z0\t%y0";
4239 else
4240 return "fst%z0\t%y0";
4241 }
4242 [(set_attr "type" "fmov")
4243 (set_attr "mode" "SF")])
4244
4245 (define_split
4246 [(set (match_operand:SF 0 "memory_operand" "")
4247 (float_truncate:SF
4248 (match_operand:TF 1 "register_operand" "")))
4249 (clobber (match_operand:SF 2 "memory_operand" ""))]
4250 "TARGET_80387"
4251 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4252 "")
4253
4254 (define_split
4255 [(set (match_operand:SF 0 "register_operand" "")
4256 (float_truncate:SF
4257 (match_operand:TF 1 "register_operand" "")))
4258 (clobber (match_operand:SF 2 "memory_operand" ""))]
4259 "TARGET_80387 && reload_completed"
4260 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4261 (set (match_dup 0) (match_dup 2))]
4262 "")
4263
4264
4265 (define_expand "truncxfdf2"
4266 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4267 (float_truncate:DF
4268 (match_operand:XF 1 "register_operand" "")))
4269 (clobber (match_dup 2))])]
4270 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4271 "operands[2] = assign_386_stack_local (DFmode, 0);")
4272
4273 (define_insn "*truncxfdf2_1"
4274 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4275 (float_truncate:DF
4276 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4277 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4278 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4279 {
4280 switch (which_alternative)
4281 {
4282 case 0:
4283 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4284 return "fstp%z0\t%y0";
4285 else
4286 return "fst%z0\t%y0";
4287 default:
4288 abort();
4289 }
4290 abort ();
4291 }
4292 [(set_attr "type" "fmov,multi,multi,multi")
4293 (set_attr "mode" "DF")])
4294
4295 (define_insn "*truncxfdf2_2"
4296 [(set (match_operand:DF 0 "memory_operand" "=m")
4297 (float_truncate:DF
4298 (match_operand:XF 1 "register_operand" "f")))]
4299 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4300 {
4301 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4302 return "fstp%z0\t%y0";
4303 else
4304 return "fst%z0\t%y0";
4305 }
4306 [(set_attr "type" "fmov")
4307 (set_attr "mode" "DF")])
4308
4309 (define_split
4310 [(set (match_operand:DF 0 "memory_operand" "")
4311 (float_truncate:DF
4312 (match_operand:XF 1 "register_operand" "")))
4313 (clobber (match_operand:DF 2 "memory_operand" ""))]
4314 "TARGET_80387"
4315 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4316 "")
4317
4318 (define_split
4319 [(set (match_operand:DF 0 "register_operand" "")
4320 (float_truncate:DF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_operand:DF 2 "memory_operand" ""))]
4323 "TARGET_80387 && reload_completed"
4324 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4325 (set (match_dup 0) (match_dup 2))]
4326 "")
4327
4328 (define_expand "trunctfdf2"
4329 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4330 (float_truncate:DF
4331 (match_operand:TF 1 "register_operand" "")))
4332 (clobber (match_dup 2))])]
4333 "TARGET_80387"
4334 "operands[2] = assign_386_stack_local (DFmode, 0);")
4335
4336 (define_insn "*trunctfdf2_1"
4337 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4338 (float_truncate:DF
4339 (match_operand:TF 1 "register_operand" "f,f,f,f")))
4340 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4341 "TARGET_80387"
4342 {
4343 switch (which_alternative)
4344 {
4345 case 0:
4346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4347 return "fstp%z0\t%y0";
4348 else
4349 return "fst%z0\t%y0";
4350 default:
4351 abort();
4352 }
4353 abort ();
4354 }
4355 [(set_attr "type" "fmov,multi,multi,multi")
4356 (set_attr "mode" "DF")])
4357
4358 (define_insn "*trunctfdf2_2"
4359 [(set (match_operand:DF 0 "memory_operand" "=m")
4360 (float_truncate:DF
4361 (match_operand:TF 1 "register_operand" "f")))]
4362 "TARGET_80387"
4363 {
4364 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4365 return "fstp%z0\t%y0";
4366 else
4367 return "fst%z0\t%y0";
4368 }
4369 [(set_attr "type" "fmov")
4370 (set_attr "mode" "DF")])
4371
4372 (define_split
4373 [(set (match_operand:DF 0 "memory_operand" "")
4374 (float_truncate:DF
4375 (match_operand:TF 1 "register_operand" "")))
4376 (clobber (match_operand:DF 2 "memory_operand" ""))]
4377 "TARGET_80387"
4378 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4379 "")
4380
4381 (define_split
4382 [(set (match_operand:DF 0 "register_operand" "")
4383 (float_truncate:DF
4384 (match_operand:TF 1 "register_operand" "")))
4385 (clobber (match_operand:DF 2 "memory_operand" ""))]
4386 "TARGET_80387 && reload_completed"
4387 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4388 (set (match_dup 0) (match_dup 2))]
4389 "")
4390
4391 \f
4392 ;; %%% Break up all these bad boys.
4393
4394 ;; Signed conversion to DImode.
4395
4396 (define_expand "fix_truncxfdi2"
4397 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4398 (fix:DI (match_operand:XF 1 "register_operand" "")))]
4399 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4400 "")
4401
4402 (define_expand "fix_trunctfdi2"
4403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4404 (fix:DI (match_operand:TF 1 "register_operand" "")))]
4405 "TARGET_80387"
4406 "")
4407
4408 (define_expand "fix_truncdfdi2"
4409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4410 (fix:DI (match_operand:DF 1 "register_operand" "")))]
4411 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4412 {
4413 if (TARGET_64BIT && TARGET_SSE2)
4414 {
4415 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4416 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4417 if (out != operands[0])
4418 emit_move_insn (operands[0], out);
4419 DONE;
4420 }
4421 })
4422
4423 (define_expand "fix_truncsfdi2"
4424 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4425 (fix:DI (match_operand:SF 1 "register_operand" "")))]
4426 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4427 {
4428 if (TARGET_SSE && TARGET_64BIT)
4429 {
4430 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4431 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4432 if (out != operands[0])
4433 emit_move_insn (operands[0], out);
4434 DONE;
4435 }
4436 })
4437
4438 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4439 ;; of the machinery.
4440 (define_insn_and_split "*fix_truncdi_1"
4441 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4442 (fix:DI (match_operand 1 "register_operand" "f,f")))]
4443 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !reload_completed && !reload_in_progress
4445 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4446 "#"
4447 "&& 1"
4448 [(const_int 0)]
4449 {
4450 ix86_optimize_mode_switching = 1;
4451 operands[2] = assign_386_stack_local (HImode, 1);
4452 operands[3] = assign_386_stack_local (HImode, 2);
4453 if (memory_operand (operands[0], VOIDmode))
4454 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4455 operands[2], operands[3]));
4456 else
4457 {
4458 operands[4] = assign_386_stack_local (DImode, 0);
4459 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4460 operands[2], operands[3],
4461 operands[4]));
4462 }
4463 DONE;
4464 }
4465 [(set_attr "type" "fistp")
4466 (set_attr "mode" "DI")])
4467
4468 (define_insn "fix_truncdi_nomemory"
4469 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4470 (fix:DI (match_operand 1 "register_operand" "f,f")))
4471 (use (match_operand:HI 2 "memory_operand" "m,m"))
4472 (use (match_operand:HI 3 "memory_operand" "m,m"))
4473 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4474 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4475 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4476 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4477 "#"
4478 [(set_attr "type" "fistp")
4479 (set_attr "mode" "DI")])
4480
4481 (define_insn "fix_truncdi_memory"
4482 [(set (match_operand:DI 0 "memory_operand" "=m")
4483 (fix:DI (match_operand 1 "register_operand" "f")))
4484 (use (match_operand:HI 2 "memory_operand" "m"))
4485 (use (match_operand:HI 3 "memory_operand" "m"))
4486 (clobber (match_scratch:DF 4 "=&1f"))]
4487 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4489 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4490 [(set_attr "type" "fistp")
4491 (set_attr "mode" "DI")])
4492
4493 (define_split
4494 [(set (match_operand:DI 0 "register_operand" "")
4495 (fix:DI (match_operand 1 "register_operand" "")))
4496 (use (match_operand:HI 2 "memory_operand" ""))
4497 (use (match_operand:HI 3 "memory_operand" ""))
4498 (clobber (match_operand:DI 4 "memory_operand" ""))
4499 (clobber (match_scratch 5 ""))]
4500 "reload_completed"
4501 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4502 (use (match_dup 2))
4503 (use (match_dup 3))
4504 (clobber (match_dup 5))])
4505 (set (match_dup 0) (match_dup 4))]
4506 "")
4507
4508 (define_split
4509 [(set (match_operand:DI 0 "memory_operand" "")
4510 (fix:DI (match_operand 1 "register_operand" "")))
4511 (use (match_operand:HI 2 "memory_operand" ""))
4512 (use (match_operand:HI 3 "memory_operand" ""))
4513 (clobber (match_operand:DI 4 "memory_operand" ""))
4514 (clobber (match_scratch 5 ""))]
4515 "reload_completed"
4516 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4517 (use (match_dup 2))
4518 (use (match_dup 3))
4519 (clobber (match_dup 5))])]
4520 "")
4521
4522 ;; When SSE available, it is always faster to use it!
4523 (define_insn "fix_truncsfdi_sse"
4524 [(set (match_operand:DI 0 "register_operand" "=r,r")
4525 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4526 "TARGET_64BIT && TARGET_SSE"
4527 "cvttss2si{q}\t{%1, %0|%0, %1}"
4528 [(set_attr "type" "sseicvt")
4529 (set_attr "mode" "SF")
4530 (set_attr "athlon_decode" "double,vector")])
4531
4532 ;; Avoid vector decoded form of the instruction.
4533 (define_peephole2
4534 [(match_scratch:SF 2 "x")
4535 (set (match_operand:DI 0 "register_operand" "")
4536 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4537 "TARGET_K8 && !optimize_size"
4538 [(set (match_dup 2) (match_dup 1))
4539 (set (match_dup 0) (fix:DI (match_dup 2)))]
4540 "")
4541
4542 (define_insn "fix_truncdfdi_sse"
4543 [(set (match_operand:DI 0 "register_operand" "=r,r")
4544 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4545 "TARGET_64BIT && TARGET_SSE2"
4546 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt,sseicvt")
4548 (set_attr "mode" "DF")
4549 (set_attr "athlon_decode" "double,vector")])
4550
4551 ;; Avoid vector decoded form of the instruction.
4552 (define_peephole2
4553 [(match_scratch:DF 2 "Y")
4554 (set (match_operand:DI 0 "register_operand" "")
4555 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4556 "TARGET_K8 && !optimize_size"
4557 [(set (match_dup 2) (match_dup 1))
4558 (set (match_dup 0) (fix:DI (match_dup 2)))]
4559 "")
4560
4561 ;; Signed conversion to SImode.
4562
4563 (define_expand "fix_truncxfsi2"
4564 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4565 (fix:SI (match_operand:XF 1 "register_operand" "")))]
4566 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4567 "")
4568
4569 (define_expand "fix_trunctfsi2"
4570 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4571 (fix:SI (match_operand:TF 1 "register_operand" "")))]
4572 "TARGET_80387"
4573 "")
4574
4575 (define_expand "fix_truncdfsi2"
4576 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4577 (fix:SI (match_operand:DF 1 "register_operand" "")))]
4578 "TARGET_80387 || TARGET_SSE2"
4579 {
4580 if (TARGET_SSE2)
4581 {
4582 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4583 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4584 if (out != operands[0])
4585 emit_move_insn (operands[0], out);
4586 DONE;
4587 }
4588 })
4589
4590 (define_expand "fix_truncsfsi2"
4591 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4592 (fix:SI (match_operand:SF 1 "register_operand" "")))]
4593 "TARGET_80387 || TARGET_SSE"
4594 {
4595 if (TARGET_SSE)
4596 {
4597 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4598 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4599 if (out != operands[0])
4600 emit_move_insn (operands[0], out);
4601 DONE;
4602 }
4603 })
4604
4605 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4606 ;; of the machinery.
4607 (define_insn_and_split "*fix_truncsi_1"
4608 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4609 (fix:SI (match_operand 1 "register_operand" "f,f")))]
4610 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4611 && !reload_completed && !reload_in_progress
4612 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4613 "#"
4614 "&& 1"
4615 [(const_int 0)]
4616 {
4617 ix86_optimize_mode_switching = 1;
4618 operands[2] = assign_386_stack_local (HImode, 1);
4619 operands[3] = assign_386_stack_local (HImode, 2);
4620 if (memory_operand (operands[0], VOIDmode))
4621 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4622 operands[2], operands[3]));
4623 else
4624 {
4625 operands[4] = assign_386_stack_local (SImode, 0);
4626 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4627 operands[2], operands[3],
4628 operands[4]));
4629 }
4630 DONE;
4631 }
4632 [(set_attr "type" "fistp")
4633 (set_attr "mode" "SI")])
4634
4635 (define_insn "fix_truncsi_nomemory"
4636 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4637 (fix:SI (match_operand 1 "register_operand" "f,f")))
4638 (use (match_operand:HI 2 "memory_operand" "m,m"))
4639 (use (match_operand:HI 3 "memory_operand" "m,m"))
4640 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4641 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4642 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4643 "#"
4644 [(set_attr "type" "fistp")
4645 (set_attr "mode" "SI")])
4646
4647 (define_insn "fix_truncsi_memory"
4648 [(set (match_operand:SI 0 "memory_operand" "=m")
4649 (fix:SI (match_operand 1 "register_operand" "f")))
4650 (use (match_operand:HI 2 "memory_operand" "m"))
4651 (use (match_operand:HI 3 "memory_operand" "m"))]
4652 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654 "* return output_fix_trunc (insn, operands);"
4655 [(set_attr "type" "fistp")
4656 (set_attr "mode" "SI")])
4657
4658 ;; When SSE available, it is always faster to use it!
4659 (define_insn "fix_truncsfsi_sse"
4660 [(set (match_operand:SI 0 "register_operand" "=r,r")
4661 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4662 "TARGET_SSE"
4663 "cvttss2si\t{%1, %0|%0, %1}"
4664 [(set_attr "type" "sseicvt")
4665 (set_attr "mode" "DF")
4666 (set_attr "athlon_decode" "double,vector")])
4667
4668 ;; Avoid vector decoded form of the instruction.
4669 (define_peephole2
4670 [(match_scratch:SF 2 "x")
4671 (set (match_operand:SI 0 "register_operand" "")
4672 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4673 "TARGET_K8 && !optimize_size"
4674 [(set (match_dup 2) (match_dup 1))
4675 (set (match_dup 0) (fix:SI (match_dup 2)))]
4676 "")
4677
4678 (define_insn "fix_truncdfsi_sse"
4679 [(set (match_operand:SI 0 "register_operand" "=r,r")
4680 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4681 "TARGET_SSE2"
4682 "cvttsd2si\t{%1, %0|%0, %1}"
4683 [(set_attr "type" "sseicvt")
4684 (set_attr "mode" "DF")
4685 (set_attr "athlon_decode" "double,vector")])
4686
4687 ;; Avoid vector decoded form of the instruction.
4688 (define_peephole2
4689 [(match_scratch:DF 2 "Y")
4690 (set (match_operand:SI 0 "register_operand" "")
4691 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4692 "TARGET_K8 && !optimize_size"
4693 [(set (match_dup 2) (match_dup 1))
4694 (set (match_dup 0) (fix:SI (match_dup 2)))]
4695 "")
4696
4697 (define_split
4698 [(set (match_operand:SI 0 "register_operand" "")
4699 (fix:SI (match_operand 1 "register_operand" "")))
4700 (use (match_operand:HI 2 "memory_operand" ""))
4701 (use (match_operand:HI 3 "memory_operand" ""))
4702 (clobber (match_operand:SI 4 "memory_operand" ""))]
4703 "reload_completed"
4704 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4705 (use (match_dup 2))
4706 (use (match_dup 3))])
4707 (set (match_dup 0) (match_dup 4))]
4708 "")
4709
4710 (define_split
4711 [(set (match_operand:SI 0 "memory_operand" "")
4712 (fix:SI (match_operand 1 "register_operand" "")))
4713 (use (match_operand:HI 2 "memory_operand" ""))
4714 (use (match_operand:HI 3 "memory_operand" ""))
4715 (clobber (match_operand:SI 4 "memory_operand" ""))]
4716 "reload_completed"
4717 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4718 (use (match_dup 2))
4719 (use (match_dup 3))])]
4720 "")
4721
4722 ;; Signed conversion to HImode.
4723
4724 (define_expand "fix_truncxfhi2"
4725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4726 (fix:HI (match_operand:XF 1 "register_operand" "")))]
4727 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4728 "")
4729
4730 (define_expand "fix_trunctfhi2"
4731 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732 (fix:HI (match_operand:TF 1 "register_operand" "")))]
4733 "TARGET_80387"
4734 "")
4735
4736 (define_expand "fix_truncdfhi2"
4737 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4738 (fix:HI (match_operand:DF 1 "register_operand" "")))]
4739 "TARGET_80387 && !TARGET_SSE2"
4740 "")
4741
4742 (define_expand "fix_truncsfhi2"
4743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4744 (fix:HI (match_operand:SF 1 "register_operand" "")))]
4745 "TARGET_80387 && !TARGET_SSE"
4746 "")
4747
4748 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4749 ;; of the machinery.
4750 (define_insn_and_split "*fix_trunchi_1"
4751 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4752 (fix:HI (match_operand 1 "register_operand" "f,f")))]
4753 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4754 && !reload_completed && !reload_in_progress
4755 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4756 "#"
4757 ""
4758 [(const_int 0)]
4759 {
4760 ix86_optimize_mode_switching = 1;
4761 operands[2] = assign_386_stack_local (HImode, 1);
4762 operands[3] = assign_386_stack_local (HImode, 2);
4763 if (memory_operand (operands[0], VOIDmode))
4764 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4765 operands[2], operands[3]));
4766 else
4767 {
4768 operands[4] = assign_386_stack_local (HImode, 0);
4769 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4770 operands[2], operands[3],
4771 operands[4]));
4772 }
4773 DONE;
4774 }
4775 [(set_attr "type" "fistp")
4776 (set_attr "mode" "HI")])
4777
4778 (define_insn "fix_trunchi_nomemory"
4779 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4780 (fix:HI (match_operand 1 "register_operand" "f,f")))
4781 (use (match_operand:HI 2 "memory_operand" "m,m"))
4782 (use (match_operand:HI 3 "memory_operand" "m,m"))
4783 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4784 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4785 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4786 "#"
4787 [(set_attr "type" "fistp")
4788 (set_attr "mode" "HI")])
4789
4790 (define_insn "fix_trunchi_memory"
4791 [(set (match_operand:HI 0 "memory_operand" "=m")
4792 (fix:HI (match_operand 1 "register_operand" "f")))
4793 (use (match_operand:HI 2 "memory_operand" "m"))
4794 (use (match_operand:HI 3 "memory_operand" "m"))]
4795 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4796 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4797 "* return output_fix_trunc (insn, operands);"
4798 [(set_attr "type" "fistp")
4799 (set_attr "mode" "HI")])
4800
4801 (define_split
4802 [(set (match_operand:HI 0 "memory_operand" "")
4803 (fix:HI (match_operand 1 "register_operand" "")))
4804 (use (match_operand:HI 2 "memory_operand" ""))
4805 (use (match_operand:HI 3 "memory_operand" ""))
4806 (clobber (match_operand:HI 4 "memory_operand" ""))]
4807 "reload_completed"
4808 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4809 (use (match_dup 2))
4810 (use (match_dup 3))])]
4811 "")
4812
4813 (define_split
4814 [(set (match_operand:HI 0 "register_operand" "")
4815 (fix:HI (match_operand 1 "register_operand" "")))
4816 (use (match_operand:HI 2 "memory_operand" ""))
4817 (use (match_operand:HI 3 "memory_operand" ""))
4818 (clobber (match_operand:HI 4 "memory_operand" ""))]
4819 "reload_completed"
4820 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4821 (use (match_dup 2))
4822 (use (match_dup 3))
4823 (clobber (match_dup 4))])
4824 (set (match_dup 0) (match_dup 4))]
4825 "")
4826
4827 ;; %% Not used yet.
4828 (define_insn "x86_fnstcw_1"
4829 [(set (match_operand:HI 0 "memory_operand" "=m")
4830 (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4831 "TARGET_80387"
4832 "fnstcw\t%0"
4833 [(set_attr "length" "2")
4834 (set_attr "mode" "HI")
4835 (set_attr "unit" "i387")
4836 (set_attr "ppro_uops" "few")])
4837
4838 (define_insn "x86_fldcw_1"
4839 [(set (reg:HI 18)
4840 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4841 "TARGET_80387"
4842 "fldcw\t%0"
4843 [(set_attr "length" "2")
4844 (set_attr "mode" "HI")
4845 (set_attr "unit" "i387")
4846 (set_attr "athlon_decode" "vector")
4847 (set_attr "ppro_uops" "few")])
4848 \f
4849 ;; Conversion between fixed point and floating point.
4850
4851 ;; Even though we only accept memory inputs, the backend _really_
4852 ;; wants to be able to do this between registers.
4853
4854 (define_expand "floathisf2"
4855 [(set (match_operand:SF 0 "register_operand" "")
4856 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4857 "TARGET_SSE || TARGET_80387"
4858 {
4859 if (TARGET_SSE && TARGET_SSE_MATH)
4860 {
4861 emit_insn (gen_floatsisf2 (operands[0],
4862 convert_to_mode (SImode, operands[1], 0)));
4863 DONE;
4864 }
4865 })
4866
4867 (define_insn "*floathisf2_1"
4868 [(set (match_operand:SF 0 "register_operand" "=f,f")
4869 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4870 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4871 "@
4872 fild%z1\t%1
4873 #"
4874 [(set_attr "type" "fmov,multi")
4875 (set_attr "mode" "SF")
4876 (set_attr "fp_int_src" "true")])
4877
4878 (define_expand "floatsisf2"
4879 [(set (match_operand:SF 0 "register_operand" "")
4880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4881 "TARGET_SSE || TARGET_80387"
4882 "")
4883
4884 (define_insn "*floatsisf2_i387"
4885 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4886 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4887 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4888 "@
4889 fild%z1\t%1
4890 #
4891 cvtsi2ss\t{%1, %0|%0, %1}
4892 cvtsi2ss\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4894 (set_attr "mode" "SF")
4895 (set_attr "athlon_decode" "*,*,vector,double")
4896 (set_attr "fp_int_src" "true")])
4897
4898 (define_insn "*floatsisf2_sse"
4899 [(set (match_operand:SF 0 "register_operand" "=x,x")
4900 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4901 "TARGET_SSE"
4902 "cvtsi2ss\t{%1, %0|%0, %1}"
4903 [(set_attr "type" "sseicvt")
4904 (set_attr "mode" "SF")
4905 (set_attr "athlon_decode" "vector,double")
4906 (set_attr "fp_int_src" "true")])
4907
4908 ; Avoid possible reformatting penalty on the destination by first
4909 ; zeroing it out
4910 (define_split
4911 [(set (match_operand:SF 0 "register_operand" "")
4912 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4913 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4914 && SSE_REG_P (operands[0])"
4915 [(const_int 0)]
4916 {
4917 rtx dest;
4918 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4919 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4920 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4921 DONE;
4922 })
4923
4924 (define_expand "floatdisf2"
4925 [(set (match_operand:SF 0 "register_operand" "")
4926 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4927 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4928 "")
4929
4930 (define_insn "*floatdisf2_i387_only"
4931 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4932 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4933 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4934 "@
4935 fild%z1\t%1
4936 #"
4937 [(set_attr "type" "fmov,multi")
4938 (set_attr "mode" "SF")
4939 (set_attr "fp_int_src" "true")])
4940
4941 (define_insn "*floatdisf2_i387"
4942 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4943 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4944 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4945 "@
4946 fild%z1\t%1
4947 #
4948 cvtsi2ss{q}\t{%1, %0|%0, %1}
4949 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4950 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4951 (set_attr "mode" "SF")
4952 (set_attr "athlon_decode" "*,*,vector,double")
4953 (set_attr "fp_int_src" "true")])
4954
4955 (define_insn "*floatdisf2_sse"
4956 [(set (match_operand:SF 0 "register_operand" "=x,x")
4957 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4958 "TARGET_64BIT && TARGET_SSE"
4959 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4960 [(set_attr "type" "sseicvt")
4961 (set_attr "mode" "SF")
4962 (set_attr "athlon_decode" "vector,double")
4963 (set_attr "fp_int_src" "true")])
4964
4965 ; Avoid possible reformatting penalty on the destination by first
4966 ; zeroing it out
4967 (define_split
4968 [(set (match_operand:SF 0 "register_operand" "")
4969 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4970 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4971 && SSE_REG_P (operands[0])"
4972 [(const_int 0)]
4973 {
4974 rtx dest;
4975 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4976 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4977 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4978 DONE;
4979 })
4980
4981 (define_expand "floathidf2"
4982 [(set (match_operand:DF 0 "register_operand" "")
4983 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4984 "TARGET_SSE2 || TARGET_80387"
4985 {
4986 if (TARGET_SSE && TARGET_SSE_MATH)
4987 {
4988 emit_insn (gen_floatsidf2 (operands[0],
4989 convert_to_mode (SImode, operands[1], 0)));
4990 DONE;
4991 }
4992 })
4993
4994 (define_insn "*floathidf2_1"
4995 [(set (match_operand:DF 0 "register_operand" "=f,f")
4996 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4997 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4998 "@
4999 fild%z1\t%1
5000 #"
5001 [(set_attr "type" "fmov,multi")
5002 (set_attr "mode" "DF")
5003 (set_attr "fp_int_src" "true")])
5004
5005 (define_expand "floatsidf2"
5006 [(set (match_operand:DF 0 "register_operand" "")
5007 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
5008 "TARGET_80387 || TARGET_SSE2"
5009 "")
5010
5011 (define_insn "*floatsidf2_i387"
5012 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5013 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5014 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5015 "@
5016 fild%z1\t%1
5017 #
5018 cvtsi2sd\t{%1, %0|%0, %1}
5019 cvtsi2sd\t{%1, %0|%0, %1}"
5020 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5021 (set_attr "mode" "DF")
5022 (set_attr "athlon_decode" "*,*,double,direct")
5023 (set_attr "fp_int_src" "true")])
5024
5025 (define_insn "*floatsidf2_sse"
5026 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5027 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5028 "TARGET_SSE2"
5029 "cvtsi2sd\t{%1, %0|%0, %1}"
5030 [(set_attr "type" "sseicvt")
5031 (set_attr "mode" "DF")
5032 (set_attr "athlon_decode" "double,direct")
5033 (set_attr "fp_int_src" "true")])
5034
5035 (define_expand "floatdidf2"
5036 [(set (match_operand:DF 0 "register_operand" "")
5037 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5038 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5039 "")
5040
5041 (define_insn "*floatdidf2_i387_only"
5042 [(set (match_operand:DF 0 "register_operand" "=f,?f")
5043 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5044 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5045 "@
5046 fild%z1\t%1
5047 #"
5048 [(set_attr "type" "fmov,multi")
5049 (set_attr "mode" "DF")
5050 (set_attr "fp_int_src" "true")])
5051
5052 (define_insn "*floatdidf2_i387"
5053 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5054 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5055 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5056 "@
5057 fild%z1\t%1
5058 #
5059 cvtsi2sd{q}\t{%1, %0|%0, %1}
5060 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5061 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5062 (set_attr "mode" "DF")
5063 (set_attr "athlon_decode" "*,*,double,direct")
5064 (set_attr "fp_int_src" "true")])
5065
5066 (define_insn "*floatdidf2_sse"
5067 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5068 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5069 "TARGET_SSE2"
5070 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "mode" "DF")
5073 (set_attr "athlon_decode" "double,direct")
5074 (set_attr "fp_int_src" "true")])
5075
5076 (define_insn "floathixf2"
5077 [(set (match_operand:XF 0 "register_operand" "=f,f")
5078 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5079 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5080 "@
5081 fild%z1\t%1
5082 #"
5083 [(set_attr "type" "fmov,multi")
5084 (set_attr "mode" "XF")
5085 (set_attr "fp_int_src" "true")])
5086
5087 (define_insn "floathitf2"
5088 [(set (match_operand:TF 0 "register_operand" "=f,f")
5089 (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5090 "TARGET_80387"
5091 "@
5092 fild%z1\t%1
5093 #"
5094 [(set_attr "type" "fmov,multi")
5095 (set_attr "mode" "XF")
5096 (set_attr "fp_int_src" "true")])
5097
5098 (define_insn "floatsixf2"
5099 [(set (match_operand:XF 0 "register_operand" "=f,f")
5100 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5101 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5102 "@
5103 fild%z1\t%1
5104 #"
5105 [(set_attr "type" "fmov,multi")
5106 (set_attr "mode" "XF")
5107 (set_attr "fp_int_src" "true")])
5108
5109 (define_insn "floatsitf2"
5110 [(set (match_operand:TF 0 "register_operand" "=f,f")
5111 (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5112 "TARGET_80387"
5113 "@
5114 fild%z1\t%1
5115 #"
5116 [(set_attr "type" "fmov,multi")
5117 (set_attr "mode" "XF")
5118 (set_attr "fp_int_src" "true")])
5119
5120 (define_insn "floatdixf2"
5121 [(set (match_operand:XF 0 "register_operand" "=f,f")
5122 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5123 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5124 "@
5125 fild%z1\t%1
5126 #"
5127 [(set_attr "type" "fmov,multi")
5128 (set_attr "mode" "XF")
5129 (set_attr "fp_int_src" "true")])
5130
5131 (define_insn "floatditf2"
5132 [(set (match_operand:TF 0 "register_operand" "=f,f")
5133 (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5134 "TARGET_80387"
5135 "@
5136 fild%z1\t%1
5137 #"
5138 [(set_attr "type" "fmov,multi")
5139 (set_attr "mode" "XF")
5140 (set_attr "fp_int_src" "true")])
5141
5142 ;; %%% Kill these when reload knows how to do it.
5143 (define_split
5144 [(set (match_operand 0 "fp_register_operand" "")
5145 (float (match_operand 1 "register_operand" "")))]
5146 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5147 [(const_int 0)]
5148 {
5149 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5150 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5151 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5152 ix86_free_from_memory (GET_MODE (operands[1]));
5153 DONE;
5154 })
5155
5156 (define_expand "floatunssisf2"
5157 [(use (match_operand:SF 0 "register_operand" ""))
5158 (use (match_operand:SI 1 "register_operand" ""))]
5159 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5160 "x86_emit_floatuns (operands); DONE;")
5161
5162 (define_expand "floatunsdisf2"
5163 [(use (match_operand:SF 0 "register_operand" ""))
5164 (use (match_operand:DI 1 "register_operand" ""))]
5165 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5166 "x86_emit_floatuns (operands); DONE;")
5167
5168 (define_expand "floatunsdidf2"
5169 [(use (match_operand:DF 0 "register_operand" ""))
5170 (use (match_operand:DI 1 "register_operand" ""))]
5171 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5172 "x86_emit_floatuns (operands); DONE;")
5173 \f
5174 ;; Add instructions
5175
5176 ;; %%% splits for addsidi3
5177 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5178 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5179 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5180
5181 (define_expand "adddi3"
5182 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5184 (match_operand:DI 2 "x86_64_general_operand" "")))
5185 (clobber (reg:CC 17))]
5186 ""
5187 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5188
5189 (define_insn "*adddi3_1"
5190 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5191 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5192 (match_operand:DI 2 "general_operand" "roiF,riF")))
5193 (clobber (reg:CC 17))]
5194 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5195 "#")
5196
5197 (define_split
5198 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5199 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5200 (match_operand:DI 2 "general_operand" "")))
5201 (clobber (reg:CC 17))]
5202 "!TARGET_64BIT && reload_completed"
5203 [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5204 UNSPEC_ADD_CARRY))
5205 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5206 (parallel [(set (match_dup 3)
5207 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5208 (match_dup 4))
5209 (match_dup 5)))
5210 (clobber (reg:CC 17))])]
5211 "split_di (operands+0, 1, operands+0, operands+3);
5212 split_di (operands+1, 1, operands+1, operands+4);
5213 split_di (operands+2, 1, operands+2, operands+5);")
5214
5215 (define_insn "adddi3_carry_rex64"
5216 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5217 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5218 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5219 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5220 (clobber (reg:CC 17))]
5221 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5222 "adc{q}\t{%2, %0|%0, %2}"
5223 [(set_attr "type" "alu")
5224 (set_attr "pent_pair" "pu")
5225 (set_attr "mode" "DI")
5226 (set_attr "ppro_uops" "few")])
5227
5228 (define_insn "*adddi3_cc_rex64"
5229 [(set (reg:CC 17)
5230 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5231 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5232 UNSPEC_ADD_CARRY))
5233 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5234 (plus:DI (match_dup 1) (match_dup 2)))]
5235 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5236 "add{q}\t{%2, %0|%0, %2}"
5237 [(set_attr "type" "alu")
5238 (set_attr "mode" "DI")])
5239
5240 (define_insn "addqi3_carry"
5241 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5242 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5243 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5244 (match_operand:QI 2 "general_operand" "ri,rm")))
5245 (clobber (reg:CC 17))]
5246 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5247 "adc{b}\t{%2, %0|%0, %2}"
5248 [(set_attr "type" "alu")
5249 (set_attr "pent_pair" "pu")
5250 (set_attr "mode" "QI")
5251 (set_attr "ppro_uops" "few")])
5252
5253 (define_insn "addhi3_carry"
5254 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5255 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5256 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5257 (match_operand:HI 2 "general_operand" "ri,rm")))
5258 (clobber (reg:CC 17))]
5259 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5260 "adc{w}\t{%2, %0|%0, %2}"
5261 [(set_attr "type" "alu")
5262 (set_attr "pent_pair" "pu")
5263 (set_attr "mode" "HI")
5264 (set_attr "ppro_uops" "few")])
5265
5266 (define_insn "addsi3_carry"
5267 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5268 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5269 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5270 (match_operand:SI 2 "general_operand" "ri,rm")))
5271 (clobber (reg:CC 17))]
5272 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5273 "adc{l}\t{%2, %0|%0, %2}"
5274 [(set_attr "type" "alu")
5275 (set_attr "pent_pair" "pu")
5276 (set_attr "mode" "SI")
5277 (set_attr "ppro_uops" "few")])
5278
5279 (define_insn "*addsi3_carry_zext"
5280 [(set (match_operand:DI 0 "register_operand" "=r")
5281 (zero_extend:DI
5282 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5283 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5284 (match_operand:SI 2 "general_operand" "rim"))))
5285 (clobber (reg:CC 17))]
5286 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5287 "adc{l}\t{%2, %k0|%k0, %2}"
5288 [(set_attr "type" "alu")
5289 (set_attr "pent_pair" "pu")
5290 (set_attr "mode" "SI")
5291 (set_attr "ppro_uops" "few")])
5292
5293 (define_insn "*addsi3_cc"
5294 [(set (reg:CC 17)
5295 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5296 (match_operand:SI 2 "general_operand" "ri,rm")]
5297 UNSPEC_ADD_CARRY))
5298 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5299 (plus:SI (match_dup 1) (match_dup 2)))]
5300 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5301 "add{l}\t{%2, %0|%0, %2}"
5302 [(set_attr "type" "alu")
5303 (set_attr "mode" "SI")])
5304
5305 (define_insn "addqi3_cc"
5306 [(set (reg:CC 17)
5307 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5308 (match_operand:QI 2 "general_operand" "qi,qm")]
5309 UNSPEC_ADD_CARRY))
5310 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5311 (plus:QI (match_dup 1) (match_dup 2)))]
5312 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5313 "add{b}\t{%2, %0|%0, %2}"
5314 [(set_attr "type" "alu")
5315 (set_attr "mode" "QI")])
5316
5317 (define_expand "addsi3"
5318 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5319 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5320 (match_operand:SI 2 "general_operand" "")))
5321 (clobber (reg:CC 17))])]
5322 ""
5323 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5324
5325 (define_insn "*lea_1"
5326 [(set (match_operand:SI 0 "register_operand" "=r")
5327 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5328 "!TARGET_64BIT"
5329 "lea{l}\t{%a1, %0|%0, %a1}"
5330 [(set_attr "type" "lea")
5331 (set_attr "mode" "SI")])
5332
5333 (define_insn "*lea_1_rex64"
5334 [(set (match_operand:SI 0 "register_operand" "=r")
5335 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5336 "TARGET_64BIT"
5337 "lea{l}\t{%a1, %0|%0, %a1}"
5338 [(set_attr "type" "lea")
5339 (set_attr "mode" "SI")])
5340
5341 (define_insn "*lea_1_zext"
5342 [(set (match_operand:DI 0 "register_operand" "=r")
5343 (zero_extend:DI
5344 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5345 "TARGET_64BIT"
5346 "lea{l}\t{%a1, %k0|%k0, %a1}"
5347 [(set_attr "type" "lea")
5348 (set_attr "mode" "SI")])
5349
5350 (define_insn "*lea_2_rex64"
5351 [(set (match_operand:DI 0 "register_operand" "=r")
5352 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5353 "TARGET_64BIT"
5354 "lea{q}\t{%a1, %0|%0, %a1}"
5355 [(set_attr "type" "lea")
5356 (set_attr "mode" "DI")])
5357
5358 ;; The lea patterns for non-Pmodes needs to be matched by several
5359 ;; insns converted to real lea by splitters.
5360
5361 (define_insn_and_split "*lea_general_1"
5362 [(set (match_operand 0 "register_operand" "=r")
5363 (plus (plus (match_operand 1 "index_register_operand" "r")
5364 (match_operand 2 "register_operand" "r"))
5365 (match_operand 3 "immediate_operand" "i")))]
5366 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5367 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5368 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5369 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5370 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5371 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5372 || GET_MODE (operands[3]) == VOIDmode)"
5373 "#"
5374 "&& reload_completed"
5375 [(const_int 0)]
5376 {
5377 rtx pat;
5378 operands[0] = gen_lowpart (SImode, operands[0]);
5379 operands[1] = gen_lowpart (Pmode, operands[1]);
5380 operands[2] = gen_lowpart (Pmode, operands[2]);
5381 operands[3] = gen_lowpart (Pmode, operands[3]);
5382 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5383 operands[3]);
5384 if (Pmode != SImode)
5385 pat = gen_rtx_SUBREG (SImode, pat, 0);
5386 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5387 DONE;
5388 }
5389 [(set_attr "type" "lea")
5390 (set_attr "mode" "SI")])
5391
5392 (define_insn_and_split "*lea_general_1_zext"
5393 [(set (match_operand:DI 0 "register_operand" "=r")
5394 (zero_extend:DI
5395 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5396 (match_operand:SI 2 "register_operand" "r"))
5397 (match_operand:SI 3 "immediate_operand" "i"))))]
5398 "TARGET_64BIT"
5399 "#"
5400 "&& reload_completed"
5401 [(set (match_dup 0)
5402 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5403 (match_dup 2))
5404 (match_dup 3)) 0)))]
5405 {
5406 operands[1] = gen_lowpart (Pmode, operands[1]);
5407 operands[2] = gen_lowpart (Pmode, operands[2]);
5408 operands[3] = gen_lowpart (Pmode, operands[3]);
5409 }
5410 [(set_attr "type" "lea")
5411 (set_attr "mode" "SI")])
5412
5413 (define_insn_and_split "*lea_general_2"
5414 [(set (match_operand 0 "register_operand" "=r")
5415 (plus (mult (match_operand 1 "index_register_operand" "r")
5416 (match_operand 2 "const248_operand" "i"))
5417 (match_operand 3 "nonmemory_operand" "ri")))]
5418 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5419 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5420 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5421 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5422 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5423 || GET_MODE (operands[3]) == VOIDmode)"
5424 "#"
5425 "&& reload_completed"
5426 [(const_int 0)]
5427 {
5428 rtx pat;
5429 operands[0] = gen_lowpart (SImode, operands[0]);
5430 operands[1] = gen_lowpart (Pmode, operands[1]);
5431 operands[3] = gen_lowpart (Pmode, operands[3]);
5432 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5433 operands[3]);
5434 if (Pmode != SImode)
5435 pat = gen_rtx_SUBREG (SImode, pat, 0);
5436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5437 DONE;
5438 }
5439 [(set_attr "type" "lea")
5440 (set_attr "mode" "SI")])
5441
5442 (define_insn_and_split "*lea_general_2_zext"
5443 [(set (match_operand:DI 0 "register_operand" "=r")
5444 (zero_extend:DI
5445 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5446 (match_operand:SI 2 "const248_operand" "n"))
5447 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5448 "TARGET_64BIT"
5449 "#"
5450 "&& reload_completed"
5451 [(set (match_dup 0)
5452 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5453 (match_dup 2))
5454 (match_dup 3)) 0)))]
5455 {
5456 operands[1] = gen_lowpart (Pmode, operands[1]);
5457 operands[3] = gen_lowpart (Pmode, operands[3]);
5458 }
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "SI")])
5461
5462 (define_insn_and_split "*lea_general_3"
5463 [(set (match_operand 0 "register_operand" "=r")
5464 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5465 (match_operand 2 "const248_operand" "i"))
5466 (match_operand 3 "register_operand" "r"))
5467 (match_operand 4 "immediate_operand" "i")))]
5468 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5469 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5470 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5471 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5472 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5473 "#"
5474 "&& reload_completed"
5475 [(const_int 0)]
5476 {
5477 rtx pat;
5478 operands[0] = gen_lowpart (SImode, operands[0]);
5479 operands[1] = gen_lowpart (Pmode, operands[1]);
5480 operands[3] = gen_lowpart (Pmode, operands[3]);
5481 operands[4] = gen_lowpart (Pmode, operands[4]);
5482 pat = gen_rtx_PLUS (Pmode,
5483 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5484 operands[2]),
5485 operands[3]),
5486 operands[4]);
5487 if (Pmode != SImode)
5488 pat = gen_rtx_SUBREG (SImode, pat, 0);
5489 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5490 DONE;
5491 }
5492 [(set_attr "type" "lea")
5493 (set_attr "mode" "SI")])
5494
5495 (define_insn_and_split "*lea_general_3_zext"
5496 [(set (match_operand:DI 0 "register_operand" "=r")
5497 (zero_extend:DI
5498 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5499 (match_operand:SI 2 "const248_operand" "n"))
5500 (match_operand:SI 3 "register_operand" "r"))
5501 (match_operand:SI 4 "immediate_operand" "i"))))]
5502 "TARGET_64BIT"
5503 "#"
5504 "&& reload_completed"
5505 [(set (match_dup 0)
5506 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5507 (match_dup 2))
5508 (match_dup 3))
5509 (match_dup 4)) 0)))]
5510 {
5511 operands[1] = gen_lowpart (Pmode, operands[1]);
5512 operands[3] = gen_lowpart (Pmode, operands[3]);
5513 operands[4] = gen_lowpart (Pmode, operands[4]);
5514 }
5515 [(set_attr "type" "lea")
5516 (set_attr "mode" "SI")])
5517
5518 (define_insn "*adddi_1_rex64"
5519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5520 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5521 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5522 (clobber (reg:CC 17))]
5523 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5524 {
5525 switch (get_attr_type (insn))
5526 {
5527 case TYPE_LEA:
5528 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5529 return "lea{q}\t{%a2, %0|%0, %a2}";
5530
5531 case TYPE_INCDEC:
5532 if (! rtx_equal_p (operands[0], operands[1]))
5533 abort ();
5534 if (operands[2] == const1_rtx)
5535 return "inc{q}\t%0";
5536 else if (operands[2] == constm1_rtx)
5537 return "dec{q}\t%0";
5538 else
5539 abort ();
5540
5541 default:
5542 if (! rtx_equal_p (operands[0], operands[1]))
5543 abort ();
5544
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (GET_CODE (operands[2]) == CONST_INT
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5553 {
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5556 }
5557 return "add{q}\t{%2, %0|%0, %2}";
5558 }
5559 }
5560 [(set (attr "type")
5561 (cond [(eq_attr "alternative" "2")
5562 (const_string "lea")
5563 ; Current assemblers are broken and do not allow @GOTOFF in
5564 ; ought but a memory context.
5565 (match_operand:DI 2 "pic_symbolic_operand" "")
5566 (const_string "lea")
5567 (match_operand:DI 2 "incdec_operand" "")
5568 (const_string "incdec")
5569 ]
5570 (const_string "alu")))
5571 (set_attr "mode" "DI")])
5572
5573 ;; Convert lea to the lea pattern to avoid flags dependency.
5574 (define_split
5575 [(set (match_operand:DI 0 "register_operand" "")
5576 (plus:DI (match_operand:DI 1 "register_operand" "")
5577 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5578 (clobber (reg:CC 17))]
5579 "TARGET_64BIT && reload_completed
5580 && true_regnum (operands[0]) != true_regnum (operands[1])"
5581 [(set (match_dup 0)
5582 (plus:DI (match_dup 1)
5583 (match_dup 2)))]
5584 "")
5585
5586 (define_insn "*adddi_2_rex64"
5587 [(set (reg 17)
5588 (compare
5589 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5591 (const_int 0)))
5592 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5593 (plus:DI (match_dup 1) (match_dup 2)))]
5594 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5595 && ix86_binary_operator_ok (PLUS, DImode, operands)
5596 /* Current assemblers are broken and do not allow @GOTOFF in
5597 ought but a memory context. */
5598 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5599 {
5600 switch (get_attr_type (insn))
5601 {
5602 case TYPE_INCDEC:
5603 if (! rtx_equal_p (operands[0], operands[1]))
5604 abort ();
5605 if (operands[2] == const1_rtx)
5606 return "inc{q}\t%0";
5607 else if (operands[2] == constm1_rtx)
5608 return "dec{q}\t%0";
5609 else
5610 abort ();
5611
5612 default:
5613 if (! rtx_equal_p (operands[0], operands[1]))
5614 abort ();
5615 /* ???? We ought to handle there the 32bit case too
5616 - do we need new constraint? */
5617 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5618 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5619 if (GET_CODE (operands[2]) == CONST_INT
5620 /* Avoid overflows. */
5621 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5625 {
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{q}\t{%2, %0|%0, %2}";
5628 }
5629 return "add{q}\t{%2, %0|%0, %2}";
5630 }
5631 }
5632 [(set (attr "type")
5633 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5634 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "DI")])
5637
5638 (define_insn "*adddi_3_rex64"
5639 [(set (reg 17)
5640 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5641 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5642 (clobber (match_scratch:DI 0 "=r"))]
5643 "TARGET_64BIT
5644 && ix86_match_ccmode (insn, CCZmode)
5645 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5646 /* Current assemblers are broken and do not allow @GOTOFF in
5647 ought but a memory context. */
5648 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5649 {
5650 switch (get_attr_type (insn))
5651 {
5652 case TYPE_INCDEC:
5653 if (! rtx_equal_p (operands[0], operands[1]))
5654 abort ();
5655 if (operands[2] == const1_rtx)
5656 return "inc{q}\t%0";
5657 else if (operands[2] == constm1_rtx)
5658 return "dec{q}\t%0";
5659 else
5660 abort ();
5661
5662 default:
5663 if (! rtx_equal_p (operands[0], operands[1]))
5664 abort ();
5665 /* ???? We ought to handle there the 32bit case too
5666 - do we need new constraint? */
5667 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5668 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5669 if (GET_CODE (operands[2]) == CONST_INT
5670 /* Avoid overflows. */
5671 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5672 && (INTVAL (operands[2]) == 128
5673 || (INTVAL (operands[2]) < 0
5674 && INTVAL (operands[2]) != -128)))
5675 {
5676 operands[2] = GEN_INT (-INTVAL (operands[2]));
5677 return "sub{q}\t{%2, %0|%0, %2}";
5678 }
5679 return "add{q}\t{%2, %0|%0, %2}";
5680 }
5681 }
5682 [(set (attr "type")
5683 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set_attr "mode" "DI")])
5687
5688 ; For comparisons against 1, -1 and 128, we may generate better code
5689 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5690 ; is matched then. We can't accept general immediate, because for
5691 ; case of overflows, the result is messed up.
5692 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5693 ; when negated.
5694 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5695 ; only for comparisons not depending on it.
5696 (define_insn "*adddi_4_rex64"
5697 [(set (reg 17)
5698 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5699 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5700 (clobber (match_scratch:DI 0 "=rm"))]
5701 "TARGET_64BIT
5702 && ix86_match_ccmode (insn, CCGCmode)"
5703 {
5704 switch (get_attr_type (insn))
5705 {
5706 case TYPE_INCDEC:
5707 if (operands[2] == constm1_rtx)
5708 return "inc{q}\t%0";
5709 else if (operands[2] == const1_rtx)
5710 return "dec{q}\t%0";
5711 else
5712 abort();
5713
5714 default:
5715 if (! rtx_equal_p (operands[0], operands[1]))
5716 abort ();
5717 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5718 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5719 if ((INTVAL (operands[2]) == -128
5720 || (INTVAL (operands[2]) > 0
5721 && INTVAL (operands[2]) != 128))
5722 /* Avoid overflows. */
5723 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5724 return "sub{q}\t{%2, %0|%0, %2}";
5725 operands[2] = GEN_INT (-INTVAL (operands[2]));
5726 return "add{q}\t{%2, %0|%0, %2}";
5727 }
5728 }
5729 [(set (attr "type")
5730 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5731 (const_string "incdec")
5732 (const_string "alu")))
5733 (set_attr "mode" "DI")])
5734
5735 (define_insn "*adddi_5_rex64"
5736 [(set (reg 17)
5737 (compare
5738 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5739 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5740 (const_int 0)))
5741 (clobber (match_scratch:DI 0 "=r"))]
5742 "TARGET_64BIT
5743 && ix86_match_ccmode (insn, CCGOCmode)
5744 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5745 /* Current assemblers are broken and do not allow @GOTOFF in
5746 ought but a memory context. */
5747 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5748 {
5749 switch (get_attr_type (insn))
5750 {
5751 case TYPE_INCDEC:
5752 if (! rtx_equal_p (operands[0], operands[1]))
5753 abort ();
5754 if (operands[2] == const1_rtx)
5755 return "inc{q}\t%0";
5756 else if (operands[2] == constm1_rtx)
5757 return "dec{q}\t%0";
5758 else
5759 abort();
5760
5761 default:
5762 if (! rtx_equal_p (operands[0], operands[1]))
5763 abort ();
5764 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5765 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5766 if (GET_CODE (operands[2]) == CONST_INT
5767 /* Avoid overflows. */
5768 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5769 && (INTVAL (operands[2]) == 128
5770 || (INTVAL (operands[2]) < 0
5771 && INTVAL (operands[2]) != -128)))
5772 {
5773 operands[2] = GEN_INT (-INTVAL (operands[2]));
5774 return "sub{q}\t{%2, %0|%0, %2}";
5775 }
5776 return "add{q}\t{%2, %0|%0, %2}";
5777 }
5778 }
5779 [(set (attr "type")
5780 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5781 (const_string "incdec")
5782 (const_string "alu")))
5783 (set_attr "mode" "DI")])
5784
5785
5786 (define_insn "*addsi_1"
5787 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5788 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5789 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5790 (clobber (reg:CC 17))]
5791 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5792 {
5793 switch (get_attr_type (insn))
5794 {
5795 case TYPE_LEA:
5796 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5797 return "lea{l}\t{%a2, %0|%0, %a2}";
5798
5799 case TYPE_INCDEC:
5800 if (! rtx_equal_p (operands[0], operands[1]))
5801 abort ();
5802 if (operands[2] == const1_rtx)
5803 return "inc{l}\t%0";
5804 else if (operands[2] == constm1_rtx)
5805 return "dec{l}\t%0";
5806 else
5807 abort();
5808
5809 default:
5810 if (! rtx_equal_p (operands[0], operands[1]))
5811 abort ();
5812
5813 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5814 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5815 if (GET_CODE (operands[2]) == CONST_INT
5816 && (INTVAL (operands[2]) == 128
5817 || (INTVAL (operands[2]) < 0
5818 && INTVAL (operands[2]) != -128)))
5819 {
5820 operands[2] = GEN_INT (-INTVAL (operands[2]));
5821 return "sub{l}\t{%2, %0|%0, %2}";
5822 }
5823 return "add{l}\t{%2, %0|%0, %2}";
5824 }
5825 }
5826 [(set (attr "type")
5827 (cond [(eq_attr "alternative" "2")
5828 (const_string "lea")
5829 ; Current assemblers are broken and do not allow @GOTOFF in
5830 ; ought but a memory context.
5831 (match_operand:SI 2 "pic_symbolic_operand" "")
5832 (const_string "lea")
5833 (match_operand:SI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 ]
5836 (const_string "alu")))
5837 (set_attr "mode" "SI")])
5838
5839 ;; Convert lea to the lea pattern to avoid flags dependency.
5840 (define_split
5841 [(set (match_operand 0 "register_operand" "")
5842 (plus (match_operand 1 "register_operand" "")
5843 (match_operand 2 "nonmemory_operand" "")))
5844 (clobber (reg:CC 17))]
5845 "reload_completed
5846 && true_regnum (operands[0]) != true_regnum (operands[1])"
5847 [(const_int 0)]
5848 {
5849 rtx pat;
5850 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5851 may confuse gen_lowpart. */
5852 if (GET_MODE (operands[0]) != Pmode)
5853 {
5854 operands[1] = gen_lowpart (Pmode, operands[1]);
5855 operands[2] = gen_lowpart (Pmode, operands[2]);
5856 }
5857 operands[0] = gen_lowpart (SImode, operands[0]);
5858 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5859 if (Pmode != SImode)
5860 pat = gen_rtx_SUBREG (SImode, pat, 0);
5861 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5862 DONE;
5863 })
5864
5865 ;; It may seem that nonimmediate operand is proper one for operand 1.
5866 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5867 ;; we take care in ix86_binary_operator_ok to not allow two memory
5868 ;; operands so proper swapping will be done in reload. This allow
5869 ;; patterns constructed from addsi_1 to match.
5870 (define_insn "addsi_1_zext"
5871 [(set (match_operand:DI 0 "register_operand" "=r,r")
5872 (zero_extend:DI
5873 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5874 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5875 (clobber (reg:CC 17))]
5876 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5877 {
5878 switch (get_attr_type (insn))
5879 {
5880 case TYPE_LEA:
5881 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5882 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5883
5884 case TYPE_INCDEC:
5885 if (operands[2] == const1_rtx)
5886 return "inc{l}\t%k0";
5887 else if (operands[2] == constm1_rtx)
5888 return "dec{l}\t%k0";
5889 else
5890 abort();
5891
5892 default:
5893 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5894 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5895 if (GET_CODE (operands[2]) == CONST_INT
5896 && (INTVAL (operands[2]) == 128
5897 || (INTVAL (operands[2]) < 0
5898 && INTVAL (operands[2]) != -128)))
5899 {
5900 operands[2] = GEN_INT (-INTVAL (operands[2]));
5901 return "sub{l}\t{%2, %k0|%k0, %2}";
5902 }
5903 return "add{l}\t{%2, %k0|%k0, %2}";
5904 }
5905 }
5906 [(set (attr "type")
5907 (cond [(eq_attr "alternative" "1")
5908 (const_string "lea")
5909 ; Current assemblers are broken and do not allow @GOTOFF in
5910 ; ought but a memory context.
5911 (match_operand:SI 2 "pic_symbolic_operand" "")
5912 (const_string "lea")
5913 (match_operand:SI 2 "incdec_operand" "")
5914 (const_string "incdec")
5915 ]
5916 (const_string "alu")))
5917 (set_attr "mode" "SI")])
5918
5919 ;; Convert lea to the lea pattern to avoid flags dependency.
5920 (define_split
5921 [(set (match_operand:DI 0 "register_operand" "")
5922 (zero_extend:DI
5923 (plus:SI (match_operand:SI 1 "register_operand" "")
5924 (match_operand:SI 2 "nonmemory_operand" ""))))
5925 (clobber (reg:CC 17))]
5926 "TARGET_64BIT && reload_completed
5927 && true_regnum (operands[0]) != true_regnum (operands[1])"
5928 [(set (match_dup 0)
5929 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5930 {
5931 operands[1] = gen_lowpart (Pmode, operands[1]);
5932 operands[2] = gen_lowpart (Pmode, operands[2]);
5933 })
5934
5935 (define_insn "*addsi_2"
5936 [(set (reg 17)
5937 (compare
5938 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5939 (match_operand:SI 2 "general_operand" "rmni,rni"))
5940 (const_int 0)))
5941 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5942 (plus:SI (match_dup 1) (match_dup 2)))]
5943 "ix86_match_ccmode (insn, CCGOCmode)
5944 && ix86_binary_operator_ok (PLUS, SImode, operands)
5945 /* Current assemblers are broken and do not allow @GOTOFF in
5946 ought but a memory context. */
5947 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5948 {
5949 switch (get_attr_type (insn))
5950 {
5951 case TYPE_INCDEC:
5952 if (! rtx_equal_p (operands[0], operands[1]))
5953 abort ();
5954 if (operands[2] == const1_rtx)
5955 return "inc{l}\t%0";
5956 else if (operands[2] == constm1_rtx)
5957 return "dec{l}\t%0";
5958 else
5959 abort();
5960
5961 default:
5962 if (! rtx_equal_p (operands[0], operands[1]))
5963 abort ();
5964 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5965 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5966 if (GET_CODE (operands[2]) == CONST_INT
5967 && (INTVAL (operands[2]) == 128
5968 || (INTVAL (operands[2]) < 0
5969 && INTVAL (operands[2]) != -128)))
5970 {
5971 operands[2] = GEN_INT (-INTVAL (operands[2]));
5972 return "sub{l}\t{%2, %0|%0, %2}";
5973 }
5974 return "add{l}\t{%2, %0|%0, %2}";
5975 }
5976 }
5977 [(set (attr "type")
5978 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set_attr "mode" "SI")])
5982
5983 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5984 (define_insn "*addsi_2_zext"
5985 [(set (reg 17)
5986 (compare
5987 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5988 (match_operand:SI 2 "general_operand" "rmni"))
5989 (const_int 0)))
5990 (set (match_operand:DI 0 "register_operand" "=r")
5991 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5992 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5993 && ix86_binary_operator_ok (PLUS, SImode, operands)
5994 /* Current assemblers are broken and do not allow @GOTOFF in
5995 ought but a memory context. */
5996 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5997 {
5998 switch (get_attr_type (insn))
5999 {
6000 case TYPE_INCDEC:
6001 if (operands[2] == const1_rtx)
6002 return "inc{l}\t%k0";
6003 else if (operands[2] == constm1_rtx)
6004 return "dec{l}\t%k0";
6005 else
6006 abort();
6007
6008 default:
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (GET_CODE (operands[2]) == CONST_INT
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6015 {
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{l}\t{%2, %k0|%k0, %2}";
6018 }
6019 return "add{l}\t{%2, %k0|%k0, %2}";
6020 }
6021 }
6022 [(set (attr "type")
6023 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "SI")])
6027
6028 (define_insn "*addsi_3"
6029 [(set (reg 17)
6030 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6031 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6032 (clobber (match_scratch:SI 0 "=r"))]
6033 "ix86_match_ccmode (insn, CCZmode)
6034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6035 /* Current assemblers are broken and do not allow @GOTOFF in
6036 ought but a memory context. */
6037 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6038 {
6039 switch (get_attr_type (insn))
6040 {
6041 case TYPE_INCDEC:
6042 if (! rtx_equal_p (operands[0], operands[1]))
6043 abort ();
6044 if (operands[2] == const1_rtx)
6045 return "inc{l}\t%0";
6046 else if (operands[2] == constm1_rtx)
6047 return "dec{l}\t%0";
6048 else
6049 abort();
6050
6051 default:
6052 if (! rtx_equal_p (operands[0], operands[1]))
6053 abort ();
6054 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6056 if (GET_CODE (operands[2]) == CONST_INT
6057 && (INTVAL (operands[2]) == 128
6058 || (INTVAL (operands[2]) < 0
6059 && INTVAL (operands[2]) != -128)))
6060 {
6061 operands[2] = GEN_INT (-INTVAL (operands[2]));
6062 return "sub{l}\t{%2, %0|%0, %2}";
6063 }
6064 return "add{l}\t{%2, %0|%0, %2}";
6065 }
6066 }
6067 [(set (attr "type")
6068 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6069 (const_string "incdec")
6070 (const_string "alu")))
6071 (set_attr "mode" "SI")])
6072
6073 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6074 (define_insn "*addsi_3_zext"
6075 [(set (reg 17)
6076 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6077 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6078 (set (match_operand:DI 0 "register_operand" "=r")
6079 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6080 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6081 && ix86_binary_operator_ok (PLUS, SImode, operands)
6082 /* Current assemblers are broken and do not allow @GOTOFF in
6083 ought but a memory context. */
6084 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6085 {
6086 switch (get_attr_type (insn))
6087 {
6088 case TYPE_INCDEC:
6089 if (operands[2] == const1_rtx)
6090 return "inc{l}\t%k0";
6091 else if (operands[2] == constm1_rtx)
6092 return "dec{l}\t%k0";
6093 else
6094 abort();
6095
6096 default:
6097 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6098 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6099 if (GET_CODE (operands[2]) == CONST_INT
6100 && (INTVAL (operands[2]) == 128
6101 || (INTVAL (operands[2]) < 0
6102 && INTVAL (operands[2]) != -128)))
6103 {
6104 operands[2] = GEN_INT (-INTVAL (operands[2]));
6105 return "sub{l}\t{%2, %k0|%k0, %2}";
6106 }
6107 return "add{l}\t{%2, %k0|%k0, %2}";
6108 }
6109 }
6110 [(set (attr "type")
6111 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6112 (const_string "incdec")
6113 (const_string "alu")))
6114 (set_attr "mode" "SI")])
6115
6116 ; For comparisons against 1, -1 and 128, we may generate better code
6117 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6118 ; is matched then. We can't accept general immediate, because for
6119 ; case of overflows, the result is messed up.
6120 ; This pattern also don't hold of 0x80000000, since the value overflows
6121 ; when negated.
6122 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6123 ; only for comparisons not depending on it.
6124 (define_insn "*addsi_4"
6125 [(set (reg 17)
6126 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6127 (match_operand:SI 2 "const_int_operand" "n")))
6128 (clobber (match_scratch:SI 0 "=rm"))]
6129 "ix86_match_ccmode (insn, CCGCmode)
6130 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6131 {
6132 switch (get_attr_type (insn))
6133 {
6134 case TYPE_INCDEC:
6135 if (operands[2] == constm1_rtx)
6136 return "inc{l}\t%0";
6137 else if (operands[2] == const1_rtx)
6138 return "dec{l}\t%0";
6139 else
6140 abort();
6141
6142 default:
6143 if (! rtx_equal_p (operands[0], operands[1]))
6144 abort ();
6145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6147 if ((INTVAL (operands[2]) == -128
6148 || (INTVAL (operands[2]) > 0
6149 && INTVAL (operands[2]) != 128)))
6150 return "sub{l}\t{%2, %0|%0, %2}";
6151 operands[2] = GEN_INT (-INTVAL (operands[2]));
6152 return "add{l}\t{%2, %0|%0, %2}";
6153 }
6154 }
6155 [(set (attr "type")
6156 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6157 (const_string "incdec")
6158 (const_string "alu")))
6159 (set_attr "mode" "SI")])
6160
6161 (define_insn "*addsi_5"
6162 [(set (reg 17)
6163 (compare
6164 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6165 (match_operand:SI 2 "general_operand" "rmni"))
6166 (const_int 0)))
6167 (clobber (match_scratch:SI 0 "=r"))]
6168 "ix86_match_ccmode (insn, CCGOCmode)
6169 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6170 /* Current assemblers are broken and do not allow @GOTOFF in
6171 ought but a memory context. */
6172 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6173 {
6174 switch (get_attr_type (insn))
6175 {
6176 case TYPE_INCDEC:
6177 if (! rtx_equal_p (operands[0], operands[1]))
6178 abort ();
6179 if (operands[2] == const1_rtx)
6180 return "inc{l}\t%0";
6181 else if (operands[2] == constm1_rtx)
6182 return "dec{l}\t%0";
6183 else
6184 abort();
6185
6186 default:
6187 if (! rtx_equal_p (operands[0], operands[1]))
6188 abort ();
6189 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6191 if (GET_CODE (operands[2]) == CONST_INT
6192 && (INTVAL (operands[2]) == 128
6193 || (INTVAL (operands[2]) < 0
6194 && INTVAL (operands[2]) != -128)))
6195 {
6196 operands[2] = GEN_INT (-INTVAL (operands[2]));
6197 return "sub{l}\t{%2, %0|%0, %2}";
6198 }
6199 return "add{l}\t{%2, %0|%0, %2}";
6200 }
6201 }
6202 [(set (attr "type")
6203 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6204 (const_string "incdec")
6205 (const_string "alu")))
6206 (set_attr "mode" "SI")])
6207
6208 (define_expand "addhi3"
6209 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6210 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6211 (match_operand:HI 2 "general_operand" "")))
6212 (clobber (reg:CC 17))])]
6213 "TARGET_HIMODE_MATH"
6214 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6215
6216 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6217 ;; type optimizations enabled by define-splits. This is not important
6218 ;; for PII, and in fact harmful because of partial register stalls.
6219
6220 (define_insn "*addhi_1_lea"
6221 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6222 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6223 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6224 (clobber (reg:CC 17))]
6225 "!TARGET_PARTIAL_REG_STALL
6226 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6227 {
6228 switch (get_attr_type (insn))
6229 {
6230 case TYPE_LEA:
6231 return "#";
6232 case TYPE_INCDEC:
6233 if (operands[2] == const1_rtx)
6234 return "inc{w}\t%0";
6235 else if (operands[2] == constm1_rtx)
6236 return "dec{w}\t%0";
6237 abort();
6238
6239 default:
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (GET_CODE (operands[2]) == CONST_INT
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6246 {
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6249 }
6250 return "add{w}\t{%2, %0|%0, %2}";
6251 }
6252 }
6253 [(set (attr "type")
6254 (if_then_else (eq_attr "alternative" "2")
6255 (const_string "lea")
6256 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu"))))
6259 (set_attr "mode" "HI,HI,SI")])
6260
6261 (define_insn "*addhi_1"
6262 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6263 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6264 (match_operand:HI 2 "general_operand" "ri,rm")))
6265 (clobber (reg:CC 17))]
6266 "TARGET_PARTIAL_REG_STALL
6267 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6268 {
6269 switch (get_attr_type (insn))
6270 {
6271 case TYPE_INCDEC:
6272 if (operands[2] == const1_rtx)
6273 return "inc{w}\t%0";
6274 else if (operands[2] == constm1_rtx)
6275 return "dec{w}\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 return "sub{w}\t{%2, %0|%0, %2}";
6288 }
6289 return "add{w}\t{%2, %0|%0, %2}";
6290 }
6291 }
6292 [(set (attr "type")
6293 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set_attr "mode" "HI")])
6297
6298 (define_insn "*addhi_2"
6299 [(set (reg 17)
6300 (compare
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6302 (match_operand:HI 2 "general_operand" "rmni,rni"))
6303 (const_int 0)))
6304 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6305 (plus:HI (match_dup 1) (match_dup 2)))]
6306 "ix86_match_ccmode (insn, CCGOCmode)
6307 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6308 {
6309 switch (get_attr_type (insn))
6310 {
6311 case TYPE_INCDEC:
6312 if (operands[2] == const1_rtx)
6313 return "inc{w}\t%0";
6314 else if (operands[2] == constm1_rtx)
6315 return "dec{w}\t%0";
6316 abort();
6317
6318 default:
6319 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6320 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6321 if (GET_CODE (operands[2]) == CONST_INT
6322 && (INTVAL (operands[2]) == 128
6323 || (INTVAL (operands[2]) < 0
6324 && INTVAL (operands[2]) != -128)))
6325 {
6326 operands[2] = GEN_INT (-INTVAL (operands[2]));
6327 return "sub{w}\t{%2, %0|%0, %2}";
6328 }
6329 return "add{w}\t{%2, %0|%0, %2}";
6330 }
6331 }
6332 [(set (attr "type")
6333 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6334 (const_string "incdec")
6335 (const_string "alu")))
6336 (set_attr "mode" "HI")])
6337
6338 (define_insn "*addhi_3"
6339 [(set (reg 17)
6340 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6341 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6342 (clobber (match_scratch:HI 0 "=r"))]
6343 "ix86_match_ccmode (insn, CCZmode)
6344 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6345 {
6346 switch (get_attr_type (insn))
6347 {
6348 case TYPE_INCDEC:
6349 if (operands[2] == const1_rtx)
6350 return "inc{w}\t%0";
6351 else if (operands[2] == constm1_rtx)
6352 return "dec{w}\t%0";
6353 abort();
6354
6355 default:
6356 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6357 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6358 if (GET_CODE (operands[2]) == CONST_INT
6359 && (INTVAL (operands[2]) == 128
6360 || (INTVAL (operands[2]) < 0
6361 && INTVAL (operands[2]) != -128)))
6362 {
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{w}\t{%2, %0|%0, %2}";
6365 }
6366 return "add{w}\t{%2, %0|%0, %2}";
6367 }
6368 }
6369 [(set (attr "type")
6370 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "HI")])
6374
6375 ; See comments above addsi_3_imm for details.
6376 (define_insn "*addhi_4"
6377 [(set (reg 17)
6378 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6379 (match_operand:HI 2 "const_int_operand" "n")))
6380 (clobber (match_scratch:HI 0 "=rm"))]
6381 "ix86_match_ccmode (insn, CCGCmode)
6382 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6383 {
6384 switch (get_attr_type (insn))
6385 {
6386 case TYPE_INCDEC:
6387 if (operands[2] == constm1_rtx)
6388 return "inc{w}\t%0";
6389 else if (operands[2] == const1_rtx)
6390 return "dec{w}\t%0";
6391 else
6392 abort();
6393
6394 default:
6395 if (! rtx_equal_p (operands[0], operands[1]))
6396 abort ();
6397 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6398 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6399 if ((INTVAL (operands[2]) == -128
6400 || (INTVAL (operands[2]) > 0
6401 && INTVAL (operands[2]) != 128)))
6402 return "sub{w}\t{%2, %0|%0, %2}";
6403 operands[2] = GEN_INT (-INTVAL (operands[2]));
6404 return "add{w}\t{%2, %0|%0, %2}";
6405 }
6406 }
6407 [(set (attr "type")
6408 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6409 (const_string "incdec")
6410 (const_string "alu")))
6411 (set_attr "mode" "SI")])
6412
6413
6414 (define_insn "*addhi_5"
6415 [(set (reg 17)
6416 (compare
6417 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6418 (match_operand:HI 2 "general_operand" "rmni"))
6419 (const_int 0)))
6420 (clobber (match_scratch:HI 0 "=r"))]
6421 "ix86_match_ccmode (insn, CCGOCmode)
6422 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6423 {
6424 switch (get_attr_type (insn))
6425 {
6426 case TYPE_INCDEC:
6427 if (operands[2] == const1_rtx)
6428 return "inc{w}\t%0";
6429 else if (operands[2] == constm1_rtx)
6430 return "dec{w}\t%0";
6431 abort();
6432
6433 default:
6434 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6435 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6436 if (GET_CODE (operands[2]) == CONST_INT
6437 && (INTVAL (operands[2]) == 128
6438 || (INTVAL (operands[2]) < 0
6439 && INTVAL (operands[2]) != -128)))
6440 {
6441 operands[2] = GEN_INT (-INTVAL (operands[2]));
6442 return "sub{w}\t{%2, %0|%0, %2}";
6443 }
6444 return "add{w}\t{%2, %0|%0, %2}";
6445 }
6446 }
6447 [(set (attr "type")
6448 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6449 (const_string "incdec")
6450 (const_string "alu")))
6451 (set_attr "mode" "HI")])
6452
6453 (define_expand "addqi3"
6454 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6455 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6456 (match_operand:QI 2 "general_operand" "")))
6457 (clobber (reg:CC 17))])]
6458 "TARGET_QIMODE_MATH"
6459 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6460
6461 ;; %%% Potential partial reg stall on alternative 2. What to do?
6462 (define_insn "*addqi_1_lea"
6463 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6464 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6465 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6466 (clobber (reg:CC 17))]
6467 "!TARGET_PARTIAL_REG_STALL
6468 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6469 {
6470 int widen = (which_alternative == 2);
6471 switch (get_attr_type (insn))
6472 {
6473 case TYPE_LEA:
6474 return "#";
6475 case TYPE_INCDEC:
6476 if (operands[2] == const1_rtx)
6477 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6478 else if (operands[2] == constm1_rtx)
6479 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6480 abort();
6481
6482 default:
6483 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6484 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6485 if (GET_CODE (operands[2]) == CONST_INT
6486 && (INTVAL (operands[2]) == 128
6487 || (INTVAL (operands[2]) < 0
6488 && INTVAL (operands[2]) != -128)))
6489 {
6490 operands[2] = GEN_INT (-INTVAL (operands[2]));
6491 if (widen)
6492 return "sub{l}\t{%2, %k0|%k0, %2}";
6493 else
6494 return "sub{b}\t{%2, %0|%0, %2}";
6495 }
6496 if (widen)
6497 return "add{l}\t{%k2, %k0|%k0, %k2}";
6498 else
6499 return "add{b}\t{%2, %0|%0, %2}";
6500 }
6501 }
6502 [(set (attr "type")
6503 (if_then_else (eq_attr "alternative" "3")
6504 (const_string "lea")
6505 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6506 (const_string "incdec")
6507 (const_string "alu"))))
6508 (set_attr "mode" "QI,QI,SI,SI")])
6509
6510 (define_insn "*addqi_1"
6511 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6512 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6513 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6514 (clobber (reg:CC 17))]
6515 "TARGET_PARTIAL_REG_STALL
6516 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6517 {
6518 int widen = (which_alternative == 2);
6519 switch (get_attr_type (insn))
6520 {
6521 case TYPE_INCDEC:
6522 if (operands[2] == const1_rtx)
6523 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6524 else if (operands[2] == constm1_rtx)
6525 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6526 abort();
6527
6528 default:
6529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6531 if (GET_CODE (operands[2]) == CONST_INT
6532 && (INTVAL (operands[2]) == 128
6533 || (INTVAL (operands[2]) < 0
6534 && INTVAL (operands[2]) != -128)))
6535 {
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 if (widen)
6538 return "sub{l}\t{%2, %k0|%k0, %2}";
6539 else
6540 return "sub{b}\t{%2, %0|%0, %2}";
6541 }
6542 if (widen)
6543 return "add{l}\t{%k2, %k0|%k0, %k2}";
6544 else
6545 return "add{b}\t{%2, %0|%0, %2}";
6546 }
6547 }
6548 [(set (attr "type")
6549 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6550 (const_string "incdec")
6551 (const_string "alu")))
6552 (set_attr "mode" "QI,QI,SI")])
6553
6554 (define_insn "*addqi_1_slp"
6555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6556 (plus:QI (match_dup 0)
6557 (match_operand:QI 1 "general_operand" "qn,qnm")))
6558 (clobber (reg:CC 17))]
6559 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6561 {
6562 switch (get_attr_type (insn))
6563 {
6564 case TYPE_INCDEC:
6565 if (operands[1] == const1_rtx)
6566 return "inc{b}\t%0";
6567 else if (operands[1] == constm1_rtx)
6568 return "dec{b}\t%0";
6569 abort();
6570
6571 default:
6572 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6573 if (GET_CODE (operands[1]) == CONST_INT
6574 && INTVAL (operands[1]) < 0)
6575 {
6576 operands[2] = GEN_INT (-INTVAL (operands[2]));
6577 return "sub{b}\t{%1, %0|%0, %1}";
6578 }
6579 return "add{b}\t{%1, %0|%0, %1}";
6580 }
6581 }
6582 [(set (attr "type")
6583 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6584 (const_string "incdec")
6585 (const_string "alu1")))
6586 (set_attr "mode" "QI")])
6587
6588 (define_insn "*addqi_2"
6589 [(set (reg 17)
6590 (compare
6591 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6592 (match_operand:QI 2 "general_operand" "qmni,qni"))
6593 (const_int 0)))
6594 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6595 (plus:QI (match_dup 1) (match_dup 2)))]
6596 "ix86_match_ccmode (insn, CCGOCmode)
6597 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6598 {
6599 switch (get_attr_type (insn))
6600 {
6601 case TYPE_INCDEC:
6602 if (operands[2] == const1_rtx)
6603 return "inc{b}\t%0";
6604 else if (operands[2] == constm1_rtx
6605 || (GET_CODE (operands[2]) == CONST_INT
6606 && INTVAL (operands[2]) == 255))
6607 return "dec{b}\t%0";
6608 abort();
6609
6610 default:
6611 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6612 if (GET_CODE (operands[2]) == CONST_INT
6613 && INTVAL (operands[2]) < 0)
6614 {
6615 operands[2] = GEN_INT (-INTVAL (operands[2]));
6616 return "sub{b}\t{%2, %0|%0, %2}";
6617 }
6618 return "add{b}\t{%2, %0|%0, %2}";
6619 }
6620 }
6621 [(set (attr "type")
6622 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6623 (const_string "incdec")
6624 (const_string "alu")))
6625 (set_attr "mode" "QI")])
6626
6627 (define_insn "*addqi_3"
6628 [(set (reg 17)
6629 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6630 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6631 (clobber (match_scratch:QI 0 "=q"))]
6632 "ix86_match_ccmode (insn, CCZmode)
6633 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6634 {
6635 switch (get_attr_type (insn))
6636 {
6637 case TYPE_INCDEC:
6638 if (operands[2] == const1_rtx)
6639 return "inc{b}\t%0";
6640 else if (operands[2] == constm1_rtx
6641 || (GET_CODE (operands[2]) == CONST_INT
6642 && INTVAL (operands[2]) == 255))
6643 return "dec{b}\t%0";
6644 abort();
6645
6646 default:
6647 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6648 if (GET_CODE (operands[2]) == CONST_INT
6649 && INTVAL (operands[2]) < 0)
6650 {
6651 operands[2] = GEN_INT (-INTVAL (operands[2]));
6652 return "sub{b}\t{%2, %0|%0, %2}";
6653 }
6654 return "add{b}\t{%2, %0|%0, %2}";
6655 }
6656 }
6657 [(set (attr "type")
6658 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6659 (const_string "incdec")
6660 (const_string "alu")))
6661 (set_attr "mode" "QI")])
6662
6663 ; See comments above addsi_3_imm for details.
6664 (define_insn "*addqi_4"
6665 [(set (reg 17)
6666 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6667 (match_operand:QI 2 "const_int_operand" "n")))
6668 (clobber (match_scratch:QI 0 "=qm"))]
6669 "ix86_match_ccmode (insn, CCGCmode)
6670 && (INTVAL (operands[2]) & 0xff) != 0x80"
6671 {
6672 switch (get_attr_type (insn))
6673 {
6674 case TYPE_INCDEC:
6675 if (operands[2] == constm1_rtx
6676 || (GET_CODE (operands[2]) == CONST_INT
6677 && INTVAL (operands[2]) == 255))
6678 return "inc{b}\t%0";
6679 else if (operands[2] == const1_rtx)
6680 return "dec{b}\t%0";
6681 else
6682 abort();
6683
6684 default:
6685 if (! rtx_equal_p (operands[0], operands[1]))
6686 abort ();
6687 if (INTVAL (operands[2]) < 0)
6688 {
6689 operands[2] = GEN_INT (-INTVAL (operands[2]));
6690 return "add{b}\t{%2, %0|%0, %2}";
6691 }
6692 return "sub{b}\t{%2, %0|%0, %2}";
6693 }
6694 }
6695 [(set (attr "type")
6696 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6697 (const_string "incdec")
6698 (const_string "alu")))
6699 (set_attr "mode" "QI")])
6700
6701
6702 (define_insn "*addqi_5"
6703 [(set (reg 17)
6704 (compare
6705 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6706 (match_operand:QI 2 "general_operand" "qmni"))
6707 (const_int 0)))
6708 (clobber (match_scratch:QI 0 "=q"))]
6709 "ix86_match_ccmode (insn, CCGOCmode)
6710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6711 {
6712 switch (get_attr_type (insn))
6713 {
6714 case TYPE_INCDEC:
6715 if (operands[2] == const1_rtx)
6716 return "inc{b}\t%0";
6717 else if (operands[2] == constm1_rtx
6718 || (GET_CODE (operands[2]) == CONST_INT
6719 && INTVAL (operands[2]) == 255))
6720 return "dec{b}\t%0";
6721 abort();
6722
6723 default:
6724 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6725 if (GET_CODE (operands[2]) == CONST_INT
6726 && INTVAL (operands[2]) < 0)
6727 {
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{b}\t{%2, %0|%0, %2}";
6730 }
6731 return "add{b}\t{%2, %0|%0, %2}";
6732 }
6733 }
6734 [(set (attr "type")
6735 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set_attr "mode" "QI")])
6739
6740
6741 (define_insn "addqi_ext_1"
6742 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6743 (const_int 8)
6744 (const_int 8))
6745 (plus:SI
6746 (zero_extract:SI
6747 (match_operand 1 "ext_register_operand" "0")
6748 (const_int 8)
6749 (const_int 8))
6750 (match_operand:QI 2 "general_operand" "Qmn")))
6751 (clobber (reg:CC 17))]
6752 "!TARGET_64BIT"
6753 {
6754 switch (get_attr_type (insn))
6755 {
6756 case TYPE_INCDEC:
6757 if (operands[2] == const1_rtx)
6758 return "inc{b}\t%h0";
6759 else if (operands[2] == constm1_rtx
6760 || (GET_CODE (operands[2]) == CONST_INT
6761 && INTVAL (operands[2]) == 255))
6762 return "dec{b}\t%h0";
6763 abort();
6764
6765 default:
6766 return "add{b}\t{%2, %h0|%h0, %2}";
6767 }
6768 }
6769 [(set (attr "type")
6770 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6771 (const_string "incdec")
6772 (const_string "alu")))
6773 (set_attr "mode" "QI")])
6774
6775 (define_insn "*addqi_ext_1_rex64"
6776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6777 (const_int 8)
6778 (const_int 8))
6779 (plus:SI
6780 (zero_extract:SI
6781 (match_operand 1 "ext_register_operand" "0")
6782 (const_int 8)
6783 (const_int 8))
6784 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6785 (clobber (reg:CC 17))]
6786 "TARGET_64BIT"
6787 {
6788 switch (get_attr_type (insn))
6789 {
6790 case TYPE_INCDEC:
6791 if (operands[2] == const1_rtx)
6792 return "inc{b}\t%h0";
6793 else if (operands[2] == constm1_rtx
6794 || (GET_CODE (operands[2]) == CONST_INT
6795 && INTVAL (operands[2]) == 255))
6796 return "dec{b}\t%h0";
6797 abort();
6798
6799 default:
6800 return "add{b}\t{%2, %h0|%h0, %2}";
6801 }
6802 }
6803 [(set (attr "type")
6804 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6805 (const_string "incdec")
6806 (const_string "alu")))
6807 (set_attr "mode" "QI")])
6808
6809 (define_insn "*addqi_ext_2"
6810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6811 (const_int 8)
6812 (const_int 8))
6813 (plus:SI
6814 (zero_extract:SI
6815 (match_operand 1 "ext_register_operand" "%0")
6816 (const_int 8)
6817 (const_int 8))
6818 (zero_extract:SI
6819 (match_operand 2 "ext_register_operand" "Q")
6820 (const_int 8)
6821 (const_int 8))))
6822 (clobber (reg:CC 17))]
6823 ""
6824 "add{b}\t{%h2, %h0|%h0, %h2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "QI")])
6827
6828 ;; The patterns that match these are at the end of this file.
6829
6830 (define_expand "addxf3"
6831 [(set (match_operand:XF 0 "register_operand" "")
6832 (plus:XF (match_operand:XF 1 "register_operand" "")
6833 (match_operand:XF 2 "register_operand" "")))]
6834 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
6835 "")
6836
6837 (define_expand "addtf3"
6838 [(set (match_operand:TF 0 "register_operand" "")
6839 (plus:TF (match_operand:TF 1 "register_operand" "")
6840 (match_operand:TF 2 "register_operand" "")))]
6841 "TARGET_80387"
6842 "")
6843
6844 (define_expand "adddf3"
6845 [(set (match_operand:DF 0 "register_operand" "")
6846 (plus:DF (match_operand:DF 1 "register_operand" "")
6847 (match_operand:DF 2 "nonimmediate_operand" "")))]
6848 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6849 "")
6850
6851 (define_expand "addsf3"
6852 [(set (match_operand:SF 0 "register_operand" "")
6853 (plus:SF (match_operand:SF 1 "register_operand" "")
6854 (match_operand:SF 2 "nonimmediate_operand" "")))]
6855 "TARGET_80387 || TARGET_SSE_MATH"
6856 "")
6857 \f
6858 ;; Subtract instructions
6859
6860 ;; %%% splits for subsidi3
6861
6862 (define_expand "subdi3"
6863 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6864 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6865 (match_operand:DI 2 "x86_64_general_operand" "")))
6866 (clobber (reg:CC 17))])]
6867 ""
6868 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6869
6870 (define_insn "*subdi3_1"
6871 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6872 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6873 (match_operand:DI 2 "general_operand" "roiF,riF")))
6874 (clobber (reg:CC 17))]
6875 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6876 "#")
6877
6878 (define_split
6879 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6880 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6881 (match_operand:DI 2 "general_operand" "")))
6882 (clobber (reg:CC 17))]
6883 "!TARGET_64BIT && reload_completed"
6884 [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6885 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6886 (parallel [(set (match_dup 3)
6887 (minus:SI (match_dup 4)
6888 (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6889 (match_dup 5))))
6890 (clobber (reg:CC 17))])]
6891 "split_di (operands+0, 1, operands+0, operands+3);
6892 split_di (operands+1, 1, operands+1, operands+4);
6893 split_di (operands+2, 1, operands+2, operands+5);")
6894
6895 (define_insn "subdi3_carry_rex64"
6896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6898 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6899 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6900 (clobber (reg:CC 17))]
6901 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6902 "sbb{q}\t{%2, %0|%0, %2}"
6903 [(set_attr "type" "alu")
6904 (set_attr "pent_pair" "pu")
6905 (set_attr "ppro_uops" "few")
6906 (set_attr "mode" "DI")])
6907
6908 (define_insn "*subdi_1_rex64"
6909 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6910 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6911 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6912 (clobber (reg:CC 17))]
6913 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6914 "sub{q}\t{%2, %0|%0, %2}"
6915 [(set_attr "type" "alu")
6916 (set_attr "mode" "DI")])
6917
6918 (define_insn "*subdi_2_rex64"
6919 [(set (reg 17)
6920 (compare
6921 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6922 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6923 (const_int 0)))
6924 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6925 (minus:DI (match_dup 1) (match_dup 2)))]
6926 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6927 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6928 "sub{q}\t{%2, %0|%0, %2}"
6929 [(set_attr "type" "alu")
6930 (set_attr "mode" "DI")])
6931
6932 (define_insn "*subdi_3_rex63"
6933 [(set (reg 17)
6934 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6935 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6936 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6937 (minus:DI (match_dup 1) (match_dup 2)))]
6938 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6939 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{q}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "DI")])
6943
6944 (define_insn "subqi3_carry"
6945 [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6946 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6947 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6948 (match_operand:QI 2 "general_operand" "ri,rm"))))
6949 (clobber (reg:CC 17))]
6950 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6951 "sbb{b}\t{%2, %0|%0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "pent_pair" "pu")
6954 (set_attr "ppro_uops" "few")
6955 (set_attr "mode" "QI")])
6956
6957 (define_insn "subhi3_carry"
6958 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6959 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6960 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6961 (match_operand:HI 2 "general_operand" "ri,rm"))))
6962 (clobber (reg:CC 17))]
6963 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6964 "sbb{w}\t{%2, %0|%0, %2}"
6965 [(set_attr "type" "alu")
6966 (set_attr "pent_pair" "pu")
6967 (set_attr "ppro_uops" "few")
6968 (set_attr "mode" "HI")])
6969
6970 (define_insn "subsi3_carry"
6971 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6972 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6973 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6974 (match_operand:SI 2 "general_operand" "ri,rm"))))
6975 (clobber (reg:CC 17))]
6976 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6977 "sbb{l}\t{%2, %0|%0, %2}"
6978 [(set_attr "type" "alu")
6979 (set_attr "pent_pair" "pu")
6980 (set_attr "ppro_uops" "few")
6981 (set_attr "mode" "SI")])
6982
6983 (define_insn "subsi3_carry_zext"
6984 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6985 (zero_extend:DI
6986 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6987 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))))
6989 (clobber (reg:CC 17))]
6990 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6991 "sbb{l}\t{%2, %k0|%k0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "pent_pair" "pu")
6994 (set_attr "ppro_uops" "few")
6995 (set_attr "mode" "SI")])
6996
6997 (define_expand "subsi3"
6998 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6999 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7000 (match_operand:SI 2 "general_operand" "")))
7001 (clobber (reg:CC 17))])]
7002 ""
7003 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7004
7005 (define_insn "*subsi_1"
7006 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7007 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7008 (match_operand:SI 2 "general_operand" "ri,rm")))
7009 (clobber (reg:CC 17))]
7010 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7011 "sub{l}\t{%2, %0|%0, %2}"
7012 [(set_attr "type" "alu")
7013 (set_attr "mode" "SI")])
7014
7015 (define_insn "*subsi_1_zext"
7016 [(set (match_operand:DI 0 "register_operand" "=r")
7017 (zero_extend:DI
7018 (minus:SI (match_operand:SI 1 "register_operand" "0")
7019 (match_operand:SI 2 "general_operand" "rim"))))
7020 (clobber (reg:CC 17))]
7021 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7022 "sub{l}\t{%2, %k0|%k0, %2}"
7023 [(set_attr "type" "alu")
7024 (set_attr "mode" "SI")])
7025
7026 (define_insn "*subsi_2"
7027 [(set (reg 17)
7028 (compare
7029 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7030 (match_operand:SI 2 "general_operand" "ri,rm"))
7031 (const_int 0)))
7032 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7033 (minus:SI (match_dup 1) (match_dup 2)))]
7034 "ix86_match_ccmode (insn, CCGOCmode)
7035 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7036 "sub{l}\t{%2, %0|%0, %2}"
7037 [(set_attr "type" "alu")
7038 (set_attr "mode" "SI")])
7039
7040 (define_insn "*subsi_2_zext"
7041 [(set (reg 17)
7042 (compare
7043 (minus:SI (match_operand:SI 1 "register_operand" "0")
7044 (match_operand:SI 2 "general_operand" "rim"))
7045 (const_int 0)))
7046 (set (match_operand:DI 0 "register_operand" "=r")
7047 (zero_extend:DI
7048 (minus:SI (match_dup 1)
7049 (match_dup 2))))]
7050 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7051 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7052 "sub{l}\t{%2, %k0|%k0, %2}"
7053 [(set_attr "type" "alu")
7054 (set_attr "mode" "SI")])
7055
7056 (define_insn "*subsi_3"
7057 [(set (reg 17)
7058 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7059 (match_operand:SI 2 "general_operand" "ri,rm")))
7060 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7061 (minus:SI (match_dup 1) (match_dup 2)))]
7062 "ix86_match_ccmode (insn, CCmode)
7063 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7064 "sub{l}\t{%2, %0|%0, %2}"
7065 [(set_attr "type" "alu")
7066 (set_attr "mode" "SI")])
7067
7068 (define_insn "*subsi_3_zext"
7069 [(set (reg 17)
7070 (compare (match_operand:SI 1 "register_operand" "0")
7071 (match_operand:SI 2 "general_operand" "rim")))
7072 (set (match_operand:DI 0 "register_operand" "=r")
7073 (zero_extend:DI
7074 (minus:SI (match_dup 1)
7075 (match_dup 2))))]
7076 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7077 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7078 "sub{q}\t{%2, %0|%0, %2}"
7079 [(set_attr "type" "alu")
7080 (set_attr "mode" "DI")])
7081
7082 (define_expand "subhi3"
7083 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7084 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7085 (match_operand:HI 2 "general_operand" "")))
7086 (clobber (reg:CC 17))])]
7087 "TARGET_HIMODE_MATH"
7088 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7089
7090 (define_insn "*subhi_1"
7091 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7092 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7093 (match_operand:HI 2 "general_operand" "ri,rm")))
7094 (clobber (reg:CC 17))]
7095 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7096 "sub{w}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "HI")])
7099
7100 (define_insn "*subhi_2"
7101 [(set (reg 17)
7102 (compare
7103 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7104 (match_operand:HI 2 "general_operand" "ri,rm"))
7105 (const_int 0)))
7106 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7107 (minus:HI (match_dup 1) (match_dup 2)))]
7108 "ix86_match_ccmode (insn, CCGOCmode)
7109 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7110 "sub{w}\t{%2, %0|%0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "HI")])
7113
7114 (define_insn "*subhi_3"
7115 [(set (reg 17)
7116 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7117 (match_operand:HI 2 "general_operand" "ri,rm")))
7118 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7119 (minus:HI (match_dup 1) (match_dup 2)))]
7120 "ix86_match_ccmode (insn, CCmode)
7121 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7122 "sub{w}\t{%2, %0|%0, %2}"
7123 [(set_attr "type" "alu")
7124 (set_attr "mode" "HI")])
7125
7126 (define_expand "subqi3"
7127 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7128 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7129 (match_operand:QI 2 "general_operand" "")))
7130 (clobber (reg:CC 17))])]
7131 "TARGET_QIMODE_MATH"
7132 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7133
7134 (define_insn "*subqi_1"
7135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7136 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7137 (match_operand:QI 2 "general_operand" "qn,qmn")))
7138 (clobber (reg:CC 17))]
7139 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7140 "sub{b}\t{%2, %0|%0, %2}"
7141 [(set_attr "type" "alu")
7142 (set_attr "mode" "QI")])
7143
7144 (define_insn "*subqi_1_slp"
7145 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7146 (minus:QI (match_dup 0)
7147 (match_operand:QI 1 "general_operand" "qn,qmn")))
7148 (clobber (reg:CC 17))]
7149 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7151 "sub{b}\t{%1, %0|%0, %1}"
7152 [(set_attr "type" "alu1")
7153 (set_attr "mode" "QI")])
7154
7155 (define_insn "*subqi_2"
7156 [(set (reg 17)
7157 (compare
7158 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7159 (match_operand:QI 2 "general_operand" "qi,qm"))
7160 (const_int 0)))
7161 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7162 (minus:HI (match_dup 1) (match_dup 2)))]
7163 "ix86_match_ccmode (insn, CCGOCmode)
7164 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7165 "sub{b}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "QI")])
7168
7169 (define_insn "*subqi_3"
7170 [(set (reg 17)
7171 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7172 (match_operand:QI 2 "general_operand" "qi,qm")))
7173 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7174 (minus:HI (match_dup 1) (match_dup 2)))]
7175 "ix86_match_ccmode (insn, CCmode)
7176 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7177 "sub{b}\t{%2, %0|%0, %2}"
7178 [(set_attr "type" "alu")
7179 (set_attr "mode" "QI")])
7180
7181 ;; The patterns that match these are at the end of this file.
7182
7183 (define_expand "subxf3"
7184 [(set (match_operand:XF 0 "register_operand" "")
7185 (minus:XF (match_operand:XF 1 "register_operand" "")
7186 (match_operand:XF 2 "register_operand" "")))]
7187 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7188 "")
7189
7190 (define_expand "subtf3"
7191 [(set (match_operand:TF 0 "register_operand" "")
7192 (minus:TF (match_operand:TF 1 "register_operand" "")
7193 (match_operand:TF 2 "register_operand" "")))]
7194 "TARGET_80387"
7195 "")
7196
7197 (define_expand "subdf3"
7198 [(set (match_operand:DF 0 "register_operand" "")
7199 (minus:DF (match_operand:DF 1 "register_operand" "")
7200 (match_operand:DF 2 "nonimmediate_operand" "")))]
7201 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7202 "")
7203
7204 (define_expand "subsf3"
7205 [(set (match_operand:SF 0 "register_operand" "")
7206 (minus:SF (match_operand:SF 1 "register_operand" "")
7207 (match_operand:SF 2 "nonimmediate_operand" "")))]
7208 "TARGET_80387 || TARGET_SSE_MATH"
7209 "")
7210 \f
7211 ;; Multiply instructions
7212
7213 (define_expand "muldi3"
7214 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7215 (mult:DI (match_operand:DI 1 "register_operand" "")
7216 (match_operand:DI 2 "x86_64_general_operand" "")))
7217 (clobber (reg:CC 17))])]
7218 "TARGET_64BIT"
7219 "")
7220
7221 (define_insn "*muldi3_1_rex64"
7222 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7223 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7224 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7225 (clobber (reg:CC 17))]
7226 "TARGET_64BIT
7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228 "@
7229 imul{q}\t{%2, %1, %0|%0, %1, %2}
7230 imul{q}\t{%2, %1, %0|%0, %1, %2}
7231 imul{q}\t{%2, %0|%0, %2}"
7232 [(set_attr "type" "imul")
7233 (set_attr "prefix_0f" "0,0,1")
7234 (set (attr "athlon_decode")
7235 (cond [(eq_attr "cpu" "athlon")
7236 (const_string "vector")
7237 (eq_attr "alternative" "1")
7238 (const_string "vector")
7239 (and (eq_attr "alternative" "2")
7240 (match_operand 1 "memory_operand" ""))
7241 (const_string "vector")]
7242 (const_string "direct")))
7243 (set_attr "mode" "DI")])
7244
7245 (define_expand "mulsi3"
7246 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:SI (match_operand:SI 1 "register_operand" "")
7248 (match_operand:SI 2 "general_operand" "")))
7249 (clobber (reg:CC 17))])]
7250 ""
7251 "")
7252
7253 (define_insn "*mulsi3_1"
7254 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7255 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7256 (match_operand:SI 2 "general_operand" "K,i,mr")))
7257 (clobber (reg:CC 17))]
7258 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7259 "@
7260 imul{l}\t{%2, %1, %0|%0, %1, %2}
7261 imul{l}\t{%2, %1, %0|%0, %1, %2}
7262 imul{l}\t{%2, %0|%0, %2}"
7263 [(set_attr "type" "imul")
7264 (set_attr "prefix_0f" "0,0,1")
7265 (set (attr "athlon_decode")
7266 (cond [(eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (eq_attr "alternative" "1")
7269 (const_string "vector")
7270 (and (eq_attr "alternative" "2")
7271 (match_operand 1 "memory_operand" ""))
7272 (const_string "vector")]
7273 (const_string "direct")))
7274 (set_attr "mode" "SI")])
7275
7276 (define_insn "*mulsi3_1_zext"
7277 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7278 (zero_extend:DI
7279 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7280 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7281 (clobber (reg:CC 17))]
7282 "TARGET_64BIT
7283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7284 "@
7285 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7286 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7287 imul{l}\t{%2, %k0|%k0, %2}"
7288 [(set_attr "type" "imul")
7289 (set_attr "prefix_0f" "0,0,1")
7290 (set (attr "athlon_decode")
7291 (cond [(eq_attr "cpu" "athlon")
7292 (const_string "vector")
7293 (eq_attr "alternative" "1")
7294 (const_string "vector")
7295 (and (eq_attr "alternative" "2")
7296 (match_operand 1 "memory_operand" ""))
7297 (const_string "vector")]
7298 (const_string "direct")))
7299 (set_attr "mode" "SI")])
7300
7301 (define_expand "mulhi3"
7302 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7303 (mult:HI (match_operand:HI 1 "register_operand" "")
7304 (match_operand:HI 2 "general_operand" "")))
7305 (clobber (reg:CC 17))])]
7306 "TARGET_HIMODE_MATH"
7307 "")
7308
7309 (define_insn "*mulhi3_1"
7310 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7311 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7312 (match_operand:HI 2 "general_operand" "K,i,mr")))
7313 (clobber (reg:CC 17))]
7314 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7315 "@
7316 imul{w}\t{%2, %1, %0|%0, %1, %2}
7317 imul{w}\t{%2, %1, %0|%0, %1, %2}
7318 imul{w}\t{%2, %0|%0, %2}"
7319 [(set_attr "type" "imul")
7320 (set_attr "prefix_0f" "0,0,1")
7321 (set (attr "athlon_decode")
7322 (cond [(eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (eq_attr "alternative" "1,2")
7325 (const_string "vector")]
7326 (const_string "direct")))
7327 (set_attr "mode" "HI")])
7328
7329 (define_expand "mulqi3"
7330 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7331 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7332 (match_operand:QI 2 "register_operand" "")))
7333 (clobber (reg:CC 17))])]
7334 "TARGET_QIMODE_MATH"
7335 "")
7336
7337 (define_insn "*mulqi3_1"
7338 [(set (match_operand:QI 0 "register_operand" "=a")
7339 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7340 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7341 (clobber (reg:CC 17))]
7342 "TARGET_QIMODE_MATH
7343 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7344 "mul{b}\t%2"
7345 [(set_attr "type" "imul")
7346 (set_attr "length_immediate" "0")
7347 (set (attr "athlon_decode")
7348 (if_then_else (eq_attr "cpu" "athlon")
7349 (const_string "vector")
7350 (const_string "direct")))
7351 (set_attr "mode" "QI")])
7352
7353 (define_expand "umulqihi3"
7354 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7355 (mult:HI (zero_extend:HI
7356 (match_operand:QI 1 "nonimmediate_operand" ""))
7357 (zero_extend:HI
7358 (match_operand:QI 2 "register_operand" ""))))
7359 (clobber (reg:CC 17))])]
7360 "TARGET_QIMODE_MATH"
7361 "")
7362
7363 (define_insn "*umulqihi3_1"
7364 [(set (match_operand:HI 0 "register_operand" "=a")
7365 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7366 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7367 (clobber (reg:CC 17))]
7368 "TARGET_QIMODE_MATH
7369 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7370 "mul{b}\t%2"
7371 [(set_attr "type" "imul")
7372 (set_attr "length_immediate" "0")
7373 (set (attr "athlon_decode")
7374 (if_then_else (eq_attr "cpu" "athlon")
7375 (const_string "vector")
7376 (const_string "direct")))
7377 (set_attr "mode" "QI")])
7378
7379 (define_expand "mulqihi3"
7380 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7381 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7382 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7383 (clobber (reg:CC 17))])]
7384 "TARGET_QIMODE_MATH"
7385 "")
7386
7387 (define_insn "*mulqihi3_insn"
7388 [(set (match_operand:HI 0 "register_operand" "=a")
7389 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7390 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7391 (clobber (reg:CC 17))]
7392 "TARGET_QIMODE_MATH
7393 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7394 "imul{b}\t%2"
7395 [(set_attr "type" "imul")
7396 (set_attr "length_immediate" "0")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "direct")))
7401 (set_attr "mode" "QI")])
7402
7403 (define_expand "umulditi3"
7404 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7405 (mult:TI (zero_extend:TI
7406 (match_operand:DI 1 "nonimmediate_operand" ""))
7407 (zero_extend:TI
7408 (match_operand:DI 2 "register_operand" ""))))
7409 (clobber (reg:CC 17))])]
7410 "TARGET_64BIT"
7411 "")
7412
7413 (define_insn "*umulditi3_insn"
7414 [(set (match_operand:TI 0 "register_operand" "=A")
7415 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7416 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7417 (clobber (reg:CC 17))]
7418 "TARGET_64BIT
7419 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7420 "mul{q}\t%2"
7421 [(set_attr "type" "imul")
7422 (set_attr "ppro_uops" "few")
7423 (set_attr "length_immediate" "0")
7424 (set (attr "athlon_decode")
7425 (if_then_else (eq_attr "cpu" "athlon")
7426 (const_string "vector")
7427 (const_string "double")))
7428 (set_attr "mode" "DI")])
7429
7430 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7431 (define_expand "umulsidi3"
7432 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7433 (mult:DI (zero_extend:DI
7434 (match_operand:SI 1 "nonimmediate_operand" ""))
7435 (zero_extend:DI
7436 (match_operand:SI 2 "register_operand" ""))))
7437 (clobber (reg:CC 17))])]
7438 "!TARGET_64BIT"
7439 "")
7440
7441 (define_insn "*umulsidi3_insn"
7442 [(set (match_operand:DI 0 "register_operand" "=A")
7443 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7444 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7445 (clobber (reg:CC 17))]
7446 "!TARGET_64BIT
7447 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7448 "mul{l}\t%2"
7449 [(set_attr "type" "imul")
7450 (set_attr "ppro_uops" "few")
7451 (set_attr "length_immediate" "0")
7452 (set (attr "athlon_decode")
7453 (if_then_else (eq_attr "cpu" "athlon")
7454 (const_string "vector")
7455 (const_string "double")))
7456 (set_attr "mode" "SI")])
7457
7458 (define_expand "mulditi3"
7459 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7460 (mult:TI (sign_extend:TI
7461 (match_operand:DI 1 "nonimmediate_operand" ""))
7462 (sign_extend:TI
7463 (match_operand:DI 2 "register_operand" ""))))
7464 (clobber (reg:CC 17))])]
7465 "TARGET_64BIT"
7466 "")
7467
7468 (define_insn "*mulditi3_insn"
7469 [(set (match_operand:TI 0 "register_operand" "=A")
7470 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7471 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7472 (clobber (reg:CC 17))]
7473 "TARGET_64BIT
7474 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7475 "imul{q}\t%2"
7476 [(set_attr "type" "imul")
7477 (set_attr "length_immediate" "0")
7478 (set (attr "athlon_decode")
7479 (if_then_else (eq_attr "cpu" "athlon")
7480 (const_string "vector")
7481 (const_string "double")))
7482 (set_attr "mode" "DI")])
7483
7484 (define_expand "mulsidi3"
7485 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7486 (mult:DI (sign_extend:DI
7487 (match_operand:SI 1 "nonimmediate_operand" ""))
7488 (sign_extend:DI
7489 (match_operand:SI 2 "register_operand" ""))))
7490 (clobber (reg:CC 17))])]
7491 "!TARGET_64BIT"
7492 "")
7493
7494 (define_insn "*mulsidi3_insn"
7495 [(set (match_operand:DI 0 "register_operand" "=A")
7496 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7497 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7498 (clobber (reg:CC 17))]
7499 "!TARGET_64BIT
7500 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7501 "imul{l}\t%2"
7502 [(set_attr "type" "imul")
7503 (set_attr "length_immediate" "0")
7504 (set (attr "athlon_decode")
7505 (if_then_else (eq_attr "cpu" "athlon")
7506 (const_string "vector")
7507 (const_string "double")))
7508 (set_attr "mode" "SI")])
7509
7510 (define_expand "umuldi3_highpart"
7511 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512 (truncate:DI
7513 (lshiftrt:TI
7514 (mult:TI (zero_extend:TI
7515 (match_operand:DI 1 "nonimmediate_operand" ""))
7516 (zero_extend:TI
7517 (match_operand:DI 2 "register_operand" "")))
7518 (const_int 64))))
7519 (clobber (match_scratch:DI 3 ""))
7520 (clobber (reg:CC 17))])]
7521 "TARGET_64BIT"
7522 "")
7523
7524 (define_insn "*umuldi3_highpart_rex64"
7525 [(set (match_operand:DI 0 "register_operand" "=d")
7526 (truncate:DI
7527 (lshiftrt:TI
7528 (mult:TI (zero_extend:TI
7529 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7530 (zero_extend:TI
7531 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532 (const_int 64))))
7533 (clobber (match_scratch:DI 3 "=1"))
7534 (clobber (reg:CC 17))]
7535 "TARGET_64BIT
7536 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7537 "mul{q}\t%2"
7538 [(set_attr "type" "imul")
7539 (set_attr "ppro_uops" "few")
7540 (set_attr "length_immediate" "0")
7541 (set (attr "athlon_decode")
7542 (if_then_else (eq_attr "cpu" "athlon")
7543 (const_string "vector")
7544 (const_string "double")))
7545 (set_attr "mode" "DI")])
7546
7547 (define_expand "umulsi3_highpart"
7548 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7549 (truncate:SI
7550 (lshiftrt:DI
7551 (mult:DI (zero_extend:DI
7552 (match_operand:SI 1 "nonimmediate_operand" ""))
7553 (zero_extend:DI
7554 (match_operand:SI 2 "register_operand" "")))
7555 (const_int 32))))
7556 (clobber (match_scratch:SI 3 ""))
7557 (clobber (reg:CC 17))])]
7558 ""
7559 "")
7560
7561 (define_insn "*umulsi3_highpart_insn"
7562 [(set (match_operand:SI 0 "register_operand" "=d")
7563 (truncate:SI
7564 (lshiftrt:DI
7565 (mult:DI (zero_extend:DI
7566 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7567 (zero_extend:DI
7568 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7569 (const_int 32))))
7570 (clobber (match_scratch:SI 3 "=1"))
7571 (clobber (reg:CC 17))]
7572 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7573 "mul{l}\t%2"
7574 [(set_attr "type" "imul")
7575 (set_attr "ppro_uops" "few")
7576 (set_attr "length_immediate" "0")
7577 (set (attr "athlon_decode")
7578 (if_then_else (eq_attr "cpu" "athlon")
7579 (const_string "vector")
7580 (const_string "double")))
7581 (set_attr "mode" "SI")])
7582
7583 (define_insn "*umulsi3_highpart_zext"
7584 [(set (match_operand:DI 0 "register_operand" "=d")
7585 (zero_extend:DI (truncate:SI
7586 (lshiftrt:DI
7587 (mult:DI (zero_extend:DI
7588 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7589 (zero_extend:DI
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591 (const_int 32)))))
7592 (clobber (match_scratch:SI 3 "=1"))
7593 (clobber (reg:CC 17))]
7594 "TARGET_64BIT
7595 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7596 "mul{l}\t%2"
7597 [(set_attr "type" "imul")
7598 (set_attr "ppro_uops" "few")
7599 (set_attr "length_immediate" "0")
7600 (set (attr "athlon_decode")
7601 (if_then_else (eq_attr "cpu" "athlon")
7602 (const_string "vector")
7603 (const_string "double")))
7604 (set_attr "mode" "SI")])
7605
7606 (define_expand "smuldi3_highpart"
7607 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7608 (truncate:DI
7609 (lshiftrt:TI
7610 (mult:TI (sign_extend:TI
7611 (match_operand:DI 1 "nonimmediate_operand" ""))
7612 (sign_extend:TI
7613 (match_operand:DI 2 "register_operand" "")))
7614 (const_int 64))))
7615 (clobber (match_scratch:DI 3 ""))
7616 (clobber (reg:CC 17))])]
7617 "TARGET_64BIT"
7618 "")
7619
7620 (define_insn "*smuldi3_highpart_rex64"
7621 [(set (match_operand:DI 0 "register_operand" "=d")
7622 (truncate:DI
7623 (lshiftrt:TI
7624 (mult:TI (sign_extend:TI
7625 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626 (sign_extend:TI
7627 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628 (const_int 64))))
7629 (clobber (match_scratch:DI 3 "=1"))
7630 (clobber (reg:CC 17))]
7631 "TARGET_64BIT
7632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7633 "imul{q}\t%2"
7634 [(set_attr "type" "imul")
7635 (set_attr "ppro_uops" "few")
7636 (set (attr "athlon_decode")
7637 (if_then_else (eq_attr "cpu" "athlon")
7638 (const_string "vector")
7639 (const_string "double")))
7640 (set_attr "mode" "DI")])
7641
7642 (define_expand "smulsi3_highpart"
7643 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7644 (truncate:SI
7645 (lshiftrt:DI
7646 (mult:DI (sign_extend:DI
7647 (match_operand:SI 1 "nonimmediate_operand" ""))
7648 (sign_extend:DI
7649 (match_operand:SI 2 "register_operand" "")))
7650 (const_int 32))))
7651 (clobber (match_scratch:SI 3 ""))
7652 (clobber (reg:CC 17))])]
7653 ""
7654 "")
7655
7656 (define_insn "*smulsi3_highpart_insn"
7657 [(set (match_operand:SI 0 "register_operand" "=d")
7658 (truncate:SI
7659 (lshiftrt:DI
7660 (mult:DI (sign_extend:DI
7661 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7662 (sign_extend:DI
7663 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7664 (const_int 32))))
7665 (clobber (match_scratch:SI 3 "=1"))
7666 (clobber (reg:CC 17))]
7667 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7668 "imul{l}\t%2"
7669 [(set_attr "type" "imul")
7670 (set_attr "ppro_uops" "few")
7671 (set (attr "athlon_decode")
7672 (if_then_else (eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (const_string "double")))
7675 (set_attr "mode" "SI")])
7676
7677 (define_insn "*smulsi3_highpart_zext"
7678 [(set (match_operand:DI 0 "register_operand" "=d")
7679 (zero_extend:DI (truncate:SI
7680 (lshiftrt:DI
7681 (mult:DI (sign_extend:DI
7682 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7683 (sign_extend:DI
7684 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7685 (const_int 32)))))
7686 (clobber (match_scratch:SI 3 "=1"))
7687 (clobber (reg:CC 17))]
7688 "TARGET_64BIT
7689 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7690 "imul{l}\t%2"
7691 [(set_attr "type" "imul")
7692 (set_attr "ppro_uops" "few")
7693 (set (attr "athlon_decode")
7694 (if_then_else (eq_attr "cpu" "athlon")
7695 (const_string "vector")
7696 (const_string "double")))
7697 (set_attr "mode" "SI")])
7698
7699 ;; The patterns that match these are at the end of this file.
7700
7701 (define_expand "mulxf3"
7702 [(set (match_operand:XF 0 "register_operand" "")
7703 (mult:XF (match_operand:XF 1 "register_operand" "")
7704 (match_operand:XF 2 "register_operand" "")))]
7705 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7706 "")
7707
7708 (define_expand "multf3"
7709 [(set (match_operand:TF 0 "register_operand" "")
7710 (mult:TF (match_operand:TF 1 "register_operand" "")
7711 (match_operand:TF 2 "register_operand" "")))]
7712 "TARGET_80387"
7713 "")
7714
7715 (define_expand "muldf3"
7716 [(set (match_operand:DF 0 "register_operand" "")
7717 (mult:DF (match_operand:DF 1 "register_operand" "")
7718 (match_operand:DF 2 "nonimmediate_operand" "")))]
7719 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7720 "")
7721
7722 (define_expand "mulsf3"
7723 [(set (match_operand:SF 0 "register_operand" "")
7724 (mult:SF (match_operand:SF 1 "register_operand" "")
7725 (match_operand:SF 2 "nonimmediate_operand" "")))]
7726 "TARGET_80387 || TARGET_SSE_MATH"
7727 "")
7728 \f
7729 ;; Divide instructions
7730
7731 (define_insn "divqi3"
7732 [(set (match_operand:QI 0 "register_operand" "=a")
7733 (div:QI (match_operand:HI 1 "register_operand" "0")
7734 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7735 (clobber (reg:CC 17))]
7736 "TARGET_QIMODE_MATH"
7737 "idiv{b}\t%2"
7738 [(set_attr "type" "idiv")
7739 (set_attr "mode" "QI")
7740 (set_attr "ppro_uops" "few")])
7741
7742 (define_insn "udivqi3"
7743 [(set (match_operand:QI 0 "register_operand" "=a")
7744 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7745 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7746 (clobber (reg:CC 17))]
7747 "TARGET_QIMODE_MATH"
7748 "div{b}\t%2"
7749 [(set_attr "type" "idiv")
7750 (set_attr "mode" "QI")
7751 (set_attr "ppro_uops" "few")])
7752
7753 ;; The patterns that match these are at the end of this file.
7754
7755 (define_expand "divxf3"
7756 [(set (match_operand:XF 0 "register_operand" "")
7757 (div:XF (match_operand:XF 1 "register_operand" "")
7758 (match_operand:XF 2 "register_operand" "")))]
7759 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7760 "")
7761
7762 (define_expand "divtf3"
7763 [(set (match_operand:TF 0 "register_operand" "")
7764 (div:TF (match_operand:TF 1 "register_operand" "")
7765 (match_operand:TF 2 "register_operand" "")))]
7766 "TARGET_80387"
7767 "")
7768
7769 (define_expand "divdf3"
7770 [(set (match_operand:DF 0 "register_operand" "")
7771 (div:DF (match_operand:DF 1 "register_operand" "")
7772 (match_operand:DF 2 "nonimmediate_operand" "")))]
7773 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7774 "")
7775
7776 (define_expand "divsf3"
7777 [(set (match_operand:SF 0 "register_operand" "")
7778 (div:SF (match_operand:SF 1 "register_operand" "")
7779 (match_operand:SF 2 "nonimmediate_operand" "")))]
7780 "TARGET_80387 || TARGET_SSE_MATH"
7781 "")
7782 \f
7783 ;; Remainder instructions.
7784
7785 (define_expand "divmoddi4"
7786 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7787 (div:DI (match_operand:DI 1 "register_operand" "")
7788 (match_operand:DI 2 "nonimmediate_operand" "")))
7789 (set (match_operand:DI 3 "register_operand" "")
7790 (mod:DI (match_dup 1) (match_dup 2)))
7791 (clobber (reg:CC 17))])]
7792 "TARGET_64BIT"
7793 "")
7794
7795 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7796 ;; Penalize eax case slightly because it results in worse scheduling
7797 ;; of code.
7798 (define_insn "*divmoddi4_nocltd_rex64"
7799 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7800 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7801 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7802 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7803 (mod:DI (match_dup 2) (match_dup 3)))
7804 (clobber (reg:CC 17))]
7805 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7806 "#"
7807 [(set_attr "type" "multi")])
7808
7809 (define_insn "*divmoddi4_cltd_rex64"
7810 [(set (match_operand:DI 0 "register_operand" "=a")
7811 (div:DI (match_operand:DI 2 "register_operand" "a")
7812 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7813 (set (match_operand:DI 1 "register_operand" "=&d")
7814 (mod:DI (match_dup 2) (match_dup 3)))
7815 (clobber (reg:CC 17))]
7816 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7817 "#"
7818 [(set_attr "type" "multi")])
7819
7820 (define_insn "*divmoddi_noext_rex64"
7821 [(set (match_operand:DI 0 "register_operand" "=a")
7822 (div:DI (match_operand:DI 1 "register_operand" "0")
7823 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7824 (set (match_operand:DI 3 "register_operand" "=d")
7825 (mod:DI (match_dup 1) (match_dup 2)))
7826 (use (match_operand:DI 4 "register_operand" "3"))
7827 (clobber (reg:CC 17))]
7828 "TARGET_64BIT"
7829 "idiv{q}\t%2"
7830 [(set_attr "type" "idiv")
7831 (set_attr "mode" "DI")
7832 (set_attr "ppro_uops" "few")])
7833
7834 (define_split
7835 [(set (match_operand:DI 0 "register_operand" "")
7836 (div:DI (match_operand:DI 1 "register_operand" "")
7837 (match_operand:DI 2 "nonimmediate_operand" "")))
7838 (set (match_operand:DI 3 "register_operand" "")
7839 (mod:DI (match_dup 1) (match_dup 2)))
7840 (clobber (reg:CC 17))]
7841 "TARGET_64BIT && reload_completed"
7842 [(parallel [(set (match_dup 3)
7843 (ashiftrt:DI (match_dup 4) (const_int 63)))
7844 (clobber (reg:CC 17))])
7845 (parallel [(set (match_dup 0)
7846 (div:DI (reg:DI 0) (match_dup 2)))
7847 (set (match_dup 3)
7848 (mod:DI (reg:DI 0) (match_dup 2)))
7849 (use (match_dup 3))
7850 (clobber (reg:CC 17))])]
7851 {
7852 /* Avoid use of cltd in favor of a mov+shift. */
7853 if (!TARGET_USE_CLTD && !optimize_size)
7854 {
7855 if (true_regnum (operands[1]))
7856 emit_move_insn (operands[0], operands[1]);
7857 else
7858 emit_move_insn (operands[3], operands[1]);
7859 operands[4] = operands[3];
7860 }
7861 else
7862 {
7863 if (true_regnum (operands[1]))
7864 abort();
7865 operands[4] = operands[1];
7866 }
7867 })
7868
7869
7870 (define_expand "divmodsi4"
7871 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7872 (div:SI (match_operand:SI 1 "register_operand" "")
7873 (match_operand:SI 2 "nonimmediate_operand" "")))
7874 (set (match_operand:SI 3 "register_operand" "")
7875 (mod:SI (match_dup 1) (match_dup 2)))
7876 (clobber (reg:CC 17))])]
7877 ""
7878 "")
7879
7880 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7881 ;; Penalize eax case slightly because it results in worse scheduling
7882 ;; of code.
7883 (define_insn "*divmodsi4_nocltd"
7884 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7885 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7886 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7887 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7888 (mod:SI (match_dup 2) (match_dup 3)))
7889 (clobber (reg:CC 17))]
7890 "!optimize_size && !TARGET_USE_CLTD"
7891 "#"
7892 [(set_attr "type" "multi")])
7893
7894 (define_insn "*divmodsi4_cltd"
7895 [(set (match_operand:SI 0 "register_operand" "=a")
7896 (div:SI (match_operand:SI 2 "register_operand" "a")
7897 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7898 (set (match_operand:SI 1 "register_operand" "=&d")
7899 (mod:SI (match_dup 2) (match_dup 3)))
7900 (clobber (reg:CC 17))]
7901 "optimize_size || TARGET_USE_CLTD"
7902 "#"
7903 [(set_attr "type" "multi")])
7904
7905 (define_insn "*divmodsi_noext"
7906 [(set (match_operand:SI 0 "register_operand" "=a")
7907 (div:SI (match_operand:SI 1 "register_operand" "0")
7908 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7909 (set (match_operand:SI 3 "register_operand" "=d")
7910 (mod:SI (match_dup 1) (match_dup 2)))
7911 (use (match_operand:SI 4 "register_operand" "3"))
7912 (clobber (reg:CC 17))]
7913 ""
7914 "idiv{l}\t%2"
7915 [(set_attr "type" "idiv")
7916 (set_attr "mode" "SI")
7917 (set_attr "ppro_uops" "few")])
7918
7919 (define_split
7920 [(set (match_operand:SI 0 "register_operand" "")
7921 (div:SI (match_operand:SI 1 "register_operand" "")
7922 (match_operand:SI 2 "nonimmediate_operand" "")))
7923 (set (match_operand:SI 3 "register_operand" "")
7924 (mod:SI (match_dup 1) (match_dup 2)))
7925 (clobber (reg:CC 17))]
7926 "reload_completed"
7927 [(parallel [(set (match_dup 3)
7928 (ashiftrt:SI (match_dup 4) (const_int 31)))
7929 (clobber (reg:CC 17))])
7930 (parallel [(set (match_dup 0)
7931 (div:SI (reg:SI 0) (match_dup 2)))
7932 (set (match_dup 3)
7933 (mod:SI (reg:SI 0) (match_dup 2)))
7934 (use (match_dup 3))
7935 (clobber (reg:CC 17))])]
7936 {
7937 /* Avoid use of cltd in favor of a mov+shift. */
7938 if (!TARGET_USE_CLTD && !optimize_size)
7939 {
7940 if (true_regnum (operands[1]))
7941 emit_move_insn (operands[0], operands[1]);
7942 else
7943 emit_move_insn (operands[3], operands[1]);
7944 operands[4] = operands[3];
7945 }
7946 else
7947 {
7948 if (true_regnum (operands[1]))
7949 abort();
7950 operands[4] = operands[1];
7951 }
7952 })
7953 ;; %%% Split me.
7954 (define_insn "divmodhi4"
7955 [(set (match_operand:HI 0 "register_operand" "=a")
7956 (div:HI (match_operand:HI 1 "register_operand" "0")
7957 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7958 (set (match_operand:HI 3 "register_operand" "=&d")
7959 (mod:HI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC 17))]
7961 "TARGET_HIMODE_MATH"
7962 "cwtd\;idiv{w}\t%2"
7963 [(set_attr "type" "multi")
7964 (set_attr "length_immediate" "0")
7965 (set_attr "mode" "SI")])
7966
7967 (define_insn "udivmoddi4"
7968 [(set (match_operand:DI 0 "register_operand" "=a")
7969 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7970 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7971 (set (match_operand:DI 3 "register_operand" "=&d")
7972 (umod:DI (match_dup 1) (match_dup 2)))
7973 (clobber (reg:CC 17))]
7974 "TARGET_64BIT"
7975 "xor{q}\t%3, %3\;div{q}\t%2"
7976 [(set_attr "type" "multi")
7977 (set_attr "length_immediate" "0")
7978 (set_attr "mode" "DI")])
7979
7980 (define_insn "*udivmoddi4_noext"
7981 [(set (match_operand:DI 0 "register_operand" "=a")
7982 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7983 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7984 (set (match_operand:DI 3 "register_operand" "=d")
7985 (umod:DI (match_dup 1) (match_dup 2)))
7986 (use (match_dup 3))
7987 (clobber (reg:CC 17))]
7988 "TARGET_64BIT"
7989 "div{q}\t%2"
7990 [(set_attr "type" "idiv")
7991 (set_attr "ppro_uops" "few")
7992 (set_attr "mode" "DI")])
7993
7994 (define_split
7995 [(set (match_operand:DI 0 "register_operand" "")
7996 (udiv:DI (match_operand:DI 1 "register_operand" "")
7997 (match_operand:DI 2 "nonimmediate_operand" "")))
7998 (set (match_operand:DI 3 "register_operand" "")
7999 (umod:DI (match_dup 1) (match_dup 2)))
8000 (clobber (reg:CC 17))]
8001 "TARGET_64BIT && reload_completed"
8002 [(set (match_dup 3) (const_int 0))
8003 (parallel [(set (match_dup 0)
8004 (udiv:DI (match_dup 1) (match_dup 2)))
8005 (set (match_dup 3)
8006 (umod:DI (match_dup 1) (match_dup 2)))
8007 (use (match_dup 3))
8008 (clobber (reg:CC 17))])]
8009 "")
8010
8011 (define_insn "udivmodsi4"
8012 [(set (match_operand:SI 0 "register_operand" "=a")
8013 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8014 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8015 (set (match_operand:SI 3 "register_operand" "=&d")
8016 (umod:SI (match_dup 1) (match_dup 2)))
8017 (clobber (reg:CC 17))]
8018 ""
8019 "xor{l}\t%3, %3\;div{l}\t%2"
8020 [(set_attr "type" "multi")
8021 (set_attr "length_immediate" "0")
8022 (set_attr "mode" "SI")])
8023
8024 (define_insn "*udivmodsi4_noext"
8025 [(set (match_operand:SI 0 "register_operand" "=a")
8026 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8027 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8028 (set (match_operand:SI 3 "register_operand" "=d")
8029 (umod:SI (match_dup 1) (match_dup 2)))
8030 (use (match_dup 3))
8031 (clobber (reg:CC 17))]
8032 ""
8033 "div{l}\t%2"
8034 [(set_attr "type" "idiv")
8035 (set_attr "ppro_uops" "few")
8036 (set_attr "mode" "SI")])
8037
8038 (define_split
8039 [(set (match_operand:SI 0 "register_operand" "")
8040 (udiv:SI (match_operand:SI 1 "register_operand" "")
8041 (match_operand:SI 2 "nonimmediate_operand" "")))
8042 (set (match_operand:SI 3 "register_operand" "")
8043 (umod:SI (match_dup 1) (match_dup 2)))
8044 (clobber (reg:CC 17))]
8045 "reload_completed"
8046 [(set (match_dup 3) (const_int 0))
8047 (parallel [(set (match_dup 0)
8048 (udiv:SI (match_dup 1) (match_dup 2)))
8049 (set (match_dup 3)
8050 (umod:SI (match_dup 1) (match_dup 2)))
8051 (use (match_dup 3))
8052 (clobber (reg:CC 17))])]
8053 "")
8054
8055 (define_expand "udivmodhi4"
8056 [(set (match_dup 4) (const_int 0))
8057 (parallel [(set (match_operand:HI 0 "register_operand" "")
8058 (udiv:HI (match_operand:HI 1 "register_operand" "")
8059 (match_operand:HI 2 "nonimmediate_operand" "")))
8060 (set (match_operand:HI 3 "register_operand" "")
8061 (umod:HI (match_dup 1) (match_dup 2)))
8062 (use (match_dup 4))
8063 (clobber (reg:CC 17))])]
8064 "TARGET_HIMODE_MATH"
8065 "operands[4] = gen_reg_rtx (HImode);")
8066
8067 (define_insn "*udivmodhi_noext"
8068 [(set (match_operand:HI 0 "register_operand" "=a")
8069 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8070 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8071 (set (match_operand:HI 3 "register_operand" "=d")
8072 (umod:HI (match_dup 1) (match_dup 2)))
8073 (use (match_operand:HI 4 "register_operand" "3"))
8074 (clobber (reg:CC 17))]
8075 ""
8076 "div{w}\t%2"
8077 [(set_attr "type" "idiv")
8078 (set_attr "mode" "HI")
8079 (set_attr "ppro_uops" "few")])
8080
8081 ;; We can not use div/idiv for double division, because it causes
8082 ;; "division by zero" on the overflow and that's not what we expect
8083 ;; from truncate. Because true (non truncating) double division is
8084 ;; never generated, we can't create this insn anyway.
8085 ;
8086 ;(define_insn ""
8087 ; [(set (match_operand:SI 0 "register_operand" "=a")
8088 ; (truncate:SI
8089 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8090 ; (zero_extend:DI
8091 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8092 ; (set (match_operand:SI 3 "register_operand" "=d")
8093 ; (truncate:SI
8094 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8095 ; (clobber (reg:CC 17))]
8096 ; ""
8097 ; "div{l}\t{%2, %0|%0, %2}"
8098 ; [(set_attr "type" "idiv")
8099 ; (set_attr "ppro_uops" "few")])
8100 \f
8101 ;;- Logical AND instructions
8102
8103 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8104 ;; Note that this excludes ah.
8105
8106 (define_insn "*testdi_1_rex64"
8107 [(set (reg 17)
8108 (compare
8109 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8110 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8111 (const_int 0)))]
8112 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8113 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8114 "@
8115 test{l}\t{%k1, %k0|%k0, %k1}
8116 test{l}\t{%k1, %k0|%k0, %k1}
8117 test{q}\t{%1, %0|%0, %1}
8118 test{q}\t{%1, %0|%0, %1}
8119 test{q}\t{%1, %0|%0, %1}"
8120 [(set_attr "type" "test")
8121 (set_attr "modrm" "0,1,0,1,1")
8122 (set_attr "mode" "SI,SI,DI,DI,DI")
8123 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8124
8125 (define_insn "testsi_1"
8126 [(set (reg 17)
8127 (compare
8128 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8129 (match_operand:SI 1 "general_operand" "in,in,rin"))
8130 (const_int 0)))]
8131 "ix86_match_ccmode (insn, CCNOmode)
8132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8133 "test{l}\t{%1, %0|%0, %1}"
8134 [(set_attr "type" "test")
8135 (set_attr "modrm" "0,1,1")
8136 (set_attr "mode" "SI")
8137 (set_attr "pent_pair" "uv,np,uv")])
8138
8139 (define_expand "testsi_ccno_1"
8140 [(set (reg:CCNO 17)
8141 (compare:CCNO
8142 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8143 (match_operand:SI 1 "nonmemory_operand" ""))
8144 (const_int 0)))]
8145 ""
8146 "")
8147
8148 (define_insn "*testhi_1"
8149 [(set (reg 17)
8150 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8151 (match_operand:HI 1 "general_operand" "n,n,rn"))
8152 (const_int 0)))]
8153 "ix86_match_ccmode (insn, CCNOmode)
8154 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8155 "test{w}\t{%1, %0|%0, %1}"
8156 [(set_attr "type" "test")
8157 (set_attr "modrm" "0,1,1")
8158 (set_attr "mode" "HI")
8159 (set_attr "pent_pair" "uv,np,uv")])
8160
8161 (define_expand "testqi_ccz_1"
8162 [(set (reg:CCZ 17)
8163 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8164 (match_operand:QI 1 "nonmemory_operand" ""))
8165 (const_int 0)))]
8166 ""
8167 "")
8168
8169 (define_insn "*testqi_1"
8170 [(set (reg 17)
8171 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8172 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8173 (const_int 0)))]
8174 "ix86_match_ccmode (insn, CCNOmode)
8175 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8176 {
8177 if (which_alternative == 3)
8178 {
8179 if (GET_CODE (operands[1]) == CONST_INT
8180 && (INTVAL (operands[1]) & 0xffffff00))
8181 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8182 return "test{l}\t{%1, %k0|%k0, %1}";
8183 }
8184 return "test{b}\t{%1, %0|%0, %1}";
8185 }
8186 [(set_attr "type" "test")
8187 (set_attr "modrm" "0,1,1,1")
8188 (set_attr "mode" "QI,QI,QI,SI")
8189 (set_attr "pent_pair" "uv,np,uv,np")])
8190
8191 (define_expand "testqi_ext_ccno_0"
8192 [(set (reg:CCNO 17)
8193 (compare:CCNO
8194 (and:SI
8195 (zero_extract:SI
8196 (match_operand 0 "ext_register_operand" "")
8197 (const_int 8)
8198 (const_int 8))
8199 (match_operand 1 "const_int_operand" ""))
8200 (const_int 0)))]
8201 ""
8202 "")
8203
8204 (define_insn "*testqi_ext_0"
8205 [(set (reg 17)
8206 (compare
8207 (and:SI
8208 (zero_extract:SI
8209 (match_operand 0 "ext_register_operand" "Q")
8210 (const_int 8)
8211 (const_int 8))
8212 (match_operand 1 "const_int_operand" "n"))
8213 (const_int 0)))]
8214 "ix86_match_ccmode (insn, CCNOmode)"
8215 "test{b}\t{%1, %h0|%h0, %1}"
8216 [(set_attr "type" "test")
8217 (set_attr "mode" "QI")
8218 (set_attr "length_immediate" "1")
8219 (set_attr "pent_pair" "np")])
8220
8221 (define_insn "*testqi_ext_1"
8222 [(set (reg 17)
8223 (compare
8224 (and:SI
8225 (zero_extract:SI
8226 (match_operand 0 "ext_register_operand" "Q")
8227 (const_int 8)
8228 (const_int 8))
8229 (zero_extend:SI
8230 (match_operand:QI 1 "general_operand" "Qm")))
8231 (const_int 0)))]
8232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8234 "test{b}\t{%1, %h0|%h0, %1}"
8235 [(set_attr "type" "test")
8236 (set_attr "mode" "QI")])
8237
8238 (define_insn "*testqi_ext_1_rex64"
8239 [(set (reg 17)
8240 (compare
8241 (and:SI
8242 (zero_extract:SI
8243 (match_operand 0 "ext_register_operand" "Q")
8244 (const_int 8)
8245 (const_int 8))
8246 (zero_extend:SI
8247 (match_operand:QI 1 "register_operand" "Q")))
8248 (const_int 0)))]
8249 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8250 "test{b}\t{%1, %h0|%h0, %1}"
8251 [(set_attr "type" "test")
8252 (set_attr "mode" "QI")])
8253
8254 (define_insn "*testqi_ext_2"
8255 [(set (reg 17)
8256 (compare
8257 (and:SI
8258 (zero_extract:SI
8259 (match_operand 0 "ext_register_operand" "Q")
8260 (const_int 8)
8261 (const_int 8))
8262 (zero_extract:SI
8263 (match_operand 1 "ext_register_operand" "Q")
8264 (const_int 8)
8265 (const_int 8)))
8266 (const_int 0)))]
8267 "ix86_match_ccmode (insn, CCNOmode)"
8268 "test{b}\t{%h1, %h0|%h0, %h1}"
8269 [(set_attr "type" "test")
8270 (set_attr "mode" "QI")])
8271
8272 ;; Combine likes to form bit extractions for some tests. Humor it.
8273 (define_insn "*testqi_ext_3"
8274 [(set (reg 17)
8275 (compare (zero_extract:SI
8276 (match_operand 0 "nonimmediate_operand" "rm")
8277 (match_operand:SI 1 "const_int_operand" "")
8278 (match_operand:SI 2 "const_int_operand" ""))
8279 (const_int 0)))]
8280 "ix86_match_ccmode (insn, CCNOmode)
8281 && (GET_MODE (operands[0]) == SImode
8282 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8283 || GET_MODE (operands[0]) == HImode
8284 || GET_MODE (operands[0]) == QImode)"
8285 "#")
8286
8287 (define_insn "*testqi_ext_3_rex64"
8288 [(set (reg 17)
8289 (compare (zero_extract:DI
8290 (match_operand 0 "nonimmediate_operand" "rm")
8291 (match_operand:DI 1 "const_int_operand" "")
8292 (match_operand:DI 2 "const_int_operand" ""))
8293 (const_int 0)))]
8294 "TARGET_64BIT
8295 && ix86_match_ccmode (insn, CCNOmode)
8296 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8297 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8298 /* Ensure that resulting mask is zero or sign extended operand. */
8299 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8300 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8301 && INTVAL (operands[1]) > 32))
8302 && (GET_MODE (operands[0]) == SImode
8303 || GET_MODE (operands[0]) == DImode
8304 || GET_MODE (operands[0]) == HImode
8305 || GET_MODE (operands[0]) == QImode)"
8306 "#")
8307
8308 (define_split
8309 [(set (reg 17)
8310 (compare (zero_extract
8311 (match_operand 0 "nonimmediate_operand" "")
8312 (match_operand 1 "const_int_operand" "")
8313 (match_operand 2 "const_int_operand" ""))
8314 (const_int 0)))]
8315 "ix86_match_ccmode (insn, CCNOmode)"
8316 [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8317 {
8318 HOST_WIDE_INT len = INTVAL (operands[1]);
8319 HOST_WIDE_INT pos = INTVAL (operands[2]);
8320 HOST_WIDE_INT mask;
8321 enum machine_mode mode, submode;
8322
8323 mode = GET_MODE (operands[0]);
8324 if (GET_CODE (operands[0]) == MEM)
8325 {
8326 /* ??? Combine likes to put non-volatile mem extractions in QImode
8327 no matter the size of the test. So find a mode that works. */
8328 if (! MEM_VOLATILE_P (operands[0]))
8329 {
8330 mode = smallest_mode_for_size (pos + len, MODE_INT);
8331 operands[0] = adjust_address (operands[0], mode, 0);
8332 }
8333 }
8334 else if (GET_CODE (operands[0]) == SUBREG
8335 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8336 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8337 && pos + len <= GET_MODE_BITSIZE (submode))
8338 {
8339 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8340 mode = submode;
8341 operands[0] = SUBREG_REG (operands[0]);
8342 }
8343 else if (mode == HImode && pos + len <= 8)
8344 {
8345 /* Small HImode tests can be converted to QImode. */
8346 mode = QImode;
8347 operands[0] = gen_lowpart (QImode, operands[0]);
8348 }
8349
8350 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8351 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8352
8353 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8354 })
8355
8356 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8357 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8358 ;; this is relatively important trick.
8359 ;; Do the conversion only post-reload to avoid limiting of the register class
8360 ;; to QI regs.
8361 (define_split
8362 [(set (reg 17)
8363 (compare
8364 (and (match_operand 0 "register_operand" "")
8365 (match_operand 1 "const_int_operand" ""))
8366 (const_int 0)))]
8367 "reload_completed
8368 && QI_REG_P (operands[0])
8369 && ((ix86_match_ccmode (insn, CCZmode)
8370 && !(INTVAL (operands[1]) & ~(255 << 8)))
8371 || (ix86_match_ccmode (insn, CCNOmode)
8372 && !(INTVAL (operands[1]) & ~(127 << 8))))
8373 && GET_MODE (operands[0]) != QImode"
8374 [(set (reg:CCNO 17)
8375 (compare:CCNO
8376 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8377 (match_dup 1))
8378 (const_int 0)))]
8379 "operands[0] = gen_lowpart (SImode, operands[0]);
8380 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8381
8382 (define_split
8383 [(set (reg 17)
8384 (compare
8385 (and (match_operand 0 "nonimmediate_operand" "")
8386 (match_operand 1 "const_int_operand" ""))
8387 (const_int 0)))]
8388 "reload_completed
8389 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8390 && ((ix86_match_ccmode (insn, CCZmode)
8391 && !(INTVAL (operands[1]) & ~255))
8392 || (ix86_match_ccmode (insn, CCNOmode)
8393 && !(INTVAL (operands[1]) & ~127)))
8394 && GET_MODE (operands[0]) != QImode"
8395 [(set (reg:CCNO 17)
8396 (compare:CCNO
8397 (and:QI (match_dup 0)
8398 (match_dup 1))
8399 (const_int 0)))]
8400 "operands[0] = gen_lowpart (QImode, operands[0]);
8401 operands[1] = gen_lowpart (QImode, operands[1]);")
8402
8403
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers. If this is considered useful,
8406 ;; it should be done with splitters.
8407
8408 (define_expand "anddi3"
8409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412 (clobber (reg:CC 17))]
8413 "TARGET_64BIT"
8414 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8415
8416 (define_insn "*anddi_1_rex64"
8417 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420 (clobber (reg:CC 17))]
8421 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8422 {
8423 switch (get_attr_type (insn))
8424 {
8425 case TYPE_IMOVX:
8426 {
8427 enum machine_mode mode;
8428
8429 if (GET_CODE (operands[2]) != CONST_INT)
8430 abort ();
8431 if (INTVAL (operands[2]) == 0xff)
8432 mode = QImode;
8433 else if (INTVAL (operands[2]) == 0xffff)
8434 mode = HImode;
8435 else
8436 abort ();
8437
8438 operands[1] = gen_lowpart (mode, operands[1]);
8439 if (mode == QImode)
8440 return "movz{bq|x}\t{%1,%0|%0, %1}";
8441 else
8442 return "movz{wq|x}\t{%1,%0|%0, %1}";
8443 }
8444
8445 default:
8446 if (! rtx_equal_p (operands[0], operands[1]))
8447 abort ();
8448 if (get_attr_mode (insn) == MODE_SI)
8449 return "and{l}\t{%k2, %k0|%k0, %k2}";
8450 else
8451 return "and{q}\t{%2, %0|%0, %2}";
8452 }
8453 }
8454 [(set_attr "type" "alu,alu,alu,imovx")
8455 (set_attr "length_immediate" "*,*,*,0")
8456 (set_attr "mode" "SI,DI,DI,DI")])
8457
8458 (define_insn "*anddi_2"
8459 [(set (reg 17)
8460 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8461 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8462 (const_int 0)))
8463 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8464 (and:DI (match_dup 1) (match_dup 2)))]
8465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8466 && ix86_binary_operator_ok (AND, DImode, operands)"
8467 "@
8468 and{l}\t{%k2, %k0|%k0, %k2}
8469 and{q}\t{%2, %0|%0, %2}
8470 and{q}\t{%2, %0|%0, %2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "mode" "SI,DI,DI")])
8473
8474 (define_expand "andsi3"
8475 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8476 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8477 (match_operand:SI 2 "general_operand" "")))
8478 (clobber (reg:CC 17))]
8479 ""
8480 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8481
8482 (define_insn "*andsi_1"
8483 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8484 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8485 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8486 (clobber (reg:CC 17))]
8487 "ix86_binary_operator_ok (AND, SImode, operands)"
8488 {
8489 switch (get_attr_type (insn))
8490 {
8491 case TYPE_IMOVX:
8492 {
8493 enum machine_mode mode;
8494
8495 if (GET_CODE (operands[2]) != CONST_INT)
8496 abort ();
8497 if (INTVAL (operands[2]) == 0xff)
8498 mode = QImode;
8499 else if (INTVAL (operands[2]) == 0xffff)
8500 mode = HImode;
8501 else
8502 abort ();
8503
8504 operands[1] = gen_lowpart (mode, operands[1]);
8505 if (mode == QImode)
8506 return "movz{bl|x}\t{%1,%0|%0, %1}";
8507 else
8508 return "movz{wl|x}\t{%1,%0|%0, %1}";
8509 }
8510
8511 default:
8512 if (! rtx_equal_p (operands[0], operands[1]))
8513 abort ();
8514 return "and{l}\t{%2, %0|%0, %2}";
8515 }
8516 }
8517 [(set_attr "type" "alu,alu,imovx")
8518 (set_attr "length_immediate" "*,*,0")
8519 (set_attr "mode" "SI")])
8520
8521 (define_split
8522 [(set (match_operand 0 "register_operand" "")
8523 (and (match_dup 0)
8524 (const_int -65536)))
8525 (clobber (reg:CC 17))]
8526 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8527 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8528 "operands[1] = gen_lowpart (HImode, operands[0]);")
8529
8530 (define_split
8531 [(set (match_operand 0 "ext_register_operand" "")
8532 (and (match_dup 0)
8533 (const_int -256)))
8534 (clobber (reg:CC 17))]
8535 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8536 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8537 "operands[1] = gen_lowpart (QImode, operands[0]);")
8538
8539 (define_split
8540 [(set (match_operand 0 "ext_register_operand" "")
8541 (and (match_dup 0)
8542 (const_int -65281)))
8543 (clobber (reg:CC 17))]
8544 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8545 [(parallel [(set (zero_extract:SI (match_dup 0)
8546 (const_int 8)
8547 (const_int 8))
8548 (xor:SI
8549 (zero_extract:SI (match_dup 0)
8550 (const_int 8)
8551 (const_int 8))
8552 (zero_extract:SI (match_dup 0)
8553 (const_int 8)
8554 (const_int 8))))
8555 (clobber (reg:CC 17))])]
8556 "operands[0] = gen_lowpart (SImode, operands[0]);")
8557
8558 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8559 (define_insn "*andsi_1_zext"
8560 [(set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI
8562 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8563 (match_operand:SI 2 "general_operand" "rim"))))
8564 (clobber (reg:CC 17))]
8565 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8566 "and{l}\t{%2, %k0|%k0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "mode" "SI")])
8569
8570 (define_insn "*andsi_2"
8571 [(set (reg 17)
8572 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573 (match_operand:SI 2 "general_operand" "rim,ri"))
8574 (const_int 0)))
8575 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8576 (and:SI (match_dup 1) (match_dup 2)))]
8577 "ix86_match_ccmode (insn, CCNOmode)
8578 && ix86_binary_operator_ok (AND, SImode, operands)"
8579 "and{l}\t{%2, %0|%0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "SI")])
8582
8583 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8584 (define_insn "*andsi_2_zext"
8585 [(set (reg 17)
8586 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8587 (match_operand:SI 2 "general_operand" "rim"))
8588 (const_int 0)))
8589 (set (match_operand:DI 0 "register_operand" "=r")
8590 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8591 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8592 && ix86_binary_operator_ok (AND, SImode, operands)"
8593 "and{l}\t{%2, %k0|%k0, %2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "mode" "SI")])
8596
8597 (define_expand "andhi3"
8598 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8599 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8600 (match_operand:HI 2 "general_operand" "")))
8601 (clobber (reg:CC 17))]
8602 "TARGET_HIMODE_MATH"
8603 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8604
8605 (define_insn "*andhi_1"
8606 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8607 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8608 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8609 (clobber (reg:CC 17))]
8610 "ix86_binary_operator_ok (AND, HImode, operands)"
8611 {
8612 switch (get_attr_type (insn))
8613 {
8614 case TYPE_IMOVX:
8615 if (GET_CODE (operands[2]) != CONST_INT)
8616 abort ();
8617 if (INTVAL (operands[2]) == 0xff)
8618 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8619 abort ();
8620
8621 default:
8622 if (! rtx_equal_p (operands[0], operands[1]))
8623 abort ();
8624
8625 return "and{w}\t{%2, %0|%0, %2}";
8626 }
8627 }
8628 [(set_attr "type" "alu,alu,imovx")
8629 (set_attr "length_immediate" "*,*,0")
8630 (set_attr "mode" "HI,HI,SI")])
8631
8632 (define_insn "*andhi_2"
8633 [(set (reg 17)
8634 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:HI 2 "general_operand" "rim,ri"))
8636 (const_int 0)))
8637 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638 (and:HI (match_dup 1) (match_dup 2)))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (AND, HImode, operands)"
8641 "and{w}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "HI")])
8644
8645 (define_expand "andqi3"
8646 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8647 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8648 (match_operand:QI 2 "general_operand" "")))
8649 (clobber (reg:CC 17))]
8650 "TARGET_QIMODE_MATH"
8651 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8652
8653 ;; %%% Potential partial reg stall on alternative 2. What to do?
8654 (define_insn "*andqi_1"
8655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8656 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8657 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8658 (clobber (reg:CC 17))]
8659 "ix86_binary_operator_ok (AND, QImode, operands)"
8660 "@
8661 and{b}\t{%2, %0|%0, %2}
8662 and{b}\t{%2, %0|%0, %2}
8663 and{l}\t{%k2, %k0|%k0, %k2}"
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "QI,QI,SI")])
8666
8667 (define_insn "*andqi_1_slp"
8668 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8669 (and:QI (match_dup 0)
8670 (match_operand:QI 1 "general_operand" "qi,qmi")))
8671 (clobber (reg:CC 17))]
8672 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8674 "and{b}\t{%1, %0|%0, %1}"
8675 [(set_attr "type" "alu1")
8676 (set_attr "mode" "QI")])
8677
8678 (define_insn "*andqi_2"
8679 [(set (reg 17)
8680 (compare (and:QI
8681 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8682 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8683 (const_int 0)))
8684 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8685 (and:QI (match_dup 1) (match_dup 2)))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (AND, QImode, operands)"
8688 {
8689 if (which_alternative == 2)
8690 {
8691 if (GET_CODE (operands[2]) == CONST_INT
8692 && (INTVAL (operands[2]) & 0xffffff00))
8693 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8694 return "and{l}\t{%2, %k0|%k0, %2}";
8695 }
8696 return "and{b}\t{%2, %0|%0, %2}";
8697 }
8698 [(set_attr "type" "alu")
8699 (set_attr "mode" "QI,QI,SI")])
8700
8701 (define_insn "*andqi_2_slp"
8702 [(set (reg 17)
8703 (compare (and:QI
8704 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8705 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8706 (const_int 0)))
8707 (set (strict_low_part (match_dup 0))
8708 (and:QI (match_dup 0) (match_dup 1)))]
8709 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8710 && ix86_match_ccmode (insn, CCNOmode)
8711 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8712 "and{b}\t{%1, %0|%0, %1}"
8713 [(set_attr "type" "alu1")
8714 (set_attr "mode" "QI")])
8715
8716 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8717 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8718 ;; for a QImode operand, which of course failed.
8719
8720 (define_insn "andqi_ext_0"
8721 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8722 (const_int 8)
8723 (const_int 8))
8724 (and:SI
8725 (zero_extract:SI
8726 (match_operand 1 "ext_register_operand" "0")
8727 (const_int 8)
8728 (const_int 8))
8729 (match_operand 2 "const_int_operand" "n")))
8730 (clobber (reg:CC 17))]
8731 ""
8732 "and{b}\t{%2, %h0|%h0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "length_immediate" "1")
8735 (set_attr "mode" "QI")])
8736
8737 ;; Generated by peephole translating test to and. This shows up
8738 ;; often in fp comparisons.
8739
8740 (define_insn "*andqi_ext_0_cc"
8741 [(set (reg 17)
8742 (compare
8743 (and:SI
8744 (zero_extract:SI
8745 (match_operand 1 "ext_register_operand" "0")
8746 (const_int 8)
8747 (const_int 8))
8748 (match_operand 2 "const_int_operand" "n"))
8749 (const_int 0)))
8750 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8751 (const_int 8)
8752 (const_int 8))
8753 (and:SI
8754 (zero_extract:SI
8755 (match_dup 1)
8756 (const_int 8)
8757 (const_int 8))
8758 (match_dup 2)))]
8759 "ix86_match_ccmode (insn, CCNOmode)"
8760 "and{b}\t{%2, %h0|%h0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "1")
8763 (set_attr "mode" "QI")])
8764
8765 (define_insn "*andqi_ext_1"
8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767 (const_int 8)
8768 (const_int 8))
8769 (and:SI
8770 (zero_extract:SI
8771 (match_operand 1 "ext_register_operand" "0")
8772 (const_int 8)
8773 (const_int 8))
8774 (zero_extend:SI
8775 (match_operand:QI 2 "general_operand" "Qm"))))
8776 (clobber (reg:CC 17))]
8777 "!TARGET_64BIT"
8778 "and{b}\t{%2, %h0|%h0, %2}"
8779 [(set_attr "type" "alu")
8780 (set_attr "length_immediate" "0")
8781 (set_attr "mode" "QI")])
8782
8783 (define_insn "*andqi_ext_1_rex64"
8784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (const_int 8)
8786 (const_int 8))
8787 (and:SI
8788 (zero_extract:SI
8789 (match_operand 1 "ext_register_operand" "0")
8790 (const_int 8)
8791 (const_int 8))
8792 (zero_extend:SI
8793 (match_operand 2 "ext_register_operand" "Q"))))
8794 (clobber (reg:CC 17))]
8795 "TARGET_64BIT"
8796 "and{b}\t{%2, %h0|%h0, %2}"
8797 [(set_attr "type" "alu")
8798 (set_attr "length_immediate" "0")
8799 (set_attr "mode" "QI")])
8800
8801 (define_insn "*andqi_ext_2"
8802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803 (const_int 8)
8804 (const_int 8))
8805 (and:SI
8806 (zero_extract:SI
8807 (match_operand 1 "ext_register_operand" "%0")
8808 (const_int 8)
8809 (const_int 8))
8810 (zero_extract:SI
8811 (match_operand 2 "ext_register_operand" "Q")
8812 (const_int 8)
8813 (const_int 8))))
8814 (clobber (reg:CC 17))]
8815 ""
8816 "and{b}\t{%h2, %h0|%h0, %h2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "length_immediate" "0")
8819 (set_attr "mode" "QI")])
8820
8821 ;; Convert wide AND instructions with immediate operand to shorter QImode
8822 ;; equivalents when possible.
8823 ;; Don't do the splitting with memory operands, since it introduces risk
8824 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8825 ;; for size, but that can (should?) be handled by generic code instead.
8826 (define_split
8827 [(set (match_operand 0 "register_operand" "")
8828 (and (match_operand 1 "register_operand" "")
8829 (match_operand 2 "const_int_operand" "")))
8830 (clobber (reg:CC 17))]
8831 "reload_completed
8832 && QI_REG_P (operands[0])
8833 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8834 && !(~INTVAL (operands[2]) & ~(255 << 8))
8835 && GET_MODE (operands[0]) != QImode"
8836 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8837 (and:SI (zero_extract:SI (match_dup 1)
8838 (const_int 8) (const_int 8))
8839 (match_dup 2)))
8840 (clobber (reg:CC 17))])]
8841 "operands[0] = gen_lowpart (SImode, operands[0]);
8842 operands[1] = gen_lowpart (SImode, operands[1]);
8843 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8844
8845 ;; Since AND can be encoded with sign extended immediate, this is only
8846 ;; profitable when 7th bit is not set.
8847 (define_split
8848 [(set (match_operand 0 "register_operand" "")
8849 (and (match_operand 1 "general_operand" "")
8850 (match_operand 2 "const_int_operand" "")))
8851 (clobber (reg:CC 17))]
8852 "reload_completed
8853 && ANY_QI_REG_P (operands[0])
8854 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8855 && !(~INTVAL (operands[2]) & ~255)
8856 && !(INTVAL (operands[2]) & 128)
8857 && GET_MODE (operands[0]) != QImode"
8858 [(parallel [(set (strict_low_part (match_dup 0))
8859 (and:QI (match_dup 1)
8860 (match_dup 2)))
8861 (clobber (reg:CC 17))])]
8862 "operands[0] = gen_lowpart (QImode, operands[0]);
8863 operands[1] = gen_lowpart (QImode, operands[1]);
8864 operands[2] = gen_lowpart (QImode, operands[2]);")
8865 \f
8866 ;; Logical inclusive OR instructions
8867
8868 ;; %%% This used to optimize known byte-wide and operations to memory.
8869 ;; If this is considered useful, it should be done with splitters.
8870
8871 (define_expand "iordi3"
8872 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8873 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8874 (match_operand:DI 2 "x86_64_general_operand" "")))
8875 (clobber (reg:CC 17))]
8876 "TARGET_64BIT"
8877 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8878
8879 (define_insn "*iordi_1_rex64"
8880 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8881 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8882 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8883 (clobber (reg:CC 17))]
8884 "TARGET_64BIT
8885 && ix86_binary_operator_ok (IOR, DImode, operands)"
8886 "or{q}\t{%2, %0|%0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "DI")])
8889
8890 (define_insn "*iordi_2_rex64"
8891 [(set (reg 17)
8892 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8894 (const_int 0)))
8895 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8896 (ior:DI (match_dup 1) (match_dup 2)))]
8897 "TARGET_64BIT
8898 && ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_binary_operator_ok (IOR, DImode, operands)"
8900 "or{q}\t{%2, %0|%0, %2}"
8901 [(set_attr "type" "alu")
8902 (set_attr "mode" "DI")])
8903
8904 (define_insn "*iordi_3_rex64"
8905 [(set (reg 17)
8906 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8907 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8908 (const_int 0)))
8909 (clobber (match_scratch:DI 0 "=r"))]
8910 "TARGET_64BIT
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (IOR, DImode, operands)"
8913 "or{q}\t{%2, %0|%0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "mode" "DI")])
8916
8917
8918 (define_expand "iorsi3"
8919 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8920 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8921 (match_operand:SI 2 "general_operand" "")))
8922 (clobber (reg:CC 17))]
8923 ""
8924 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8925
8926 (define_insn "*iorsi_1"
8927 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8928 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8929 (match_operand:SI 2 "general_operand" "ri,rmi")))
8930 (clobber (reg:CC 17))]
8931 "ix86_binary_operator_ok (IOR, SImode, operands)"
8932 "or{l}\t{%2, %0|%0, %2}"
8933 [(set_attr "type" "alu")
8934 (set_attr "mode" "SI")])
8935
8936 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8937 (define_insn "*iorsi_1_zext"
8938 [(set (match_operand:DI 0 "register_operand" "=rm")
8939 (zero_extend:DI
8940 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8941 (match_operand:SI 2 "general_operand" "rim"))))
8942 (clobber (reg:CC 17))]
8943 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8944 "or{l}\t{%2, %k0|%k0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "mode" "SI")])
8947
8948 (define_insn "*iorsi_1_zext_imm"
8949 [(set (match_operand:DI 0 "register_operand" "=rm")
8950 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8951 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8952 (clobber (reg:CC 17))]
8953 "TARGET_64BIT"
8954 "or{l}\t{%2, %k0|%k0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "SI")])
8957
8958 (define_insn "*iorsi_2"
8959 [(set (reg 17)
8960 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8961 (match_operand:SI 2 "general_operand" "rim,ri"))
8962 (const_int 0)))
8963 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8964 (ior:SI (match_dup 1) (match_dup 2)))]
8965 "ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (IOR, SImode, operands)"
8967 "or{l}\t{%2, %0|%0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "SI")])
8970
8971 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8972 ;; ??? Special case for immediate operand is missing - it is tricky.
8973 (define_insn "*iorsi_2_zext"
8974 [(set (reg 17)
8975 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8976 (match_operand:SI 2 "general_operand" "rim"))
8977 (const_int 0)))
8978 (set (match_operand:DI 0 "register_operand" "=r")
8979 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8980 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (IOR, SImode, operands)"
8982 "or{l}\t{%2, %k0|%k0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8985
8986 (define_insn "*iorsi_2_zext_imm"
8987 [(set (reg 17)
8988 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8990 (const_int 0)))
8991 (set (match_operand:DI 0 "register_operand" "=r")
8992 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994 && ix86_binary_operator_ok (IOR, SImode, operands)"
8995 "or{l}\t{%2, %k0|%k0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "mode" "SI")])
8998
8999 (define_insn "*iorsi_3"
9000 [(set (reg 17)
9001 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002 (match_operand:SI 2 "general_operand" "rim"))
9003 (const_int 0)))
9004 (clobber (match_scratch:SI 0 "=r"))]
9005 "ix86_match_ccmode (insn, CCNOmode)
9006 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9007 "or{l}\t{%2, %0|%0, %2}"
9008 [(set_attr "type" "alu")
9009 (set_attr "mode" "SI")])
9010
9011 (define_expand "iorhi3"
9012 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9013 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9014 (match_operand:HI 2 "general_operand" "")))
9015 (clobber (reg:CC 17))]
9016 "TARGET_HIMODE_MATH"
9017 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9018
9019 (define_insn "*iorhi_1"
9020 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9021 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9022 (match_operand:HI 2 "general_operand" "rmi,ri")))
9023 (clobber (reg:CC 17))]
9024 "ix86_binary_operator_ok (IOR, HImode, operands)"
9025 "or{w}\t{%2, %0|%0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "HI")])
9028
9029 (define_insn "*iorhi_2"
9030 [(set (reg 17)
9031 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:HI 2 "general_operand" "rim,ri"))
9033 (const_int 0)))
9034 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9035 (ior:HI (match_dup 1) (match_dup 2)))]
9036 "ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_binary_operator_ok (IOR, HImode, operands)"
9038 "or{w}\t{%2, %0|%0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "HI")])
9041
9042 (define_insn "*iorhi_3"
9043 [(set (reg 17)
9044 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9045 (match_operand:HI 2 "general_operand" "rim"))
9046 (const_int 0)))
9047 (clobber (match_scratch:HI 0 "=r"))]
9048 "ix86_match_ccmode (insn, CCNOmode)
9049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9050 "or{w}\t{%2, %0|%0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "HI")])
9053
9054 (define_expand "iorqi3"
9055 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9056 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9057 (match_operand:QI 2 "general_operand" "")))
9058 (clobber (reg:CC 17))]
9059 "TARGET_QIMODE_MATH"
9060 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9061
9062 ;; %%% Potential partial reg stall on alternative 2. What to do?
9063 (define_insn "*iorqi_1"
9064 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9065 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9066 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9067 (clobber (reg:CC 17))]
9068 "ix86_binary_operator_ok (IOR, QImode, operands)"
9069 "@
9070 or{b}\t{%2, %0|%0, %2}
9071 or{b}\t{%2, %0|%0, %2}
9072 or{l}\t{%k2, %k0|%k0, %k2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "QI,QI,SI")])
9075
9076 (define_insn "*iorqi_1_slp"
9077 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9078 (ior:QI (match_dup 0)
9079 (match_operand:QI 1 "general_operand" "qmi,qi")))
9080 (clobber (reg:CC 17))]
9081 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9082 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9083 "or{b}\t{%1, %0|%0, %1}"
9084 [(set_attr "type" "alu1")
9085 (set_attr "mode" "QI")])
9086
9087 (define_insn "*iorqi_2"
9088 [(set (reg 17)
9089 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9090 (match_operand:QI 2 "general_operand" "qim,qi"))
9091 (const_int 0)))
9092 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9093 (ior:QI (match_dup 1) (match_dup 2)))]
9094 "ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (IOR, QImode, operands)"
9096 "or{b}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "QI")])
9099
9100 (define_insn "*iorqi_2_slp"
9101 [(set (reg 17)
9102 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9103 (match_operand:QI 1 "general_operand" "qim,qi"))
9104 (const_int 0)))
9105 (set (strict_low_part (match_dup 0))
9106 (ior:QI (match_dup 0) (match_dup 1)))]
9107 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9108 && ix86_match_ccmode (insn, CCNOmode)
9109 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9110 "or{b}\t{%1, %0|%0, %1}"
9111 [(set_attr "type" "alu1")
9112 (set_attr "mode" "QI")])
9113
9114 (define_insn "*iorqi_3"
9115 [(set (reg 17)
9116 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9117 (match_operand:QI 2 "general_operand" "qim"))
9118 (const_int 0)))
9119 (clobber (match_scratch:QI 0 "=q"))]
9120 "ix86_match_ccmode (insn, CCNOmode)
9121 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9122 "or{b}\t{%2, %0|%0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "mode" "QI")])
9125
9126 (define_insn "iorqi_ext_0"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (const_int 8)
9129 (const_int 8))
9130 (ior:SI
9131 (zero_extract:SI
9132 (match_operand 1 "ext_register_operand" "0")
9133 (const_int 8)
9134 (const_int 8))
9135 (match_operand 2 "const_int_operand" "n")))
9136 (clobber (reg:CC 17))]
9137 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9138 "or{b}\t{%2, %h0|%h0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "length_immediate" "1")
9141 (set_attr "mode" "QI")])
9142
9143 (define_insn "*iorqi_ext_1"
9144 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (const_int 8)
9146 (const_int 8))
9147 (ior:SI
9148 (zero_extract:SI
9149 (match_operand 1 "ext_register_operand" "0")
9150 (const_int 8)
9151 (const_int 8))
9152 (zero_extend:SI
9153 (match_operand:QI 2 "general_operand" "Qm"))))
9154 (clobber (reg:CC 17))]
9155 "!TARGET_64BIT
9156 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9157 "or{b}\t{%2, %h0|%h0, %2}"
9158 [(set_attr "type" "alu")
9159 (set_attr "length_immediate" "0")
9160 (set_attr "mode" "QI")])
9161
9162 (define_insn "*iorqi_ext_1_rex64"
9163 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9164 (const_int 8)
9165 (const_int 8))
9166 (ior:SI
9167 (zero_extract:SI
9168 (match_operand 1 "ext_register_operand" "0")
9169 (const_int 8)
9170 (const_int 8))
9171 (zero_extend:SI
9172 (match_operand 2 "ext_register_operand" "Q"))))
9173 (clobber (reg:CC 17))]
9174 "TARGET_64BIT
9175 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176 "or{b}\t{%2, %h0|%h0, %2}"
9177 [(set_attr "type" "alu")
9178 (set_attr "length_immediate" "0")
9179 (set_attr "mode" "QI")])
9180
9181 (define_insn "*iorqi_ext_2"
9182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9183 (const_int 8)
9184 (const_int 8))
9185 (ior:SI
9186 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9187 (const_int 8)
9188 (const_int 8))
9189 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9190 (const_int 8)
9191 (const_int 8))))
9192 (clobber (reg:CC 17))]
9193 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9194 "ior{b}\t{%h2, %h0|%h0, %h2}"
9195 [(set_attr "type" "alu")
9196 (set_attr "length_immediate" "0")
9197 (set_attr "mode" "QI")])
9198
9199 (define_split
9200 [(set (match_operand 0 "register_operand" "")
9201 (ior (match_operand 1 "register_operand" "")
9202 (match_operand 2 "const_int_operand" "")))
9203 (clobber (reg:CC 17))]
9204 "reload_completed
9205 && QI_REG_P (operands[0])
9206 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9207 && !(INTVAL (operands[2]) & ~(255 << 8))
9208 && GET_MODE (operands[0]) != QImode"
9209 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9210 (ior:SI (zero_extract:SI (match_dup 1)
9211 (const_int 8) (const_int 8))
9212 (match_dup 2)))
9213 (clobber (reg:CC 17))])]
9214 "operands[0] = gen_lowpart (SImode, operands[0]);
9215 operands[1] = gen_lowpart (SImode, operands[1]);
9216 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9217
9218 ;; Since OR can be encoded with sign extended immediate, this is only
9219 ;; profitable when 7th bit is set.
9220 (define_split
9221 [(set (match_operand 0 "register_operand" "")
9222 (ior (match_operand 1 "general_operand" "")
9223 (match_operand 2 "const_int_operand" "")))
9224 (clobber (reg:CC 17))]
9225 "reload_completed
9226 && ANY_QI_REG_P (operands[0])
9227 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9228 && !(INTVAL (operands[2]) & ~255)
9229 && (INTVAL (operands[2]) & 128)
9230 && GET_MODE (operands[0]) != QImode"
9231 [(parallel [(set (strict_low_part (match_dup 0))
9232 (ior:QI (match_dup 1)
9233 (match_dup 2)))
9234 (clobber (reg:CC 17))])]
9235 "operands[0] = gen_lowpart (QImode, operands[0]);
9236 operands[1] = gen_lowpart (QImode, operands[1]);
9237 operands[2] = gen_lowpart (QImode, operands[2]);")
9238 \f
9239 ;; Logical XOR instructions
9240
9241 ;; %%% This used to optimize known byte-wide and operations to memory.
9242 ;; If this is considered useful, it should be done with splitters.
9243
9244 (define_expand "xordi3"
9245 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9246 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9247 (match_operand:DI 2 "x86_64_general_operand" "")))
9248 (clobber (reg:CC 17))]
9249 "TARGET_64BIT"
9250 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9251
9252 (define_insn "*xordi_1_rex64"
9253 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9254 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9255 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9256 (clobber (reg:CC 17))]
9257 "TARGET_64BIT
9258 && ix86_binary_operator_ok (XOR, DImode, operands)"
9259 "@
9260 xor{q}\t{%2, %0|%0, %2}
9261 xor{q}\t{%2, %0|%0, %2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "mode" "DI,DI")])
9264
9265 (define_insn "*xordi_2_rex64"
9266 [(set (reg 17)
9267 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9269 (const_int 0)))
9270 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9271 (xor:DI (match_dup 1) (match_dup 2)))]
9272 "TARGET_64BIT
9273 && ix86_match_ccmode (insn, CCNOmode)
9274 && ix86_binary_operator_ok (XOR, DImode, operands)"
9275 "@
9276 xor{q}\t{%2, %0|%0, %2}
9277 xor{q}\t{%2, %0|%0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "mode" "DI,DI")])
9280
9281 (define_insn "*xordi_3_rex64"
9282 [(set (reg 17)
9283 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9284 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9285 (const_int 0)))
9286 (clobber (match_scratch:DI 0 "=r"))]
9287 "TARGET_64BIT
9288 && ix86_match_ccmode (insn, CCNOmode)
9289 && ix86_binary_operator_ok (XOR, DImode, operands)"
9290 "xor{q}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "DI")])
9293
9294 (define_expand "xorsi3"
9295 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9296 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9297 (match_operand:SI 2 "general_operand" "")))
9298 (clobber (reg:CC 17))]
9299 ""
9300 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9301
9302 (define_insn "*xorsi_1"
9303 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9304 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9305 (match_operand:SI 2 "general_operand" "ri,rm")))
9306 (clobber (reg:CC 17))]
9307 "ix86_binary_operator_ok (XOR, SImode, operands)"
9308 "xor{l}\t{%2, %0|%0, %2}"
9309 [(set_attr "type" "alu")
9310 (set_attr "mode" "SI")])
9311
9312 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9313 ;; Add speccase for immediates
9314 (define_insn "*xorsi_1_zext"
9315 [(set (match_operand:DI 0 "register_operand" "=r")
9316 (zero_extend:DI
9317 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9318 (match_operand:SI 2 "general_operand" "rim"))))
9319 (clobber (reg:CC 17))]
9320 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9321 "xor{l}\t{%2, %k0|%k0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9324
9325 (define_insn "*xorsi_1_zext_imm"
9326 [(set (match_operand:DI 0 "register_operand" "=r")
9327 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9328 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9329 (clobber (reg:CC 17))]
9330 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331 "xor{l}\t{%2, %k0|%k0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9334
9335 (define_insn "*xorsi_2"
9336 [(set (reg 17)
9337 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9338 (match_operand:SI 2 "general_operand" "rim,ri"))
9339 (const_int 0)))
9340 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9341 (xor:SI (match_dup 1) (match_dup 2)))]
9342 "ix86_match_ccmode (insn, CCNOmode)
9343 && ix86_binary_operator_ok (XOR, SImode, operands)"
9344 "xor{l}\t{%2, %0|%0, %2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "SI")])
9347
9348 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9349 ;; ??? Special case for immediate operand is missing - it is tricky.
9350 (define_insn "*xorsi_2_zext"
9351 [(set (reg 17)
9352 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9353 (match_operand:SI 2 "general_operand" "rim"))
9354 (const_int 0)))
9355 (set (match_operand:DI 0 "register_operand" "=r")
9356 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9357 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9358 && ix86_binary_operator_ok (XOR, SImode, operands)"
9359 "xor{l}\t{%2, %k0|%k0, %2}"
9360 [(set_attr "type" "alu")
9361 (set_attr "mode" "SI")])
9362
9363 (define_insn "*xorsi_2_zext_imm"
9364 [(set (reg 17)
9365 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9366 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9367 (const_int 0)))
9368 (set (match_operand:DI 0 "register_operand" "=r")
9369 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9371 && ix86_binary_operator_ok (XOR, SImode, operands)"
9372 "xor{l}\t{%2, %k0|%k0, %2}"
9373 [(set_attr "type" "alu")
9374 (set_attr "mode" "SI")])
9375
9376 (define_insn "*xorsi_3"
9377 [(set (reg 17)
9378 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9379 (match_operand:SI 2 "general_operand" "rim"))
9380 (const_int 0)))
9381 (clobber (match_scratch:SI 0 "=r"))]
9382 "ix86_match_ccmode (insn, CCNOmode)
9383 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9384 "xor{l}\t{%2, %0|%0, %2}"
9385 [(set_attr "type" "alu")
9386 (set_attr "mode" "SI")])
9387
9388 (define_expand "xorhi3"
9389 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9390 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9391 (match_operand:HI 2 "general_operand" "")))
9392 (clobber (reg:CC 17))]
9393 "TARGET_HIMODE_MATH"
9394 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9395
9396 (define_insn "*xorhi_1"
9397 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9398 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9399 (match_operand:HI 2 "general_operand" "rmi,ri")))
9400 (clobber (reg:CC 17))]
9401 "ix86_binary_operator_ok (XOR, HImode, operands)"
9402 "xor{w}\t{%2, %0|%0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "mode" "HI")])
9405
9406 (define_insn "*xorhi_2"
9407 [(set (reg 17)
9408 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409 (match_operand:HI 2 "general_operand" "rim,ri"))
9410 (const_int 0)))
9411 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9412 (xor:HI (match_dup 1) (match_dup 2)))]
9413 "ix86_match_ccmode (insn, CCNOmode)
9414 && ix86_binary_operator_ok (XOR, HImode, operands)"
9415 "xor{w}\t{%2, %0|%0, %2}"
9416 [(set_attr "type" "alu")
9417 (set_attr "mode" "HI")])
9418
9419 (define_insn "*xorhi_3"
9420 [(set (reg 17)
9421 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9422 (match_operand:HI 2 "general_operand" "rim"))
9423 (const_int 0)))
9424 (clobber (match_scratch:HI 0 "=r"))]
9425 "ix86_match_ccmode (insn, CCNOmode)
9426 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9427 "xor{w}\t{%2, %0|%0, %2}"
9428 [(set_attr "type" "alu")
9429 (set_attr "mode" "HI")])
9430
9431 (define_expand "xorqi3"
9432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9433 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9434 (match_operand:QI 2 "general_operand" "")))
9435 (clobber (reg:CC 17))]
9436 "TARGET_QIMODE_MATH"
9437 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9438
9439 ;; %%% Potential partial reg stall on alternative 2. What to do?
9440 (define_insn "*xorqi_1"
9441 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9442 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9443 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9444 (clobber (reg:CC 17))]
9445 "ix86_binary_operator_ok (XOR, QImode, operands)"
9446 "@
9447 xor{b}\t{%2, %0|%0, %2}
9448 xor{b}\t{%2, %0|%0, %2}
9449 xor{l}\t{%k2, %k0|%k0, %k2}"
9450 [(set_attr "type" "alu")
9451 (set_attr "mode" "QI,QI,SI")])
9452
9453 (define_insn "*xorqi_1_slp"
9454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9455 (xor:QI (match_dup 0)
9456 (match_operand:QI 1 "general_operand" "qi,qmi")))
9457 (clobber (reg:CC 17))]
9458 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9459 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9460 "xor{b}\t{%1, %0|%0, %1}"
9461 [(set_attr "type" "alu1")
9462 (set_attr "mode" "QI")])
9463
9464 (define_insn "xorqi_ext_0"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466 (const_int 8)
9467 (const_int 8))
9468 (xor:SI
9469 (zero_extract:SI
9470 (match_operand 1 "ext_register_operand" "0")
9471 (const_int 8)
9472 (const_int 8))
9473 (match_operand 2 "const_int_operand" "n")))
9474 (clobber (reg:CC 17))]
9475 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9476 "xor{b}\t{%2, %h0|%h0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "length_immediate" "1")
9479 (set_attr "mode" "QI")])
9480
9481 (define_insn "*xorqi_ext_1"
9482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (const_int 8)
9484 (const_int 8))
9485 (xor:SI
9486 (zero_extract:SI
9487 (match_operand 1 "ext_register_operand" "0")
9488 (const_int 8)
9489 (const_int 8))
9490 (zero_extend:SI
9491 (match_operand:QI 2 "general_operand" "Qm"))))
9492 (clobber (reg:CC 17))]
9493 "!TARGET_64BIT
9494 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9495 "xor{b}\t{%2, %h0|%h0, %2}"
9496 [(set_attr "type" "alu")
9497 (set_attr "length_immediate" "0")
9498 (set_attr "mode" "QI")])
9499
9500 (define_insn "*xorqi_ext_1_rex64"
9501 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9502 (const_int 8)
9503 (const_int 8))
9504 (xor:SI
9505 (zero_extract:SI
9506 (match_operand 1 "ext_register_operand" "0")
9507 (const_int 8)
9508 (const_int 8))
9509 (zero_extend:SI
9510 (match_operand 2 "ext_register_operand" "Q"))))
9511 (clobber (reg:CC 17))]
9512 "TARGET_64BIT
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9514 "xor{b}\t{%2, %h0|%h0, %2}"
9515 [(set_attr "type" "alu")
9516 (set_attr "length_immediate" "0")
9517 (set_attr "mode" "QI")])
9518
9519 (define_insn "*xorqi_ext_2"
9520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9521 (const_int 8)
9522 (const_int 8))
9523 (xor:SI
9524 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9525 (const_int 8)
9526 (const_int 8))
9527 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9528 (const_int 8)
9529 (const_int 8))))
9530 (clobber (reg:CC 17))]
9531 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9532 "xor{b}\t{%h2, %h0|%h0, %h2}"
9533 [(set_attr "type" "alu")
9534 (set_attr "length_immediate" "0")
9535 (set_attr "mode" "QI")])
9536
9537 (define_insn "*xorqi_cc_1"
9538 [(set (reg 17)
9539 (compare
9540 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9541 (match_operand:QI 2 "general_operand" "qim,qi"))
9542 (const_int 0)))
9543 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9544 (xor:QI (match_dup 1) (match_dup 2)))]
9545 "ix86_match_ccmode (insn, CCNOmode)
9546 && ix86_binary_operator_ok (XOR, QImode, operands)"
9547 "xor{b}\t{%2, %0|%0, %2}"
9548 [(set_attr "type" "alu")
9549 (set_attr "mode" "QI")])
9550
9551 (define_insn "*xorqi_2_slp"
9552 [(set (reg 17)
9553 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9554 (match_operand:QI 1 "general_operand" "qim,qi"))
9555 (const_int 0)))
9556 (set (strict_low_part (match_dup 0))
9557 (xor:QI (match_dup 0) (match_dup 1)))]
9558 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9559 && ix86_match_ccmode (insn, CCNOmode)
9560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9561 "xor{b}\t{%1, %0|%0, %1}"
9562 [(set_attr "type" "alu1")
9563 (set_attr "mode" "QI")])
9564
9565 (define_insn "*xorqi_cc_2"
9566 [(set (reg 17)
9567 (compare
9568 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9569 (match_operand:QI 2 "general_operand" "qim"))
9570 (const_int 0)))
9571 (clobber (match_scratch:QI 0 "=q"))]
9572 "ix86_match_ccmode (insn, CCNOmode)
9573 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9574 "xor{b}\t{%2, %0|%0, %2}"
9575 [(set_attr "type" "alu")
9576 (set_attr "mode" "QI")])
9577
9578 (define_insn "*xorqi_cc_ext_1"
9579 [(set (reg 17)
9580 (compare
9581 (xor:SI
9582 (zero_extract:SI
9583 (match_operand 1 "ext_register_operand" "0")
9584 (const_int 8)
9585 (const_int 8))
9586 (match_operand:QI 2 "general_operand" "qmn"))
9587 (const_int 0)))
9588 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9589 (const_int 8)
9590 (const_int 8))
9591 (xor:SI
9592 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9593 (match_dup 2)))]
9594 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9595 "xor{b}\t{%2, %h0|%h0, %2}"
9596 [(set_attr "type" "alu")
9597 (set_attr "mode" "QI")])
9598
9599 (define_insn "*xorqi_cc_ext_1_rex64"
9600 [(set (reg 17)
9601 (compare
9602 (xor:SI
9603 (zero_extract:SI
9604 (match_operand 1 "ext_register_operand" "0")
9605 (const_int 8)
9606 (const_int 8))
9607 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9608 (const_int 0)))
9609 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9610 (const_int 8)
9611 (const_int 8))
9612 (xor:SI
9613 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9614 (match_dup 2)))]
9615 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9616 "xor{b}\t{%2, %h0|%h0, %2}"
9617 [(set_attr "type" "alu")
9618 (set_attr "mode" "QI")])
9619
9620 (define_expand "xorqi_cc_ext_1"
9621 [(parallel [
9622 (set (reg:CCNO 17)
9623 (compare:CCNO
9624 (xor:SI
9625 (zero_extract:SI
9626 (match_operand 1 "ext_register_operand" "")
9627 (const_int 8)
9628 (const_int 8))
9629 (match_operand:QI 2 "general_operand" ""))
9630 (const_int 0)))
9631 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9632 (const_int 8)
9633 (const_int 8))
9634 (xor:SI
9635 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9636 (match_dup 2)))])]
9637 ""
9638 "")
9639
9640 (define_split
9641 [(set (match_operand 0 "register_operand" "")
9642 (xor (match_operand 1 "register_operand" "")
9643 (match_operand 2 "const_int_operand" "")))
9644 (clobber (reg:CC 17))]
9645 "reload_completed
9646 && QI_REG_P (operands[0])
9647 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9648 && !(INTVAL (operands[2]) & ~(255 << 8))
9649 && GET_MODE (operands[0]) != QImode"
9650 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9651 (xor:SI (zero_extract:SI (match_dup 1)
9652 (const_int 8) (const_int 8))
9653 (match_dup 2)))
9654 (clobber (reg:CC 17))])]
9655 "operands[0] = gen_lowpart (SImode, operands[0]);
9656 operands[1] = gen_lowpart (SImode, operands[1]);
9657 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9658
9659 ;; Since XOR can be encoded with sign extended immediate, this is only
9660 ;; profitable when 7th bit is set.
9661 (define_split
9662 [(set (match_operand 0 "register_operand" "")
9663 (xor (match_operand 1 "general_operand" "")
9664 (match_operand 2 "const_int_operand" "")))
9665 (clobber (reg:CC 17))]
9666 "reload_completed
9667 && ANY_QI_REG_P (operands[0])
9668 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9669 && !(INTVAL (operands[2]) & ~255)
9670 && (INTVAL (operands[2]) & 128)
9671 && GET_MODE (operands[0]) != QImode"
9672 [(parallel [(set (strict_low_part (match_dup 0))
9673 (xor:QI (match_dup 1)
9674 (match_dup 2)))
9675 (clobber (reg:CC 17))])]
9676 "operands[0] = gen_lowpart (QImode, operands[0]);
9677 operands[1] = gen_lowpart (QImode, operands[1]);
9678 operands[2] = gen_lowpart (QImode, operands[2]);")
9679 \f
9680 ;; Negation instructions
9681
9682 (define_expand "negdi2"
9683 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9684 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9685 (clobber (reg:CC 17))])]
9686 ""
9687 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9688
9689 (define_insn "*negdi2_1"
9690 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9691 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9692 (clobber (reg:CC 17))]
9693 "!TARGET_64BIT
9694 && ix86_unary_operator_ok (NEG, DImode, operands)"
9695 "#")
9696
9697 (define_split
9698 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9699 (neg:DI (match_operand:DI 1 "general_operand" "")))
9700 (clobber (reg:CC 17))]
9701 "!TARGET_64BIT && reload_completed"
9702 [(parallel
9703 [(set (reg:CCZ 17)
9704 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9705 (set (match_dup 0) (neg:SI (match_dup 2)))])
9706 (parallel
9707 [(set (match_dup 1)
9708 (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9709 (match_dup 3))
9710 (const_int 0)))
9711 (clobber (reg:CC 17))])
9712 (parallel
9713 [(set (match_dup 1)
9714 (neg:SI (match_dup 1)))
9715 (clobber (reg:CC 17))])]
9716 "split_di (operands+1, 1, operands+2, operands+3);
9717 split_di (operands+0, 1, operands+0, operands+1);")
9718
9719 (define_insn "*negdi2_1_rex64"
9720 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9721 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9722 (clobber (reg:CC 17))]
9723 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9724 "neg{q}\t%0"
9725 [(set_attr "type" "negnot")
9726 (set_attr "mode" "DI")])
9727
9728 ;; The problem with neg is that it does not perform (compare x 0),
9729 ;; it really performs (compare 0 x), which leaves us with the zero
9730 ;; flag being the only useful item.
9731
9732 (define_insn "*negdi2_cmpz_rex64"
9733 [(set (reg:CCZ 17)
9734 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9735 (const_int 0)))
9736 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9737 (neg:DI (match_dup 1)))]
9738 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9739 "neg{q}\t%0"
9740 [(set_attr "type" "negnot")
9741 (set_attr "mode" "DI")])
9742
9743
9744 (define_expand "negsi2"
9745 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9746 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9747 (clobber (reg:CC 17))])]
9748 ""
9749 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9750
9751 (define_insn "*negsi2_1"
9752 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9753 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9754 (clobber (reg:CC 17))]
9755 "ix86_unary_operator_ok (NEG, SImode, operands)"
9756 "neg{l}\t%0"
9757 [(set_attr "type" "negnot")
9758 (set_attr "mode" "SI")])
9759
9760 ;; Combine is quite creative about this pattern.
9761 (define_insn "*negsi2_1_zext"
9762 [(set (match_operand:DI 0 "register_operand" "=r")
9763 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9764 (const_int 32)))
9765 (const_int 32)))
9766 (clobber (reg:CC 17))]
9767 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9768 "neg{l}\t%k0"
9769 [(set_attr "type" "negnot")
9770 (set_attr "mode" "SI")])
9771
9772 ;; The problem with neg is that it does not perform (compare x 0),
9773 ;; it really performs (compare 0 x), which leaves us with the zero
9774 ;; flag being the only useful item.
9775
9776 (define_insn "*negsi2_cmpz"
9777 [(set (reg:CCZ 17)
9778 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9779 (const_int 0)))
9780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9781 (neg:SI (match_dup 1)))]
9782 "ix86_unary_operator_ok (NEG, SImode, operands)"
9783 "neg{l}\t%0"
9784 [(set_attr "type" "negnot")
9785 (set_attr "mode" "SI")])
9786
9787 (define_insn "*negsi2_cmpz_zext"
9788 [(set (reg:CCZ 17)
9789 (compare:CCZ (lshiftrt:DI
9790 (neg:DI (ashift:DI
9791 (match_operand:DI 1 "register_operand" "0")
9792 (const_int 32)))
9793 (const_int 32))
9794 (const_int 0)))
9795 (set (match_operand:DI 0 "register_operand" "=r")
9796 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9797 (const_int 32)))
9798 (const_int 32)))]
9799 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9800 "neg{l}\t%k0"
9801 [(set_attr "type" "negnot")
9802 (set_attr "mode" "SI")])
9803
9804 (define_expand "neghi2"
9805 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9806 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9807 (clobber (reg:CC 17))])]
9808 "TARGET_HIMODE_MATH"
9809 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9810
9811 (define_insn "*neghi2_1"
9812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9813 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9814 (clobber (reg:CC 17))]
9815 "ix86_unary_operator_ok (NEG, HImode, operands)"
9816 "neg{w}\t%0"
9817 [(set_attr "type" "negnot")
9818 (set_attr "mode" "HI")])
9819
9820 (define_insn "*neghi2_cmpz"
9821 [(set (reg:CCZ 17)
9822 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9823 (const_int 0)))
9824 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9825 (neg:HI (match_dup 1)))]
9826 "ix86_unary_operator_ok (NEG, HImode, operands)"
9827 "neg{w}\t%0"
9828 [(set_attr "type" "negnot")
9829 (set_attr "mode" "HI")])
9830
9831 (define_expand "negqi2"
9832 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9833 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9834 (clobber (reg:CC 17))])]
9835 "TARGET_QIMODE_MATH"
9836 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9837
9838 (define_insn "*negqi2_1"
9839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9840 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9841 (clobber (reg:CC 17))]
9842 "ix86_unary_operator_ok (NEG, QImode, operands)"
9843 "neg{b}\t%0"
9844 [(set_attr "type" "negnot")
9845 (set_attr "mode" "QI")])
9846
9847 (define_insn "*negqi2_cmpz"
9848 [(set (reg:CCZ 17)
9849 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9850 (const_int 0)))
9851 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9852 (neg:QI (match_dup 1)))]
9853 "ix86_unary_operator_ok (NEG, QImode, operands)"
9854 "neg{b}\t%0"
9855 [(set_attr "type" "negnot")
9856 (set_attr "mode" "QI")])
9857
9858 ;; Changing of sign for FP values is doable using integer unit too.
9859
9860 (define_expand "negsf2"
9861 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9862 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9863 (clobber (reg:CC 17))])]
9864 "TARGET_80387"
9865 "if (TARGET_SSE)
9866 {
9867 /* In case operand is in memory, we will not use SSE. */
9868 if (memory_operand (operands[0], VOIDmode)
9869 && rtx_equal_p (operands[0], operands[1]))
9870 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9871 else
9872 {
9873 /* Using SSE is tricky, since we need bitwise negation of -0
9874 in register. */
9875 rtx reg = gen_reg_rtx (SFmode);
9876 rtx dest = operands[0];
9877 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9878
9879 operands[1] = force_reg (SFmode, operands[1]);
9880 operands[0] = force_reg (SFmode, operands[0]);
9881 reg = force_reg (V4SFmode,
9882 gen_rtx_CONST_VECTOR (V4SFmode,
9883 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9884 CONST0_RTX (SFmode),
9885 CONST0_RTX (SFmode))));
9886 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9887 if (dest != operands[0])
9888 emit_move_insn (dest, operands[0]);
9889 }
9890 DONE;
9891 }
9892 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9893
9894 (define_insn "negsf2_memory"
9895 [(set (match_operand:SF 0 "memory_operand" "=m")
9896 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9897 (clobber (reg:CC 17))]
9898 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9899 "#")
9900
9901 (define_insn "negsf2_ifs"
9902 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9903 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9904 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9905 (clobber (reg:CC 17))]
9906 "TARGET_SSE
9907 && (reload_in_progress || reload_completed
9908 || (register_operand (operands[0], VOIDmode)
9909 && register_operand (operands[1], VOIDmode)))"
9910 "#")
9911
9912 (define_split
9913 [(set (match_operand:SF 0 "memory_operand" "")
9914 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9915 (use (match_operand:SF 2 "" ""))
9916 (clobber (reg:CC 17))]
9917 ""
9918 [(parallel [(set (match_dup 0)
9919 (neg:SF (match_dup 1)))
9920 (clobber (reg:CC 17))])])
9921
9922 (define_split
9923 [(set (match_operand:SF 0 "register_operand" "")
9924 (neg:SF (match_operand:SF 1 "register_operand" "")))
9925 (use (match_operand:V4SF 2 "" ""))
9926 (clobber (reg:CC 17))]
9927 "reload_completed && !SSE_REG_P (operands[0])"
9928 [(parallel [(set (match_dup 0)
9929 (neg:SF (match_dup 1)))
9930 (clobber (reg:CC 17))])])
9931
9932 (define_split
9933 [(set (match_operand:SF 0 "register_operand" "")
9934 (neg:SF (match_operand:SF 1 "register_operand" "")))
9935 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9936 (clobber (reg:CC 17))]
9937 "reload_completed && SSE_REG_P (operands[0])"
9938 [(set (subreg:TI (match_dup 0) 0)
9939 (xor:TI (match_dup 1)
9940 (match_dup 2)))]
9941 {
9942 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9943 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9944 if (operands_match_p (operands[0], operands[2]))
9945 {
9946 rtx tmp;
9947 tmp = operands[1];
9948 operands[1] = operands[2];
9949 operands[2] = tmp;
9950 }
9951 })
9952
9953
9954 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9955 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9956 ;; to itself.
9957 (define_insn "*negsf2_if"
9958 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9959 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9960 (clobber (reg:CC 17))]
9961 "TARGET_80387 && !TARGET_SSE
9962 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9963 "#")
9964
9965 (define_split
9966 [(set (match_operand:SF 0 "fp_register_operand" "")
9967 (neg:SF (match_operand:SF 1 "register_operand" "")))
9968 (clobber (reg:CC 17))]
9969 "TARGET_80387 && reload_completed"
9970 [(set (match_dup 0)
9971 (neg:SF (match_dup 1)))]
9972 "")
9973
9974 (define_split
9975 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9976 (neg:SF (match_operand:SF 1 "register_operand" "")))
9977 (clobber (reg:CC 17))]
9978 "TARGET_80387 && reload_completed"
9979 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9980 (clobber (reg:CC 17))])]
9981 "operands[1] = gen_int_mode (0x80000000, SImode);
9982 operands[0] = gen_lowpart (SImode, operands[0]);")
9983
9984 (define_split
9985 [(set (match_operand 0 "memory_operand" "")
9986 (neg (match_operand 1 "memory_operand" "")))
9987 (clobber (reg:CC 17))]
9988 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9989 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9990 (clobber (reg:CC 17))])]
9991 {
9992 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9993
9994 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
9995 if (size >= 12)
9996 size = 10;
9997 operands[0] = adjust_address (operands[0], QImode, size - 1);
9998 operands[1] = gen_int_mode (0x80, QImode);
9999 })
10000
10001 (define_expand "negdf2"
10002 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10003 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10004 (clobber (reg:CC 17))])]
10005 "TARGET_80387"
10006 "if (TARGET_SSE2)
10007 {
10008 /* In case operand is in memory, we will not use SSE. */
10009 if (memory_operand (operands[0], VOIDmode)
10010 && rtx_equal_p (operands[0], operands[1]))
10011 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
10012 else
10013 {
10014 /* Using SSE is tricky, since we need bitwise negation of -0
10015 in register. */
10016 rtx reg;
10017 #if HOST_BITS_PER_WIDE_INT >= 64
10018 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10019 #else
10020 rtx imm = immed_double_const (0, 0x80000000, DImode);
10021 #endif
10022 rtx dest = operands[0];
10023
10024 operands[1] = force_reg (DFmode, operands[1]);
10025 operands[0] = force_reg (DFmode, operands[0]);
10026 imm = gen_lowpart (DFmode, imm);
10027 reg = force_reg (V2DFmode,
10028 gen_rtx_CONST_VECTOR (V2DFmode,
10029 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10030 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10031 if (dest != operands[0])
10032 emit_move_insn (dest, operands[0]);
10033 }
10034 DONE;
10035 }
10036 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10037
10038 (define_insn "negdf2_memory"
10039 [(set (match_operand:DF 0 "memory_operand" "=m")
10040 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10041 (clobber (reg:CC 17))]
10042 "ix86_unary_operator_ok (NEG, DFmode, operands)"
10043 "#")
10044
10045 (define_insn "negdf2_ifs"
10046 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10047 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10048 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10049 (clobber (reg:CC 17))]
10050 "!TARGET_64BIT && TARGET_SSE2
10051 && (reload_in_progress || reload_completed
10052 || (register_operand (operands[0], VOIDmode)
10053 && register_operand (operands[1], VOIDmode)))"
10054 "#")
10055
10056 (define_insn "*negdf2_ifs_rex64"
10057 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10058 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10059 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10060 (clobber (reg:CC 17))]
10061 "TARGET_64BIT && TARGET_SSE2
10062 && (reload_in_progress || reload_completed
10063 || (register_operand (operands[0], VOIDmode)
10064 && register_operand (operands[1], VOIDmode)))"
10065 "#")
10066
10067 (define_split
10068 [(set (match_operand:DF 0 "memory_operand" "")
10069 (neg:DF (match_operand:DF 1 "memory_operand" "")))
10070 (use (match_operand:V2DF 2 "" ""))
10071 (clobber (reg:CC 17))]
10072 ""
10073 [(parallel [(set (match_dup 0)
10074 (neg:DF (match_dup 1)))
10075 (clobber (reg:CC 17))])])
10076
10077 (define_split
10078 [(set (match_operand:DF 0 "register_operand" "")
10079 (neg:DF (match_operand:DF 1 "register_operand" "")))
10080 (use (match_operand:V2DF 2 "" ""))
10081 (clobber (reg:CC 17))]
10082 "reload_completed && !SSE_REG_P (operands[0])
10083 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10084 [(parallel [(set (match_dup 0)
10085 (neg:DF (match_dup 1)))
10086 (clobber (reg:CC 17))])])
10087
10088 (define_split
10089 [(set (match_operand:DF 0 "register_operand" "")
10090 (neg:DF (match_operand:DF 1 "register_operand" "")))
10091 (use (match_operand:V2DF 2 "" ""))
10092 (clobber (reg:CC 17))]
10093 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10094 [(parallel [(set (match_dup 0)
10095 (xor:DI (match_dup 1) (match_dup 2)))
10096 (clobber (reg:CC 17))])]
10097 "operands[0] = gen_lowpart (DImode, operands[0]);
10098 operands[1] = gen_lowpart (DImode, operands[1]);
10099 operands[2] = gen_lowpart (DImode, operands[2]);")
10100
10101 (define_split
10102 [(set (match_operand:DF 0 "register_operand" "")
10103 (neg:DF (match_operand:DF 1 "register_operand" "")))
10104 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10105 (clobber (reg:CC 17))]
10106 "reload_completed && SSE_REG_P (operands[0])"
10107 [(set (subreg:TI (match_dup 0) 0)
10108 (xor:TI (match_dup 1)
10109 (match_dup 2)))]
10110 {
10111 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10112 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10113 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10114 /* Avoid possible reformatting on the operands. */
10115 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10116 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10117 if (operands_match_p (operands[0], operands[2]))
10118 {
10119 rtx tmp;
10120 tmp = operands[1];
10121 operands[1] = operands[2];
10122 operands[2] = tmp;
10123 }
10124 })
10125
10126 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10127 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10128 ;; to itself.
10129 (define_insn "*negdf2_if"
10130 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10131 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10132 (clobber (reg:CC 17))]
10133 "!TARGET_64BIT && TARGET_80387
10134 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10135 "#")
10136
10137 ;; FIXME: We should to allow integer registers here. Problem is that
10138 ;; we need another scratch register to get constant from.
10139 ;; Forcing constant to mem if no register available in peep2 should be
10140 ;; safe even for PIC mode, because of RIP relative addressing.
10141 (define_insn "*negdf2_if_rex64"
10142 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10143 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10144 (clobber (reg:CC 17))]
10145 "TARGET_64BIT && TARGET_80387
10146 && ix86_unary_operator_ok (NEG, DFmode, operands)"
10147 "#")
10148
10149 (define_split
10150 [(set (match_operand:DF 0 "fp_register_operand" "")
10151 (neg:DF (match_operand:DF 1 "register_operand" "")))
10152 (clobber (reg:CC 17))]
10153 "TARGET_80387 && reload_completed"
10154 [(set (match_dup 0)
10155 (neg:DF (match_dup 1)))]
10156 "")
10157
10158 (define_split
10159 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10160 (neg:DF (match_operand:DF 1 "register_operand" "")))
10161 (clobber (reg:CC 17))]
10162 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10163 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10164 (clobber (reg:CC 17))])]
10165 "operands[4] = gen_int_mode (0x80000000, SImode);
10166 split_di (operands+0, 1, operands+2, operands+3);")
10167
10168 (define_expand "negxf2"
10169 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10170 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10171 (clobber (reg:CC 17))])]
10172 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10173 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10174
10175 (define_expand "negtf2"
10176 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10177 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10178 (clobber (reg:CC 17))])]
10179 "TARGET_80387"
10180 "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10181
10182 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10183 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10184 ;; to itself.
10185 (define_insn "*negxf2_if"
10186 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10187 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10188 (clobber (reg:CC 17))]
10189 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10190 && ix86_unary_operator_ok (NEG, XFmode, operands)"
10191 "#")
10192
10193 (define_split
10194 [(set (match_operand:XF 0 "fp_register_operand" "")
10195 (neg:XF (match_operand:XF 1 "register_operand" "")))
10196 (clobber (reg:CC 17))]
10197 "TARGET_80387 && reload_completed"
10198 [(set (match_dup 0)
10199 (neg:XF (match_dup 1)))]
10200 "")
10201
10202 (define_split
10203 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10204 (neg:XF (match_operand:XF 1 "register_operand" "")))
10205 (clobber (reg:CC 17))]
10206 "TARGET_80387 && reload_completed"
10207 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10208 (clobber (reg:CC 17))])]
10209 "operands[1] = GEN_INT (0x8000);
10210 operands[0] = gen_rtx_REG (SImode,
10211 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10212
10213 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10214 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10215 ;; to itself.
10216 (define_insn "*negtf2_if"
10217 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10218 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10219 (clobber (reg:CC 17))]
10220 "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10221 "#")
10222
10223 (define_split
10224 [(set (match_operand:TF 0 "fp_register_operand" "")
10225 (neg:TF (match_operand:TF 1 "register_operand" "")))
10226 (clobber (reg:CC 17))]
10227 "TARGET_80387 && reload_completed"
10228 [(set (match_dup 0)
10229 (neg:TF (match_dup 1)))]
10230 "")
10231
10232 (define_split
10233 [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10234 (neg:TF (match_operand:TF 1 "register_operand" "")))
10235 (clobber (reg:CC 17))]
10236 "TARGET_80387 && reload_completed"
10237 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10238 (clobber (reg:CC 17))])]
10239 "operands[1] = GEN_INT (0x8000);
10240 operands[0] = gen_rtx_REG (SImode,
10241 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10242
10243 ;; Conditionalize these after reload. If they matches before reload, we
10244 ;; lose the clobber and ability to use integer instructions.
10245
10246 (define_insn "*negsf2_1"
10247 [(set (match_operand:SF 0 "register_operand" "=f")
10248 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10249 "TARGET_80387 && reload_completed"
10250 "fchs"
10251 [(set_attr "type" "fsgn")
10252 (set_attr "mode" "SF")
10253 (set_attr "ppro_uops" "few")])
10254
10255 (define_insn "*negdf2_1"
10256 [(set (match_operand:DF 0 "register_operand" "=f")
10257 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10258 "TARGET_80387 && reload_completed"
10259 "fchs"
10260 [(set_attr "type" "fsgn")
10261 (set_attr "mode" "DF")
10262 (set_attr "ppro_uops" "few")])
10263
10264 (define_insn "*negextendsfdf2"
10265 [(set (match_operand:DF 0 "register_operand" "=f")
10266 (neg:DF (float_extend:DF
10267 (match_operand:SF 1 "register_operand" "0"))))]
10268 "TARGET_80387"
10269 "fchs"
10270 [(set_attr "type" "fsgn")
10271 (set_attr "mode" "DF")
10272 (set_attr "ppro_uops" "few")])
10273
10274 (define_insn "*negxf2_1"
10275 [(set (match_operand:XF 0 "register_operand" "=f")
10276 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10277 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10278 "fchs"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "XF")
10281 (set_attr "ppro_uops" "few")])
10282
10283 (define_insn "*negextenddfxf2"
10284 [(set (match_operand:XF 0 "register_operand" "=f")
10285 (neg:XF (float_extend:XF
10286 (match_operand:DF 1 "register_operand" "0"))))]
10287 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10288 "fchs"
10289 [(set_attr "type" "fsgn")
10290 (set_attr "mode" "XF")
10291 (set_attr "ppro_uops" "few")])
10292
10293 (define_insn "*negextendsfxf2"
10294 [(set (match_operand:XF 0 "register_operand" "=f")
10295 (neg:XF (float_extend:XF
10296 (match_operand:SF 1 "register_operand" "0"))))]
10297 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10298 "fchs"
10299 [(set_attr "type" "fsgn")
10300 (set_attr "mode" "XF")
10301 (set_attr "ppro_uops" "few")])
10302
10303 (define_insn "*negtf2_1"
10304 [(set (match_operand:TF 0 "register_operand" "=f")
10305 (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10306 "TARGET_80387 && reload_completed"
10307 "fchs"
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "XF")
10310 (set_attr "ppro_uops" "few")])
10311
10312 (define_insn "*negextenddftf2"
10313 [(set (match_operand:TF 0 "register_operand" "=f")
10314 (neg:TF (float_extend:TF
10315 (match_operand:DF 1 "register_operand" "0"))))]
10316 "TARGET_80387"
10317 "fchs"
10318 [(set_attr "type" "fsgn")
10319 (set_attr "mode" "XF")
10320 (set_attr "ppro_uops" "few")])
10321
10322 (define_insn "*negextendsftf2"
10323 [(set (match_operand:TF 0 "register_operand" "=f")
10324 (neg:TF (float_extend:TF
10325 (match_operand:SF 1 "register_operand" "0"))))]
10326 "TARGET_80387"
10327 "fchs"
10328 [(set_attr "type" "fsgn")
10329 (set_attr "mode" "XF")
10330 (set_attr "ppro_uops" "few")])
10331 \f
10332 ;; Absolute value instructions
10333
10334 (define_expand "abssf2"
10335 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10336 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10337 (clobber (reg:CC 17))])]
10338 "TARGET_80387"
10339 "if (TARGET_SSE)
10340 {
10341 /* In case operand is in memory, we will not use SSE. */
10342 if (memory_operand (operands[0], VOIDmode)
10343 && rtx_equal_p (operands[0], operands[1]))
10344 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10345 else
10346 {
10347 /* Using SSE is tricky, since we need bitwise negation of -0
10348 in register. */
10349 rtx reg = gen_reg_rtx (V4SFmode);
10350 rtx dest = operands[0];
10351 rtx imm;
10352
10353 operands[1] = force_reg (SFmode, operands[1]);
10354 operands[0] = force_reg (SFmode, operands[0]);
10355 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10356 reg = force_reg (V4SFmode,
10357 gen_rtx_CONST_VECTOR (V4SFmode,
10358 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10359 CONST0_RTX (SFmode),
10360 CONST0_RTX (SFmode))));
10361 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10362 if (dest != operands[0])
10363 emit_move_insn (dest, operands[0]);
10364 }
10365 DONE;
10366 }
10367 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10368
10369 (define_insn "abssf2_memory"
10370 [(set (match_operand:SF 0 "memory_operand" "=m")
10371 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10372 (clobber (reg:CC 17))]
10373 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10374 "#")
10375
10376 (define_insn "abssf2_ifs"
10377 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10378 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10379 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10380 (clobber (reg:CC 17))]
10381 "TARGET_SSE
10382 && (reload_in_progress || reload_completed
10383 || (register_operand (operands[0], VOIDmode)
10384 && register_operand (operands[1], VOIDmode)))"
10385 "#")
10386
10387 (define_split
10388 [(set (match_operand:SF 0 "memory_operand" "")
10389 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10390 (use (match_operand:V4SF 2 "" ""))
10391 (clobber (reg:CC 17))]
10392 ""
10393 [(parallel [(set (match_dup 0)
10394 (abs:SF (match_dup 1)))
10395 (clobber (reg:CC 17))])])
10396
10397 (define_split
10398 [(set (match_operand:SF 0 "register_operand" "")
10399 (abs:SF (match_operand:SF 1 "register_operand" "")))
10400 (use (match_operand:V4SF 2 "" ""))
10401 (clobber (reg:CC 17))]
10402 "reload_completed && !SSE_REG_P (operands[0])"
10403 [(parallel [(set (match_dup 0)
10404 (abs:SF (match_dup 1)))
10405 (clobber (reg:CC 17))])])
10406
10407 (define_split
10408 [(set (match_operand:SF 0 "register_operand" "")
10409 (abs:SF (match_operand:SF 1 "register_operand" "")))
10410 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10411 (clobber (reg:CC 17))]
10412 "reload_completed && SSE_REG_P (operands[0])"
10413 [(set (subreg:TI (match_dup 0) 0)
10414 (and:TI (match_dup 1)
10415 (match_dup 2)))]
10416 {
10417 operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10418 operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10419 if (operands_match_p (operands[0], operands[2]))
10420 {
10421 rtx tmp;
10422 tmp = operands[1];
10423 operands[1] = operands[2];
10424 operands[2] = tmp;
10425 }
10426 })
10427
10428 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10429 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10430 ;; to itself.
10431 (define_insn "*abssf2_if"
10432 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10433 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10434 (clobber (reg:CC 17))]
10435 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10436 "#")
10437
10438 (define_split
10439 [(set (match_operand:SF 0 "fp_register_operand" "")
10440 (abs:SF (match_operand:SF 1 "register_operand" "")))
10441 (clobber (reg:CC 17))]
10442 "TARGET_80387 && reload_completed"
10443 [(set (match_dup 0)
10444 (abs:SF (match_dup 1)))]
10445 "")
10446
10447 (define_split
10448 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10449 (abs:SF (match_operand:SF 1 "register_operand" "")))
10450 (clobber (reg:CC 17))]
10451 "TARGET_80387 && reload_completed"
10452 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10453 (clobber (reg:CC 17))])]
10454 "operands[1] = gen_int_mode (~0x80000000, SImode);
10455 operands[0] = gen_lowpart (SImode, operands[0]);")
10456
10457 (define_split
10458 [(set (match_operand 0 "memory_operand" "")
10459 (abs (match_operand 1 "memory_operand" "")))
10460 (clobber (reg:CC 17))]
10461 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10462 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10463 (clobber (reg:CC 17))])]
10464 {
10465 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10466
10467 /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
10468 if (size >= 12)
10469 size = 10;
10470 operands[0] = adjust_address (operands[0], QImode, size - 1);
10471 operands[1] = gen_int_mode (~0x80, QImode);
10472 })
10473
10474 (define_expand "absdf2"
10475 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10476 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10477 (clobber (reg:CC 17))])]
10478 "TARGET_80387"
10479 "if (TARGET_SSE2)
10480 {
10481 /* In case operand is in memory, we will not use SSE. */
10482 if (memory_operand (operands[0], VOIDmode)
10483 && rtx_equal_p (operands[0], operands[1]))
10484 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10485 else
10486 {
10487 /* Using SSE is tricky, since we need bitwise negation of -0
10488 in register. */
10489 rtx reg = gen_reg_rtx (V2DFmode);
10490 #if HOST_BITS_PER_WIDE_INT >= 64
10491 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10492 #else
10493 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10494 #endif
10495 rtx dest = operands[0];
10496
10497 operands[1] = force_reg (DFmode, operands[1]);
10498 operands[0] = force_reg (DFmode, operands[0]);
10499
10500 /* Produce LONG_DOUBLE with the proper immediate argument. */
10501 imm = gen_lowpart (DFmode, imm);
10502 reg = force_reg (V2DFmode,
10503 gen_rtx_CONST_VECTOR (V2DFmode,
10504 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10505 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10506 if (dest != operands[0])
10507 emit_move_insn (dest, operands[0]);
10508 }
10509 DONE;
10510 }
10511 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10512
10513 (define_insn "absdf2_memory"
10514 [(set (match_operand:DF 0 "memory_operand" "=m")
10515 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10516 (clobber (reg:CC 17))]
10517 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10518 "#")
10519
10520 (define_insn "absdf2_ifs"
10521 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10522 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10523 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10524 (clobber (reg:CC 17))]
10525 "!TARGET_64BIT && TARGET_SSE2
10526 && (reload_in_progress || reload_completed
10527 || (register_operand (operands[0], VOIDmode)
10528 && register_operand (operands[1], VOIDmode)))"
10529 "#")
10530
10531 (define_insn "*absdf2_ifs_rex64"
10532 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10533 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10534 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10535 (clobber (reg:CC 17))]
10536 "TARGET_64BIT && TARGET_SSE2
10537 && (reload_in_progress || reload_completed
10538 || (register_operand (operands[0], VOIDmode)
10539 && register_operand (operands[1], VOIDmode)))"
10540 "#")
10541
10542 (define_split
10543 [(set (match_operand:DF 0 "memory_operand" "")
10544 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10545 (use (match_operand:V2DF 2 "" ""))
10546 (clobber (reg:CC 17))]
10547 ""
10548 [(parallel [(set (match_dup 0)
10549 (abs:DF (match_dup 1)))
10550 (clobber (reg:CC 17))])])
10551
10552 (define_split
10553 [(set (match_operand:DF 0 "register_operand" "")
10554 (abs:DF (match_operand:DF 1 "register_operand" "")))
10555 (use (match_operand:V2DF 2 "" ""))
10556 (clobber (reg:CC 17))]
10557 "reload_completed && !SSE_REG_P (operands[0])"
10558 [(parallel [(set (match_dup 0)
10559 (abs:DF (match_dup 1)))
10560 (clobber (reg:CC 17))])])
10561
10562 (define_split
10563 [(set (match_operand:DF 0 "register_operand" "")
10564 (abs:DF (match_operand:DF 1 "register_operand" "")))
10565 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10566 (clobber (reg:CC 17))]
10567 "reload_completed && SSE_REG_P (operands[0])"
10568 [(set (subreg:TI (match_dup 0) 0)
10569 (and:TI (match_dup 1)
10570 (match_dup 2)))]
10571 {
10572 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10573 operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10574 operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10575 /* Avoid possible reformatting on the operands. */
10576 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10577 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10578 if (operands_match_p (operands[0], operands[2]))
10579 {
10580 rtx tmp;
10581 tmp = operands[1];
10582 operands[1] = operands[2];
10583 operands[2] = tmp;
10584 }
10585 })
10586
10587
10588 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10589 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10590 ;; to itself.
10591 (define_insn "*absdf2_if"
10592 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10593 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10594 (clobber (reg:CC 17))]
10595 "!TARGET_64BIT && TARGET_80387
10596 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10597 "#")
10598
10599 ;; FIXME: We should to allow integer registers here. Problem is that
10600 ;; we need another scratch register to get constant from.
10601 ;; Forcing constant to mem if no register available in peep2 should be
10602 ;; safe even for PIC mode, because of RIP relative addressing.
10603 (define_insn "*absdf2_if_rex64"
10604 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10605 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10606 (clobber (reg:CC 17))]
10607 "TARGET_64BIT && TARGET_80387
10608 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10609 "#")
10610
10611 (define_split
10612 [(set (match_operand:DF 0 "fp_register_operand" "")
10613 (abs:DF (match_operand:DF 1 "register_operand" "")))
10614 (clobber (reg:CC 17))]
10615 "TARGET_80387 && reload_completed"
10616 [(set (match_dup 0)
10617 (abs:DF (match_dup 1)))]
10618 "")
10619
10620 (define_split
10621 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10622 (abs:DF (match_operand:DF 1 "register_operand" "")))
10623 (clobber (reg:CC 17))]
10624 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10625 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10626 (clobber (reg:CC 17))])]
10627 "operands[4] = gen_int_mode (~0x80000000, SImode);
10628 split_di (operands+0, 1, operands+2, operands+3);")
10629
10630 (define_expand "absxf2"
10631 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10632 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10633 (clobber (reg:CC 17))])]
10634 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10635 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10636
10637 (define_expand "abstf2"
10638 [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10639 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10640 (clobber (reg:CC 17))])]
10641 "TARGET_80387"
10642 "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10643
10644 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10645 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10646 ;; to itself.
10647 (define_insn "*absxf2_if"
10648 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10649 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10650 (clobber (reg:CC 17))]
10651 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10652 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10653 "#")
10654
10655 (define_split
10656 [(set (match_operand:XF 0 "fp_register_operand" "")
10657 (abs:XF (match_operand:XF 1 "register_operand" "")))
10658 (clobber (reg:CC 17))]
10659 "TARGET_80387 && reload_completed"
10660 [(set (match_dup 0)
10661 (abs:XF (match_dup 1)))]
10662 "")
10663
10664 (define_split
10665 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10666 (abs:XF (match_operand:XF 1 "register_operand" "")))
10667 (clobber (reg:CC 17))]
10668 "TARGET_80387 && reload_completed"
10669 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10670 (clobber (reg:CC 17))])]
10671 "operands[1] = GEN_INT (~0x8000);
10672 operands[0] = gen_rtx_REG (SImode,
10673 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10674
10675 (define_insn "*abstf2_if"
10676 [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10677 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10678 (clobber (reg:CC 17))]
10679 "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10680 "#")
10681
10682 (define_split
10683 [(set (match_operand:TF 0 "fp_register_operand" "")
10684 (abs:TF (match_operand:TF 1 "register_operand" "")))
10685 (clobber (reg:CC 17))]
10686 "TARGET_80387 && reload_completed"
10687 [(set (match_dup 0)
10688 (abs:TF (match_dup 1)))]
10689 "")
10690
10691 (define_split
10692 [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10693 (abs:TF (match_operand:TF 1 "register_operand" "")))
10694 (clobber (reg:CC 17))]
10695 "TARGET_80387 && reload_completed"
10696 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10697 (clobber (reg:CC 17))])]
10698 "operands[1] = GEN_INT (~0x8000);
10699 operands[0] = gen_rtx_REG (SImode,
10700 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10701
10702 (define_insn "*abssf2_1"
10703 [(set (match_operand:SF 0 "register_operand" "=f")
10704 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10705 "TARGET_80387 && reload_completed"
10706 "fabs"
10707 [(set_attr "type" "fsgn")
10708 (set_attr "mode" "SF")])
10709
10710 (define_insn "*absdf2_1"
10711 [(set (match_operand:DF 0 "register_operand" "=f")
10712 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10713 "TARGET_80387 && reload_completed"
10714 "fabs"
10715 [(set_attr "type" "fsgn")
10716 (set_attr "mode" "DF")])
10717
10718 (define_insn "*absextendsfdf2"
10719 [(set (match_operand:DF 0 "register_operand" "=f")
10720 (abs:DF (float_extend:DF
10721 (match_operand:SF 1 "register_operand" "0"))))]
10722 "TARGET_80387"
10723 "fabs"
10724 [(set_attr "type" "fsgn")
10725 (set_attr "mode" "DF")])
10726
10727 (define_insn "*absxf2_1"
10728 [(set (match_operand:XF 0 "register_operand" "=f")
10729 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10730 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10731 "fabs"
10732 [(set_attr "type" "fsgn")
10733 (set_attr "mode" "DF")])
10734
10735 (define_insn "*absextenddfxf2"
10736 [(set (match_operand:XF 0 "register_operand" "=f")
10737 (abs:XF (float_extend:XF
10738 (match_operand:DF 1 "register_operand" "0"))))]
10739 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10740 "fabs"
10741 [(set_attr "type" "fsgn")
10742 (set_attr "mode" "XF")])
10743
10744 (define_insn "*absextendsfxf2"
10745 [(set (match_operand:XF 0 "register_operand" "=f")
10746 (abs:XF (float_extend:XF
10747 (match_operand:SF 1 "register_operand" "0"))))]
10748 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10749 "fabs"
10750 [(set_attr "type" "fsgn")
10751 (set_attr "mode" "XF")])
10752
10753 (define_insn "*abstf2_1"
10754 [(set (match_operand:TF 0 "register_operand" "=f")
10755 (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10756 "TARGET_80387 && reload_completed"
10757 "fabs"
10758 [(set_attr "type" "fsgn")
10759 (set_attr "mode" "DF")])
10760
10761 (define_insn "*absextenddftf2"
10762 [(set (match_operand:TF 0 "register_operand" "=f")
10763 (abs:TF (float_extend:TF
10764 (match_operand:DF 1 "register_operand" "0"))))]
10765 "TARGET_80387"
10766 "fabs"
10767 [(set_attr "type" "fsgn")
10768 (set_attr "mode" "XF")])
10769
10770 (define_insn "*absextendsftf2"
10771 [(set (match_operand:TF 0 "register_operand" "=f")
10772 (abs:TF (float_extend:TF
10773 (match_operand:SF 1 "register_operand" "0"))))]
10774 "TARGET_80387"
10775 "fabs"
10776 [(set_attr "type" "fsgn")
10777 (set_attr "mode" "XF")])
10778 \f
10779 ;; One complement instructions
10780
10781 (define_expand "one_cmpldi2"
10782 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10783 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10784 "TARGET_64BIT"
10785 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10786
10787 (define_insn "*one_cmpldi2_1_rex64"
10788 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10789 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10790 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10791 "not{q}\t%0"
10792 [(set_attr "type" "negnot")
10793 (set_attr "mode" "DI")])
10794
10795 (define_insn "*one_cmpldi2_2_rex64"
10796 [(set (reg 17)
10797 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10798 (const_int 0)))
10799 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10800 (not:DI (match_dup 1)))]
10801 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10802 && ix86_unary_operator_ok (NOT, DImode, operands)"
10803 "#"
10804 [(set_attr "type" "alu1")
10805 (set_attr "mode" "DI")])
10806
10807 (define_split
10808 [(set (reg 17)
10809 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10810 (const_int 0)))
10811 (set (match_operand:DI 0 "nonimmediate_operand" "")
10812 (not:DI (match_dup 1)))]
10813 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10814 [(parallel [(set (reg:CCNO 17)
10815 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10816 (const_int 0)))
10817 (set (match_dup 0)
10818 (xor:DI (match_dup 1) (const_int -1)))])]
10819 "")
10820
10821 (define_expand "one_cmplsi2"
10822 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10823 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10824 ""
10825 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10826
10827 (define_insn "*one_cmplsi2_1"
10828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10829 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10830 "ix86_unary_operator_ok (NOT, SImode, operands)"
10831 "not{l}\t%0"
10832 [(set_attr "type" "negnot")
10833 (set_attr "mode" "SI")])
10834
10835 ;; ??? Currently never generated - xor is used instead.
10836 (define_insn "*one_cmplsi2_1_zext"
10837 [(set (match_operand:DI 0 "register_operand" "=r")
10838 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10839 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10840 "not{l}\t%k0"
10841 [(set_attr "type" "negnot")
10842 (set_attr "mode" "SI")])
10843
10844 (define_insn "*one_cmplsi2_2"
10845 [(set (reg 17)
10846 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10847 (const_int 0)))
10848 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10849 (not:SI (match_dup 1)))]
10850 "ix86_match_ccmode (insn, CCNOmode)
10851 && ix86_unary_operator_ok (NOT, SImode, operands)"
10852 "#"
10853 [(set_attr "type" "alu1")
10854 (set_attr "mode" "SI")])
10855
10856 (define_split
10857 [(set (reg 17)
10858 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10859 (const_int 0)))
10860 (set (match_operand:SI 0 "nonimmediate_operand" "")
10861 (not:SI (match_dup 1)))]
10862 "ix86_match_ccmode (insn, CCNOmode)"
10863 [(parallel [(set (reg:CCNO 17)
10864 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10865 (const_int 0)))
10866 (set (match_dup 0)
10867 (xor:SI (match_dup 1) (const_int -1)))])]
10868 "")
10869
10870 ;; ??? Currently never generated - xor is used instead.
10871 (define_insn "*one_cmplsi2_2_zext"
10872 [(set (reg 17)
10873 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10874 (const_int 0)))
10875 (set (match_operand:DI 0 "register_operand" "=r")
10876 (zero_extend:DI (not:SI (match_dup 1))))]
10877 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10878 && ix86_unary_operator_ok (NOT, SImode, operands)"
10879 "#"
10880 [(set_attr "type" "alu1")
10881 (set_attr "mode" "SI")])
10882
10883 (define_split
10884 [(set (reg 17)
10885 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10886 (const_int 0)))
10887 (set (match_operand:DI 0 "register_operand" "")
10888 (zero_extend:DI (not:SI (match_dup 1))))]
10889 "ix86_match_ccmode (insn, CCNOmode)"
10890 [(parallel [(set (reg:CCNO 17)
10891 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10892 (const_int 0)))
10893 (set (match_dup 0)
10894 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10895 "")
10896
10897 (define_expand "one_cmplhi2"
10898 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10899 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10900 "TARGET_HIMODE_MATH"
10901 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10902
10903 (define_insn "*one_cmplhi2_1"
10904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10905 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10906 "ix86_unary_operator_ok (NOT, HImode, operands)"
10907 "not{w}\t%0"
10908 [(set_attr "type" "negnot")
10909 (set_attr "mode" "HI")])
10910
10911 (define_insn "*one_cmplhi2_2"
10912 [(set (reg 17)
10913 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10914 (const_int 0)))
10915 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10916 (not:HI (match_dup 1)))]
10917 "ix86_match_ccmode (insn, CCNOmode)
10918 && ix86_unary_operator_ok (NEG, HImode, operands)"
10919 "#"
10920 [(set_attr "type" "alu1")
10921 (set_attr "mode" "HI")])
10922
10923 (define_split
10924 [(set (reg 17)
10925 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10926 (const_int 0)))
10927 (set (match_operand:HI 0 "nonimmediate_operand" "")
10928 (not:HI (match_dup 1)))]
10929 "ix86_match_ccmode (insn, CCNOmode)"
10930 [(parallel [(set (reg:CCNO 17)
10931 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10932 (const_int 0)))
10933 (set (match_dup 0)
10934 (xor:HI (match_dup 1) (const_int -1)))])]
10935 "")
10936
10937 ;; %%% Potential partial reg stall on alternative 1. What to do?
10938 (define_expand "one_cmplqi2"
10939 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10940 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10941 "TARGET_QIMODE_MATH"
10942 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10943
10944 (define_insn "*one_cmplqi2_1"
10945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10946 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10947 "ix86_unary_operator_ok (NOT, QImode, operands)"
10948 "@
10949 not{b}\t%0
10950 not{l}\t%k0"
10951 [(set_attr "type" "negnot")
10952 (set_attr "mode" "QI,SI")])
10953
10954 (define_insn "*one_cmplqi2_2"
10955 [(set (reg 17)
10956 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10957 (const_int 0)))
10958 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10959 (not:QI (match_dup 1)))]
10960 "ix86_match_ccmode (insn, CCNOmode)
10961 && ix86_unary_operator_ok (NOT, QImode, operands)"
10962 "#"
10963 [(set_attr "type" "alu1")
10964 (set_attr "mode" "QI")])
10965
10966 (define_split
10967 [(set (reg 17)
10968 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10969 (const_int 0)))
10970 (set (match_operand:QI 0 "nonimmediate_operand" "")
10971 (not:QI (match_dup 1)))]
10972 "ix86_match_ccmode (insn, CCNOmode)"
10973 [(parallel [(set (reg:CCNO 17)
10974 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10975 (const_int 0)))
10976 (set (match_dup 0)
10977 (xor:QI (match_dup 1) (const_int -1)))])]
10978 "")
10979 \f
10980 ;; Arithmetic shift instructions
10981
10982 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10983 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10984 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10985 ;; from the assembler input.
10986 ;;
10987 ;; This instruction shifts the target reg/mem as usual, but instead of
10988 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10989 ;; is a left shift double, bits are taken from the high order bits of
10990 ;; reg, else if the insn is a shift right double, bits are taken from the
10991 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10992 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10993 ;;
10994 ;; Since sh[lr]d does not change the `reg' operand, that is done
10995 ;; separately, making all shifts emit pairs of shift double and normal
10996 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10997 ;; support a 63 bit shift, each shift where the count is in a reg expands
10998 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10999 ;;
11000 ;; If the shift count is a constant, we need never emit more than one
11001 ;; shift pair, instead using moves and sign extension for counts greater
11002 ;; than 31.
11003
11004 (define_expand "ashldi3"
11005 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11006 (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
11007 (match_operand:QI 2 "nonmemory_operand" "")))
11008 (clobber (reg:CC 17))])]
11009 ""
11010 {
11011 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11012 {
11013 emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11014 DONE;
11015 }
11016 ix86_expand_binary_operator (ASHIFT, DImode, operands);
11017 DONE;
11018 })
11019
11020 (define_insn "*ashldi3_1_rex64"
11021 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11022 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11023 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11024 (clobber (reg:CC 17))]
11025 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11026 {
11027 switch (get_attr_type (insn))
11028 {
11029 case TYPE_ALU:
11030 if (operands[2] != const1_rtx)
11031 abort ();
11032 if (!rtx_equal_p (operands[0], operands[1]))
11033 abort ();
11034 return "add{q}\t{%0, %0|%0, %0}";
11035
11036 case TYPE_LEA:
11037 if (GET_CODE (operands[2]) != CONST_INT
11038 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11039 abort ();
11040 operands[1] = gen_rtx_MULT (DImode, operands[1],
11041 GEN_INT (1 << INTVAL (operands[2])));
11042 return "lea{q}\t{%a1, %0|%0, %a1}";
11043
11044 default:
11045 if (REG_P (operands[2]))
11046 return "sal{q}\t{%b2, %0|%0, %b2}";
11047 else if (GET_CODE (operands[2]) == CONST_INT
11048 && INTVAL (operands[2]) == 1
11049 && (TARGET_SHIFT1 || optimize_size))
11050 return "sal{q}\t%0";
11051 else
11052 return "sal{q}\t{%2, %0|%0, %2}";
11053 }
11054 }
11055 [(set (attr "type")
11056 (cond [(eq_attr "alternative" "1")
11057 (const_string "lea")
11058 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059 (const_int 0))
11060 (match_operand 0 "register_operand" ""))
11061 (match_operand 2 "const1_operand" ""))
11062 (const_string "alu")
11063 ]
11064 (const_string "ishift")))
11065 (set_attr "mode" "DI")])
11066
11067 ;; Convert lea to the lea pattern to avoid flags dependency.
11068 (define_split
11069 [(set (match_operand:DI 0 "register_operand" "")
11070 (ashift:DI (match_operand:DI 1 "register_operand" "")
11071 (match_operand:QI 2 "immediate_operand" "")))
11072 (clobber (reg:CC 17))]
11073 "TARGET_64BIT && reload_completed
11074 && true_regnum (operands[0]) != true_regnum (operands[1])"
11075 [(set (match_dup 0)
11076 (mult:DI (match_dup 1)
11077 (match_dup 2)))]
11078 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11079
11080 ;; This pattern can't accept a variable shift count, since shifts by
11081 ;; zero don't affect the flags. We assume that shifts by constant
11082 ;; zero are optimized away.
11083 (define_insn "*ashldi3_cmp_rex64"
11084 [(set (reg 17)
11085 (compare
11086 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11087 (match_operand:QI 2 "immediate_operand" "e"))
11088 (const_int 0)))
11089 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11090 (ashift:DI (match_dup 1) (match_dup 2)))]
11091 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11092 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11093 {
11094 switch (get_attr_type (insn))
11095 {
11096 case TYPE_ALU:
11097 if (operands[2] != const1_rtx)
11098 abort ();
11099 return "add{q}\t{%0, %0|%0, %0}";
11100
11101 default:
11102 if (REG_P (operands[2]))
11103 return "sal{q}\t{%b2, %0|%0, %b2}";
11104 else if (GET_CODE (operands[2]) == CONST_INT
11105 && INTVAL (operands[2]) == 1
11106 && (TARGET_SHIFT1 || optimize_size))
11107 return "sal{q}\t%0";
11108 else
11109 return "sal{q}\t{%2, %0|%0, %2}";
11110 }
11111 }
11112 [(set (attr "type")
11113 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11114 (const_int 0))
11115 (match_operand 0 "register_operand" ""))
11116 (match_operand 2 "const1_operand" ""))
11117 (const_string "alu")
11118 ]
11119 (const_string "ishift")))
11120 (set_attr "mode" "DI")])
11121
11122 (define_insn "ashldi3_1"
11123 [(set (match_operand:DI 0 "register_operand" "=r")
11124 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11125 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11126 (clobber (match_scratch:SI 3 "=&r"))
11127 (clobber (reg:CC 17))]
11128 "!TARGET_64BIT && TARGET_CMOVE"
11129 "#"
11130 [(set_attr "type" "multi")])
11131
11132 (define_insn "*ashldi3_2"
11133 [(set (match_operand:DI 0 "register_operand" "=r")
11134 (ashift:DI (match_operand:DI 1 "register_operand" "0")
11135 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11136 (clobber (reg:CC 17))]
11137 "!TARGET_64BIT"
11138 "#"
11139 [(set_attr "type" "multi")])
11140
11141 (define_split
11142 [(set (match_operand:DI 0 "register_operand" "")
11143 (ashift:DI (match_operand:DI 1 "register_operand" "")
11144 (match_operand:QI 2 "nonmemory_operand" "")))
11145 (clobber (match_scratch:SI 3 ""))
11146 (clobber (reg:CC 17))]
11147 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11148 [(const_int 0)]
11149 "ix86_split_ashldi (operands, operands[3]); DONE;")
11150
11151 (define_split
11152 [(set (match_operand:DI 0 "register_operand" "")
11153 (ashift:DI (match_operand:DI 1 "register_operand" "")
11154 (match_operand:QI 2 "nonmemory_operand" "")))
11155 (clobber (reg:CC 17))]
11156 "!TARGET_64BIT && reload_completed"
11157 [(const_int 0)]
11158 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11159
11160 (define_insn "x86_shld_1"
11161 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11162 (ior:SI (ashift:SI (match_dup 0)
11163 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11164 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11165 (minus:QI (const_int 32) (match_dup 2)))))
11166 (clobber (reg:CC 17))]
11167 ""
11168 "@
11169 shld{l}\t{%2, %1, %0|%0, %1, %2}
11170 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11171 [(set_attr "type" "ishift")
11172 (set_attr "prefix_0f" "1")
11173 (set_attr "mode" "SI")
11174 (set_attr "pent_pair" "np")
11175 (set_attr "athlon_decode" "vector")
11176 (set_attr "ppro_uops" "few")])
11177
11178 (define_expand "x86_shift_adj_1"
11179 [(set (reg:CCZ 17)
11180 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11181 (const_int 32))
11182 (const_int 0)))
11183 (set (match_operand:SI 0 "register_operand" "")
11184 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11185 (match_operand:SI 1 "register_operand" "")
11186 (match_dup 0)))
11187 (set (match_dup 1)
11188 (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11189 (match_operand:SI 3 "register_operand" "r")
11190 (match_dup 1)))]
11191 "TARGET_CMOVE"
11192 "")
11193
11194 (define_expand "x86_shift_adj_2"
11195 [(use (match_operand:SI 0 "register_operand" ""))
11196 (use (match_operand:SI 1 "register_operand" ""))
11197 (use (match_operand:QI 2 "register_operand" ""))]
11198 ""
11199 {
11200 rtx label = gen_label_rtx ();
11201 rtx tmp;
11202
11203 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11204
11205 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11206 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11207 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11208 gen_rtx_LABEL_REF (VOIDmode, label),
11209 pc_rtx);
11210 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11211 JUMP_LABEL (tmp) = label;
11212
11213 emit_move_insn (operands[0], operands[1]);
11214 emit_move_insn (operands[1], const0_rtx);
11215
11216 emit_label (label);
11217 LABEL_NUSES (label) = 1;
11218
11219 DONE;
11220 })
11221
11222 (define_expand "ashlsi3"
11223 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11224 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11225 (match_operand:QI 2 "nonmemory_operand" "")))
11226 (clobber (reg:CC 17))]
11227 ""
11228 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11229
11230 (define_insn "*ashlsi3_1"
11231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11232 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11233 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11234 (clobber (reg:CC 17))]
11235 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11236 {
11237 switch (get_attr_type (insn))
11238 {
11239 case TYPE_ALU:
11240 if (operands[2] != const1_rtx)
11241 abort ();
11242 if (!rtx_equal_p (operands[0], operands[1]))
11243 abort ();
11244 return "add{l}\t{%0, %0|%0, %0}";
11245
11246 case TYPE_LEA:
11247 return "#";
11248
11249 default:
11250 if (REG_P (operands[2]))
11251 return "sal{l}\t{%b2, %0|%0, %b2}";
11252 else if (GET_CODE (operands[2]) == CONST_INT
11253 && INTVAL (operands[2]) == 1
11254 && (TARGET_SHIFT1 || optimize_size))
11255 return "sal{l}\t%0";
11256 else
11257 return "sal{l}\t{%2, %0|%0, %2}";
11258 }
11259 }
11260 [(set (attr "type")
11261 (cond [(eq_attr "alternative" "1")
11262 (const_string "lea")
11263 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11264 (const_int 0))
11265 (match_operand 0 "register_operand" ""))
11266 (match_operand 2 "const1_operand" ""))
11267 (const_string "alu")
11268 ]
11269 (const_string "ishift")))
11270 (set_attr "mode" "SI")])
11271
11272 ;; Convert lea to the lea pattern to avoid flags dependency.
11273 (define_split
11274 [(set (match_operand 0 "register_operand" "")
11275 (ashift (match_operand 1 "index_register_operand" "")
11276 (match_operand:QI 2 "const_int_operand" "")))
11277 (clobber (reg:CC 17))]
11278 "reload_completed
11279 && true_regnum (operands[0]) != true_regnum (operands[1])"
11280 [(const_int 0)]
11281 {
11282 rtx pat;
11283 operands[0] = gen_lowpart (SImode, operands[0]);
11284 operands[1] = gen_lowpart (Pmode, operands[1]);
11285 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11286 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11287 if (Pmode != SImode)
11288 pat = gen_rtx_SUBREG (SImode, pat, 0);
11289 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11290 DONE;
11291 })
11292
11293 ;; Rare case of shifting RSP is handled by generating move and shift
11294 (define_split
11295 [(set (match_operand 0 "register_operand" "")
11296 (ashift (match_operand 1 "register_operand" "")
11297 (match_operand:QI 2 "const_int_operand" "")))
11298 (clobber (reg:CC 17))]
11299 "reload_completed
11300 && true_regnum (operands[0]) != true_regnum (operands[1])"
11301 [(const_int 0)]
11302 {
11303 rtx pat, clob;
11304 emit_move_insn (operands[1], operands[0]);
11305 pat = gen_rtx_SET (VOIDmode, operands[0],
11306 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11307 operands[0], operands[2]));
11308 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11309 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11310 DONE;
11311 })
11312
11313 (define_insn "*ashlsi3_1_zext"
11314 [(set (match_operand:DI 0 "register_operand" "=r,r")
11315 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11316 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11317 (clobber (reg:CC 17))]
11318 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11319 {
11320 switch (get_attr_type (insn))
11321 {
11322 case TYPE_ALU:
11323 if (operands[2] != const1_rtx)
11324 abort ();
11325 return "add{l}\t{%k0, %k0|%k0, %k0}";
11326
11327 case TYPE_LEA:
11328 return "#";
11329
11330 default:
11331 if (REG_P (operands[2]))
11332 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11333 else if (GET_CODE (operands[2]) == CONST_INT
11334 && INTVAL (operands[2]) == 1
11335 && (TARGET_SHIFT1 || optimize_size))
11336 return "sal{l}\t%k0";
11337 else
11338 return "sal{l}\t{%2, %k0|%k0, %2}";
11339 }
11340 }
11341 [(set (attr "type")
11342 (cond [(eq_attr "alternative" "1")
11343 (const_string "lea")
11344 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11345 (const_int 0))
11346 (match_operand 2 "const1_operand" ""))
11347 (const_string "alu")
11348 ]
11349 (const_string "ishift")))
11350 (set_attr "mode" "SI")])
11351
11352 ;; Convert lea to the lea pattern to avoid flags dependency.
11353 (define_split
11354 [(set (match_operand:DI 0 "register_operand" "")
11355 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11356 (match_operand:QI 2 "const_int_operand" ""))))
11357 (clobber (reg:CC 17))]
11358 "TARGET_64BIT && reload_completed
11359 && true_regnum (operands[0]) != true_regnum (operands[1])"
11360 [(set (match_dup 0) (zero_extend:DI
11361 (subreg:SI (mult:SI (match_dup 1)
11362 (match_dup 2)) 0)))]
11363 {
11364 operands[1] = gen_lowpart (Pmode, operands[1]);
11365 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11366 })
11367
11368 ;; This pattern can't accept a variable shift count, since shifts by
11369 ;; zero don't affect the flags. We assume that shifts by constant
11370 ;; zero are optimized away.
11371 (define_insn "*ashlsi3_cmp"
11372 [(set (reg 17)
11373 (compare
11374 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11375 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11376 (const_int 0)))
11377 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11378 (ashift:SI (match_dup 1) (match_dup 2)))]
11379 "ix86_match_ccmode (insn, CCGOCmode)
11380 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11381 {
11382 switch (get_attr_type (insn))
11383 {
11384 case TYPE_ALU:
11385 if (operands[2] != const1_rtx)
11386 abort ();
11387 return "add{l}\t{%0, %0|%0, %0}";
11388
11389 default:
11390 if (REG_P (operands[2]))
11391 return "sal{l}\t{%b2, %0|%0, %b2}";
11392 else if (GET_CODE (operands[2]) == CONST_INT
11393 && INTVAL (operands[2]) == 1
11394 && (TARGET_SHIFT1 || optimize_size))
11395 return "sal{l}\t%0";
11396 else
11397 return "sal{l}\t{%2, %0|%0, %2}";
11398 }
11399 }
11400 [(set (attr "type")
11401 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11402 (const_int 0))
11403 (match_operand 0 "register_operand" ""))
11404 (match_operand 2 "const1_operand" ""))
11405 (const_string "alu")
11406 ]
11407 (const_string "ishift")))
11408 (set_attr "mode" "SI")])
11409
11410 (define_insn "*ashlsi3_cmp_zext"
11411 [(set (reg 17)
11412 (compare
11413 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11414 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11415 (const_int 0)))
11416 (set (match_operand:DI 0 "register_operand" "=r")
11417 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11418 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11419 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11420 {
11421 switch (get_attr_type (insn))
11422 {
11423 case TYPE_ALU:
11424 if (operands[2] != const1_rtx)
11425 abort ();
11426 return "add{l}\t{%k0, %k0|%k0, %k0}";
11427
11428 default:
11429 if (REG_P (operands[2]))
11430 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11431 else if (GET_CODE (operands[2]) == CONST_INT
11432 && INTVAL (operands[2]) == 1
11433 && (TARGET_SHIFT1 || optimize_size))
11434 return "sal{l}\t%k0";
11435 else
11436 return "sal{l}\t{%2, %k0|%k0, %2}";
11437 }
11438 }
11439 [(set (attr "type")
11440 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11441 (const_int 0))
11442 (match_operand 2 "const1_operand" ""))
11443 (const_string "alu")
11444 ]
11445 (const_string "ishift")))
11446 (set_attr "mode" "SI")])
11447
11448 (define_expand "ashlhi3"
11449 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11450 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11451 (match_operand:QI 2 "nonmemory_operand" "")))
11452 (clobber (reg:CC 17))]
11453 "TARGET_HIMODE_MATH"
11454 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11455
11456 (define_insn "*ashlhi3_1_lea"
11457 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11458 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11459 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11460 (clobber (reg:CC 17))]
11461 "!TARGET_PARTIAL_REG_STALL
11462 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11463 {
11464 switch (get_attr_type (insn))
11465 {
11466 case TYPE_LEA:
11467 return "#";
11468 case TYPE_ALU:
11469 if (operands[2] != const1_rtx)
11470 abort ();
11471 return "add{w}\t{%0, %0|%0, %0}";
11472
11473 default:
11474 if (REG_P (operands[2]))
11475 return "sal{w}\t{%b2, %0|%0, %b2}";
11476 else if (GET_CODE (operands[2]) == CONST_INT
11477 && INTVAL (operands[2]) == 1
11478 && (TARGET_SHIFT1 || optimize_size))
11479 return "sal{w}\t%0";
11480 else
11481 return "sal{w}\t{%2, %0|%0, %2}";
11482 }
11483 }
11484 [(set (attr "type")
11485 (cond [(eq_attr "alternative" "1")
11486 (const_string "lea")
11487 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11488 (const_int 0))
11489 (match_operand 0 "register_operand" ""))
11490 (match_operand 2 "const1_operand" ""))
11491 (const_string "alu")
11492 ]
11493 (const_string "ishift")))
11494 (set_attr "mode" "HI,SI")])
11495
11496 (define_insn "*ashlhi3_1"
11497 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11498 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11499 (match_operand:QI 2 "nonmemory_operand" "cI")))
11500 (clobber (reg:CC 17))]
11501 "TARGET_PARTIAL_REG_STALL
11502 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11503 {
11504 switch (get_attr_type (insn))
11505 {
11506 case TYPE_ALU:
11507 if (operands[2] != const1_rtx)
11508 abort ();
11509 return "add{w}\t{%0, %0|%0, %0}";
11510
11511 default:
11512 if (REG_P (operands[2]))
11513 return "sal{w}\t{%b2, %0|%0, %b2}";
11514 else if (GET_CODE (operands[2]) == CONST_INT
11515 && INTVAL (operands[2]) == 1
11516 && (TARGET_SHIFT1 || optimize_size))
11517 return "sal{w}\t%0";
11518 else
11519 return "sal{w}\t{%2, %0|%0, %2}";
11520 }
11521 }
11522 [(set (attr "type")
11523 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11524 (const_int 0))
11525 (match_operand 0 "register_operand" ""))
11526 (match_operand 2 "const1_operand" ""))
11527 (const_string "alu")
11528 ]
11529 (const_string "ishift")))
11530 (set_attr "mode" "HI")])
11531
11532 ;; This pattern can't accept a variable shift count, since shifts by
11533 ;; zero don't affect the flags. We assume that shifts by constant
11534 ;; zero are optimized away.
11535 (define_insn "*ashlhi3_cmp"
11536 [(set (reg 17)
11537 (compare
11538 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11539 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11540 (const_int 0)))
11541 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11542 (ashift:HI (match_dup 1) (match_dup 2)))]
11543 "ix86_match_ccmode (insn, CCGOCmode)
11544 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11545 {
11546 switch (get_attr_type (insn))
11547 {
11548 case TYPE_ALU:
11549 if (operands[2] != const1_rtx)
11550 abort ();
11551 return "add{w}\t{%0, %0|%0, %0}";
11552
11553 default:
11554 if (REG_P (operands[2]))
11555 return "sal{w}\t{%b2, %0|%0, %b2}";
11556 else if (GET_CODE (operands[2]) == CONST_INT
11557 && INTVAL (operands[2]) == 1
11558 && (TARGET_SHIFT1 || optimize_size))
11559 return "sal{w}\t%0";
11560 else
11561 return "sal{w}\t{%2, %0|%0, %2}";
11562 }
11563 }
11564 [(set (attr "type")
11565 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11566 (const_int 0))
11567 (match_operand 0 "register_operand" ""))
11568 (match_operand 2 "const1_operand" ""))
11569 (const_string "alu")
11570 ]
11571 (const_string "ishift")))
11572 (set_attr "mode" "HI")])
11573
11574 (define_expand "ashlqi3"
11575 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11576 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11577 (match_operand:QI 2 "nonmemory_operand" "")))
11578 (clobber (reg:CC 17))]
11579 "TARGET_QIMODE_MATH"
11580 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11581
11582 ;; %%% Potential partial reg stall on alternative 2. What to do?
11583
11584 (define_insn "*ashlqi3_1_lea"
11585 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11586 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11587 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11588 (clobber (reg:CC 17))]
11589 "!TARGET_PARTIAL_REG_STALL
11590 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11591 {
11592 switch (get_attr_type (insn))
11593 {
11594 case TYPE_LEA:
11595 return "#";
11596 case TYPE_ALU:
11597 if (operands[2] != const1_rtx)
11598 abort ();
11599 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11600 return "add{l}\t{%k0, %k0|%k0, %k0}";
11601 else
11602 return "add{b}\t{%0, %0|%0, %0}";
11603
11604 default:
11605 if (REG_P (operands[2]))
11606 {
11607 if (get_attr_mode (insn) == MODE_SI)
11608 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11609 else
11610 return "sal{b}\t{%b2, %0|%0, %b2}";
11611 }
11612 else if (GET_CODE (operands[2]) == CONST_INT
11613 && INTVAL (operands[2]) == 1
11614 && (TARGET_SHIFT1 || optimize_size))
11615 {
11616 if (get_attr_mode (insn) == MODE_SI)
11617 return "sal{l}\t%0";
11618 else
11619 return "sal{b}\t%0";
11620 }
11621 else
11622 {
11623 if (get_attr_mode (insn) == MODE_SI)
11624 return "sal{l}\t{%2, %k0|%k0, %2}";
11625 else
11626 return "sal{b}\t{%2, %0|%0, %2}";
11627 }
11628 }
11629 }
11630 [(set (attr "type")
11631 (cond [(eq_attr "alternative" "2")
11632 (const_string "lea")
11633 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634 (const_int 0))
11635 (match_operand 0 "register_operand" ""))
11636 (match_operand 2 "const1_operand" ""))
11637 (const_string "alu")
11638 ]
11639 (const_string "ishift")))
11640 (set_attr "mode" "QI,SI,SI")])
11641
11642 (define_insn "*ashlqi3_1"
11643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11644 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11645 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11646 (clobber (reg:CC 17))]
11647 "TARGET_PARTIAL_REG_STALL
11648 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11649 {
11650 switch (get_attr_type (insn))
11651 {
11652 case TYPE_ALU:
11653 if (operands[2] != const1_rtx)
11654 abort ();
11655 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11656 return "add{l}\t{%k0, %k0|%k0, %k0}";
11657 else
11658 return "add{b}\t{%0, %0|%0, %0}";
11659
11660 default:
11661 if (REG_P (operands[2]))
11662 {
11663 if (get_attr_mode (insn) == MODE_SI)
11664 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11665 else
11666 return "sal{b}\t{%b2, %0|%0, %b2}";
11667 }
11668 else if (GET_CODE (operands[2]) == CONST_INT
11669 && INTVAL (operands[2]) == 1
11670 && (TARGET_SHIFT1 || optimize_size))
11671 {
11672 if (get_attr_mode (insn) == MODE_SI)
11673 return "sal{l}\t%0";
11674 else
11675 return "sal{b}\t%0";
11676 }
11677 else
11678 {
11679 if (get_attr_mode (insn) == MODE_SI)
11680 return "sal{l}\t{%2, %k0|%k0, %2}";
11681 else
11682 return "sal{b}\t{%2, %0|%0, %2}";
11683 }
11684 }
11685 }
11686 [(set (attr "type")
11687 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11688 (const_int 0))
11689 (match_operand 0 "register_operand" ""))
11690 (match_operand 2 "const1_operand" ""))
11691 (const_string "alu")
11692 ]
11693 (const_string "ishift")))
11694 (set_attr "mode" "QI,SI")])
11695
11696 ;; This pattern can't accept a variable shift count, since shifts by
11697 ;; zero don't affect the flags. We assume that shifts by constant
11698 ;; zero are optimized away.
11699 (define_insn "*ashlqi3_cmp"
11700 [(set (reg 17)
11701 (compare
11702 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11703 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11704 (const_int 0)))
11705 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11706 (ashift:QI (match_dup 1) (match_dup 2)))]
11707 "ix86_match_ccmode (insn, CCGOCmode)
11708 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11709 {
11710 switch (get_attr_type (insn))
11711 {
11712 case TYPE_ALU:
11713 if (operands[2] != const1_rtx)
11714 abort ();
11715 return "add{b}\t{%0, %0|%0, %0}";
11716
11717 default:
11718 if (REG_P (operands[2]))
11719 return "sal{b}\t{%b2, %0|%0, %b2}";
11720 else if (GET_CODE (operands[2]) == CONST_INT
11721 && INTVAL (operands[2]) == 1
11722 && (TARGET_SHIFT1 || optimize_size))
11723 return "sal{b}\t%0";
11724 else
11725 return "sal{b}\t{%2, %0|%0, %2}";
11726 }
11727 }
11728 [(set (attr "type")
11729 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11730 (const_int 0))
11731 (match_operand 0 "register_operand" ""))
11732 (match_operand 2 "const1_operand" ""))
11733 (const_string "alu")
11734 ]
11735 (const_string "ishift")))
11736 (set_attr "mode" "QI")])
11737
11738 ;; See comment above `ashldi3' about how this works.
11739
11740 (define_expand "ashrdi3"
11741 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11742 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11743 (match_operand:QI 2 "nonmemory_operand" "")))
11744 (clobber (reg:CC 17))])]
11745 ""
11746 {
11747 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11748 {
11749 emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11750 DONE;
11751 }
11752 ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11753 DONE;
11754 })
11755
11756 (define_insn "ashrdi3_63_rex64"
11757 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11758 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11759 (match_operand:DI 2 "const_int_operand" "i,i")))
11760 (clobber (reg:CC 17))]
11761 "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11762 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11763 "@
11764 {cqto|cqo}
11765 sar{q}\t{%2, %0|%0, %2}"
11766 [(set_attr "type" "imovx,ishift")
11767 (set_attr "prefix_0f" "0,*")
11768 (set_attr "length_immediate" "0,*")
11769 (set_attr "modrm" "0,1")
11770 (set_attr "mode" "DI")])
11771
11772 (define_insn "*ashrdi3_1_one_bit_rex64"
11773 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11774 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11775 (match_operand:QI 2 "const_int_1_operand" "")))
11776 (clobber (reg:CC 17))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11778 && (TARGET_SHIFT1 || optimize_size)"
11779 "sar{q}\t%0"
11780 [(set_attr "type" "ishift")
11781 (set (attr "length")
11782 (if_then_else (match_operand:DI 0 "register_operand" "")
11783 (const_string "2")
11784 (const_string "*")))])
11785
11786 (define_insn "*ashrdi3_1_rex64"
11787 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11788 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11789 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11790 (clobber (reg:CC 17))]
11791 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11792 "@
11793 sar{q}\t{%2, %0|%0, %2}
11794 sar{q}\t{%b2, %0|%0, %b2}"
11795 [(set_attr "type" "ishift")
11796 (set_attr "mode" "DI")])
11797
11798 ;; This pattern can't accept a variable shift count, since shifts by
11799 ;; zero don't affect the flags. We assume that shifts by constant
11800 ;; zero are optimized away.
11801 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11802 [(set (reg 17)
11803 (compare
11804 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11805 (match_operand:QI 2 "const_int_1_operand" ""))
11806 (const_int 0)))
11807 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11808 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11809 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11810 && (TARGET_SHIFT1 || optimize_size)
11811 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11812 "sar{q}\t%0"
11813 [(set_attr "type" "ishift")
11814 (set (attr "length")
11815 (if_then_else (match_operand:DI 0 "register_operand" "")
11816 (const_string "2")
11817 (const_string "*")))])
11818
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags. We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashrdi3_cmp_rex64"
11823 [(set (reg 17)
11824 (compare
11825 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11826 (match_operand:QI 2 "const_int_operand" "n"))
11827 (const_int 0)))
11828 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11829 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11830 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11831 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11832 "sar{q}\t{%2, %0|%0, %2}"
11833 [(set_attr "type" "ishift")
11834 (set_attr "mode" "DI")])
11835
11836
11837 (define_insn "ashrdi3_1"
11838 [(set (match_operand:DI 0 "register_operand" "=r")
11839 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11840 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11841 (clobber (match_scratch:SI 3 "=&r"))
11842 (clobber (reg:CC 17))]
11843 "!TARGET_64BIT && TARGET_CMOVE"
11844 "#"
11845 [(set_attr "type" "multi")])
11846
11847 (define_insn "*ashrdi3_2"
11848 [(set (match_operand:DI 0 "register_operand" "=r")
11849 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11850 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11851 (clobber (reg:CC 17))]
11852 "!TARGET_64BIT"
11853 "#"
11854 [(set_attr "type" "multi")])
11855
11856 (define_split
11857 [(set (match_operand:DI 0 "register_operand" "")
11858 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11859 (match_operand:QI 2 "nonmemory_operand" "")))
11860 (clobber (match_scratch:SI 3 ""))
11861 (clobber (reg:CC 17))]
11862 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11863 [(const_int 0)]
11864 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11865
11866 (define_split
11867 [(set (match_operand:DI 0 "register_operand" "")
11868 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11869 (match_operand:QI 2 "nonmemory_operand" "")))
11870 (clobber (reg:CC 17))]
11871 "!TARGET_64BIT && reload_completed"
11872 [(const_int 0)]
11873 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11874
11875 (define_insn "x86_shrd_1"
11876 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11877 (ior:SI (ashiftrt:SI (match_dup 0)
11878 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11879 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11880 (minus:QI (const_int 32) (match_dup 2)))))
11881 (clobber (reg:CC 17))]
11882 ""
11883 "@
11884 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11885 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11886 [(set_attr "type" "ishift")
11887 (set_attr "prefix_0f" "1")
11888 (set_attr "pent_pair" "np")
11889 (set_attr "ppro_uops" "few")
11890 (set_attr "mode" "SI")])
11891
11892 (define_expand "x86_shift_adj_3"
11893 [(use (match_operand:SI 0 "register_operand" ""))
11894 (use (match_operand:SI 1 "register_operand" ""))
11895 (use (match_operand:QI 2 "register_operand" ""))]
11896 ""
11897 {
11898 rtx label = gen_label_rtx ();
11899 rtx tmp;
11900
11901 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11902
11903 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11904 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11905 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11906 gen_rtx_LABEL_REF (VOIDmode, label),
11907 pc_rtx);
11908 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11909 JUMP_LABEL (tmp) = label;
11910
11911 emit_move_insn (operands[0], operands[1]);
11912 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11913
11914 emit_label (label);
11915 LABEL_NUSES (label) = 1;
11916
11917 DONE;
11918 })
11919
11920 (define_insn "ashrsi3_31"
11921 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11922 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11923 (match_operand:SI 2 "const_int_operand" "i,i")))
11924 (clobber (reg:CC 17))]
11925 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11926 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11927 "@
11928 {cltd|cdq}
11929 sar{l}\t{%2, %0|%0, %2}"
11930 [(set_attr "type" "imovx,ishift")
11931 (set_attr "prefix_0f" "0,*")
11932 (set_attr "length_immediate" "0,*")
11933 (set_attr "modrm" "0,1")
11934 (set_attr "mode" "SI")])
11935
11936 (define_insn "*ashrsi3_31_zext"
11937 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11938 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11939 (match_operand:SI 2 "const_int_operand" "i,i"))))
11940 (clobber (reg:CC 17))]
11941 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11942 && INTVAL (operands[2]) == 31
11943 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11944 "@
11945 {cltd|cdq}
11946 sar{l}\t{%2, %k0|%k0, %2}"
11947 [(set_attr "type" "imovx,ishift")
11948 (set_attr "prefix_0f" "0,*")
11949 (set_attr "length_immediate" "0,*")
11950 (set_attr "modrm" "0,1")
11951 (set_attr "mode" "SI")])
11952
11953 (define_expand "ashrsi3"
11954 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11955 (ashiftrt: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 (ASHIFTRT, SImode, operands); DONE;")
11960
11961 (define_insn "*ashrsi3_1_one_bit"
11962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11963 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11964 (match_operand:QI 2 "const_int_1_operand" "")))
11965 (clobber (reg:CC 17))]
11966 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11967 && (TARGET_SHIFT1 || optimize_size)"
11968 "sar{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 "*ashrsi3_1_one_bit_zext"
11976 [(set (match_operand:DI 0 "register_operand" "=r")
11977 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11978 (match_operand:QI 2 "const_int_1_operand" ""))))
11979 (clobber (reg:CC 17))]
11980 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11981 && (TARGET_SHIFT1 || optimize_size)"
11982 "sar{l}\t%k0"
11983 [(set_attr "type" "ishift")
11984 (set_attr "length" "2")])
11985
11986 (define_insn "*ashrsi3_1"
11987 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11988 (ashiftrt: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 (ASHIFTRT, SImode, operands)"
11992 "@
11993 sar{l}\t{%2, %0|%0, %2}
11994 sar{l}\t{%b2, %0|%0, %b2}"
11995 [(set_attr "type" "ishift")
11996 (set_attr "mode" "SI")])
11997
11998 (define_insn "*ashrsi3_1_zext"
11999 [(set (match_operand:DI 0 "register_operand" "=r,r")
12000 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12001 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12002 (clobber (reg:CC 17))]
12003 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12004 "@
12005 sar{l}\t{%2, %k0|%k0, %2}
12006 sar{l}\t{%b2, %k0|%k0, %b2}"
12007 [(set_attr "type" "ishift")
12008 (set_attr "mode" "SI")])
12009
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags. We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*ashrsi3_one_bit_cmp"
12014 [(set (reg 17)
12015 (compare
12016 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const_int_1_operand" ""))
12018 (const_int 0)))
12019 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12020 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12021 "ix86_match_ccmode (insn, CCGOCmode)
12022 && (TARGET_SHIFT1 || optimize_size)
12023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12024 "sar{l}\t%0"
12025 [(set_attr "type" "ishift")
12026 (set (attr "length")
12027 (if_then_else (match_operand:SI 0 "register_operand" "")
12028 (const_string "2")
12029 (const_string "*")))])
12030
12031 (define_insn "*ashrsi3_one_bit_cmp_zext"
12032 [(set (reg 17)
12033 (compare
12034 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12035 (match_operand:QI 2 "const_int_1_operand" ""))
12036 (const_int 0)))
12037 (set (match_operand:DI 0 "register_operand" "=r")
12038 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12039 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12040 && (TARGET_SHIFT1 || optimize_size)
12041 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12042 "sar{l}\t%k0"
12043 [(set_attr "type" "ishift")
12044 (set_attr "length" "2")])
12045
12046 ;; This pattern can't accept a variable shift count, since shifts by
12047 ;; zero don't affect the flags. We assume that shifts by constant
12048 ;; zero are optimized away.
12049 (define_insn "*ashrsi3_cmp"
12050 [(set (reg 17)
12051 (compare
12052 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12054 (const_int 0)))
12055 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12056 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12057 "ix86_match_ccmode (insn, CCGOCmode)
12058 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12059 "sar{l}\t{%2, %0|%0, %2}"
12060 [(set_attr "type" "ishift")
12061 (set_attr "mode" "SI")])
12062
12063 (define_insn "*ashrsi3_cmp_zext"
12064 [(set (reg 17)
12065 (compare
12066 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12067 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12068 (const_int 0)))
12069 (set (match_operand:DI 0 "register_operand" "=r")
12070 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12071 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12073 "sar{l}\t{%2, %k0|%k0, %2}"
12074 [(set_attr "type" "ishift")
12075 (set_attr "mode" "SI")])
12076
12077 (define_expand "ashrhi3"
12078 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12079 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))
12081 (clobber (reg:CC 17))]
12082 "TARGET_HIMODE_MATH"
12083 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12084
12085 (define_insn "*ashrhi3_1_one_bit"
12086 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12087 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const_int_1_operand" "")))
12089 (clobber (reg:CC 17))]
12090 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12091 && (TARGET_SHIFT1 || optimize_size)"
12092 "sar{w}\t%0"
12093 [(set_attr "type" "ishift")
12094 (set (attr "length")
12095 (if_then_else (match_operand 0 "register_operand" "")
12096 (const_string "2")
12097 (const_string "*")))])
12098
12099 (define_insn "*ashrhi3_1"
12100 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12101 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12102 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12103 (clobber (reg:CC 17))]
12104 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12105 "@
12106 sar{w}\t{%2, %0|%0, %2}
12107 sar{w}\t{%b2, %0|%0, %b2}"
12108 [(set_attr "type" "ishift")
12109 (set_attr "mode" "HI")])
12110
12111 ;; This pattern can't accept a variable shift count, since shifts by
12112 ;; zero don't affect the flags. We assume that shifts by constant
12113 ;; zero are optimized away.
12114 (define_insn "*ashrhi3_one_bit_cmp"
12115 [(set (reg 17)
12116 (compare
12117 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12118 (match_operand:QI 2 "const_int_1_operand" ""))
12119 (const_int 0)))
12120 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12121 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12122 "ix86_match_ccmode (insn, CCGOCmode)
12123 && (TARGET_SHIFT1 || optimize_size)
12124 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12125 "sar{w}\t%0"
12126 [(set_attr "type" "ishift")
12127 (set (attr "length")
12128 (if_then_else (match_operand 0 "register_operand" "")
12129 (const_string "2")
12130 (const_string "*")))])
12131
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags. We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*ashrhi3_cmp"
12136 [(set (reg 17)
12137 (compare
12138 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12140 (const_int 0)))
12141 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12142 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12143 "ix86_match_ccmode (insn, CCGOCmode)
12144 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12145 "sar{w}\t{%2, %0|%0, %2}"
12146 [(set_attr "type" "ishift")
12147 (set_attr "mode" "HI")])
12148
12149 (define_expand "ashrqi3"
12150 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12151 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12152 (match_operand:QI 2 "nonmemory_operand" "")))
12153 (clobber (reg:CC 17))]
12154 "TARGET_QIMODE_MATH"
12155 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12156
12157 (define_insn "*ashrqi3_1_one_bit"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12160 (match_operand:QI 2 "const_int_1_operand" "")))
12161 (clobber (reg:CC 17))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12163 && (TARGET_SHIFT1 || optimize_size)"
12164 "sar{b}\t%0"
12165 [(set_attr "type" "ishift")
12166 (set (attr "length")
12167 (if_then_else (match_operand 0 "register_operand" "")
12168 (const_string "2")
12169 (const_string "*")))])
12170
12171 (define_insn "*ashrqi3_1_one_bit_slp"
12172 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12173 (ashiftrt:QI (match_dup 0)
12174 (match_operand:QI 1 "const_int_1_operand" "")))
12175 (clobber (reg:CC 17))]
12176 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12177 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12178 && (TARGET_SHIFT1 || optimize_size)"
12179 "sar{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 "*ashrqi3_1"
12187 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12188 (ashiftrt: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 (ASHIFTRT, QImode, operands)"
12192 "@
12193 sar{b}\t{%2, %0|%0, %2}
12194 sar{b}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "ishift")
12196 (set_attr "mode" "QI")])
12197
12198 (define_insn "*ashrqi3_1_slp"
12199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12200 (ashiftrt: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 sar{b}\t{%1, %0|%0, %1}
12207 sar{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 "*ashrqi3_one_bit_cmp"
12215 [(set (reg 17)
12216 (compare
12217 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const_int_1_operand" "I"))
12219 (const_int 0)))
12220 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12221 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && (TARGET_SHIFT1 || optimize_size)
12224 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12225 "sar{b}\t%0"
12226 [(set_attr "type" "ishift")
12227 (set (attr "length")
12228 (if_then_else (match_operand 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 "*ashrqi3_cmp"
12236 [(set (reg 17)
12237 (compare
12238 (ashiftrt: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 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12245 "sar{b}\t{%2, %0|%0, %2}"
12246 [(set_attr "type" "ishift")
12247 (set_attr "mode" "QI")])
12248 \f
12249 ;; Logical shift instructions
12250
12251 ;; See comment above `ashldi3' about how this works.
12252
12253 (define_expand "lshrdi3"
12254 [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12255 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12256 (match_operand:QI 2 "nonmemory_operand" "")))
12257 (clobber (reg:CC 17))])]
12258 ""
12259 {
12260 if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12261 {
12262 emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12263 DONE;
12264 }
12265 ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12266 DONE;
12267 })
12268
12269 (define_insn "*lshrdi3_1_one_bit_rex64"
12270 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12272 (match_operand:QI 2 "const_int_1_operand" "")))
12273 (clobber (reg:CC 17))]
12274 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275 && (TARGET_SHIFT1 || optimize_size)"
12276 "shr{q}\t%0"
12277 [(set_attr "type" "ishift")
12278 (set (attr "length")
12279 (if_then_else (match_operand:DI 0 "register_operand" "")
12280 (const_string "2")
12281 (const_string "*")))])
12282
12283 (define_insn "*lshrdi3_1_rex64"
12284 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12285 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12286 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12287 (clobber (reg:CC 17))]
12288 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 "@
12290 shr{q}\t{%2, %0|%0, %2}
12291 shr{q}\t{%b2, %0|%0, %b2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "DI")])
12294
12295 ;; This pattern can't accept a variable shift count, since shifts by
12296 ;; zero don't affect the flags. We assume that shifts by constant
12297 ;; zero are optimized away.
12298 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12299 [(set (reg 17)
12300 (compare
12301 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const_int_1_operand" ""))
12303 (const_int 0)))
12304 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12305 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12306 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12307 && (TARGET_SHIFT1 || optimize_size)
12308 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309 "shr{q}\t%0"
12310 [(set_attr "type" "ishift")
12311 (set (attr "length")
12312 (if_then_else (match_operand:DI 0 "register_operand" "")
12313 (const_string "2")
12314 (const_string "*")))])
12315
12316 ;; This pattern can't accept a variable shift count, since shifts by
12317 ;; zero don't affect the flags. We assume that shifts by constant
12318 ;; zero are optimized away.
12319 (define_insn "*lshrdi3_cmp_rex64"
12320 [(set (reg 17)
12321 (compare
12322 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12323 (match_operand:QI 2 "const_int_operand" "e"))
12324 (const_int 0)))
12325 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12326 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12327 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12328 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12329 "shr{q}\t{%2, %0|%0, %2}"
12330 [(set_attr "type" "ishift")
12331 (set_attr "mode" "DI")])
12332
12333 (define_insn "lshrdi3_1"
12334 [(set (match_operand:DI 0 "register_operand" "=r")
12335 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12336 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12337 (clobber (match_scratch:SI 3 "=&r"))
12338 (clobber (reg:CC 17))]
12339 "!TARGET_64BIT && TARGET_CMOVE"
12340 "#"
12341 [(set_attr "type" "multi")])
12342
12343 (define_insn "*lshrdi3_2"
12344 [(set (match_operand:DI 0 "register_operand" "=r")
12345 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12346 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12347 (clobber (reg:CC 17))]
12348 "!TARGET_64BIT"
12349 "#"
12350 [(set_attr "type" "multi")])
12351
12352 (define_split
12353 [(set (match_operand:DI 0 "register_operand" "")
12354 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12355 (match_operand:QI 2 "nonmemory_operand" "")))
12356 (clobber (match_scratch:SI 3 ""))
12357 (clobber (reg:CC 17))]
12358 "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12359 [(const_int 0)]
12360 "ix86_split_lshrdi (operands, operands[3]); DONE;")
12361
12362 (define_split
12363 [(set (match_operand:DI 0 "register_operand" "")
12364 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12365 (match_operand:QI 2 "nonmemory_operand" "")))
12366 (clobber (reg:CC 17))]
12367 "!TARGET_64BIT && reload_completed"
12368 [(const_int 0)]
12369 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12370
12371 (define_expand "lshrsi3"
12372 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12373 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12374 (match_operand:QI 2 "nonmemory_operand" "")))
12375 (clobber (reg:CC 17))]
12376 ""
12377 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12378
12379 (define_insn "*lshrsi3_1_one_bit"
12380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12381 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12382 (match_operand:QI 2 "const_int_1_operand" "")))
12383 (clobber (reg:CC 17))]
12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12385 && (TARGET_SHIFT1 || optimize_size)"
12386 "shr{l}\t%0"
12387 [(set_attr "type" "ishift")
12388 (set (attr "length")
12389 (if_then_else (match_operand:SI 0 "register_operand" "")
12390 (const_string "2")
12391 (const_string "*")))])
12392
12393 (define_insn "*lshrsi3_1_one_bit_zext"
12394 [(set (match_operand:DI 0 "register_operand" "=r")
12395 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12396 (match_operand:QI 2 "const_int_1_operand" "")))
12397 (clobber (reg:CC 17))]
12398 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12399 && (TARGET_SHIFT1 || optimize_size)"
12400 "shr{l}\t%k0"
12401 [(set_attr "type" "ishift")
12402 (set_attr "length" "2")])
12403
12404 (define_insn "*lshrsi3_1"
12405 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12406 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12407 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12408 (clobber (reg:CC 17))]
12409 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12410 "@
12411 shr{l}\t{%2, %0|%0, %2}
12412 shr{l}\t{%b2, %0|%0, %b2}"
12413 [(set_attr "type" "ishift")
12414 (set_attr "mode" "SI")])
12415
12416 (define_insn "*lshrsi3_1_zext"
12417 [(set (match_operand:DI 0 "register_operand" "=r,r")
12418 (zero_extend:DI
12419 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12420 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12421 (clobber (reg:CC 17))]
12422 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12423 "@
12424 shr{l}\t{%2, %k0|%k0, %2}
12425 shr{l}\t{%b2, %k0|%k0, %b2}"
12426 [(set_attr "type" "ishift")
12427 (set_attr "mode" "SI")])
12428
12429 ;; This pattern can't accept a variable shift count, since shifts by
12430 ;; zero don't affect the flags. We assume that shifts by constant
12431 ;; zero are optimized away.
12432 (define_insn "*lshrsi3_one_bit_cmp"
12433 [(set (reg 17)
12434 (compare
12435 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12436 (match_operand:QI 2 "const_int_1_operand" ""))
12437 (const_int 0)))
12438 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12439 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12440 "ix86_match_ccmode (insn, CCGOCmode)
12441 && (TARGET_SHIFT1 || optimize_size)
12442 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12443 "shr{l}\t%0"
12444 [(set_attr "type" "ishift")
12445 (set (attr "length")
12446 (if_then_else (match_operand:SI 0 "register_operand" "")
12447 (const_string "2")
12448 (const_string "*")))])
12449
12450 (define_insn "*lshrsi3_cmp_one_bit_zext"
12451 [(set (reg 17)
12452 (compare
12453 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12454 (match_operand:QI 2 "const_int_1_operand" ""))
12455 (const_int 0)))
12456 (set (match_operand:DI 0 "register_operand" "=r")
12457 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12458 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12459 && (TARGET_SHIFT1 || optimize_size)
12460 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12461 "shr{l}\t%k0"
12462 [(set_attr "type" "ishift")
12463 (set_attr "length" "2")])
12464
12465 ;; This pattern can't accept a variable shift count, since shifts by
12466 ;; zero don't affect the flags. We assume that shifts by constant
12467 ;; zero are optimized away.
12468 (define_insn "*lshrsi3_cmp"
12469 [(set (reg 17)
12470 (compare
12471 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12472 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12473 (const_int 0)))
12474 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12475 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12476 "ix86_match_ccmode (insn, CCGOCmode)
12477 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12478 "shr{l}\t{%2, %0|%0, %2}"
12479 [(set_attr "type" "ishift")
12480 (set_attr "mode" "SI")])
12481
12482 (define_insn "*lshrsi3_cmp_zext"
12483 [(set (reg 17)
12484 (compare
12485 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12486 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12487 (const_int 0)))
12488 (set (match_operand:DI 0 "register_operand" "=r")
12489 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12490 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12491 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12492 "shr{l}\t{%2, %k0|%k0, %2}"
12493 [(set_attr "type" "ishift")
12494 (set_attr "mode" "SI")])
12495
12496 (define_expand "lshrhi3"
12497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12498 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12499 (match_operand:QI 2 "nonmemory_operand" "")))
12500 (clobber (reg:CC 17))]
12501 "TARGET_HIMODE_MATH"
12502 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12503
12504 (define_insn "*lshrhi3_1_one_bit"
12505 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12506 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12507 (match_operand:QI 2 "const_int_1_operand" "")))
12508 (clobber (reg:CC 17))]
12509 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12510 && (TARGET_SHIFT1 || optimize_size)"
12511 "shr{w}\t%0"
12512 [(set_attr "type" "ishift")
12513 (set (attr "length")
12514 (if_then_else (match_operand 0 "register_operand" "")
12515 (const_string "2")
12516 (const_string "*")))])
12517
12518 (define_insn "*lshrhi3_1"
12519 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12520 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12521 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12522 (clobber (reg:CC 17))]
12523 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524 "@
12525 shr{w}\t{%2, %0|%0, %2}
12526 shr{w}\t{%b2, %0|%0, %b2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "HI")])
12529
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags. We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrhi3_one_bit_cmp"
12534 [(set (reg 17)
12535 (compare
12536 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const_int_1_operand" ""))
12538 (const_int 0)))
12539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12540 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12541 "ix86_match_ccmode (insn, CCGOCmode)
12542 && (TARGET_SHIFT1 || optimize_size)
12543 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544 "shr{w}\t%0"
12545 [(set_attr "type" "ishift")
12546 (set (attr "length")
12547 (if_then_else (match_operand:SI 0 "register_operand" "")
12548 (const_string "2")
12549 (const_string "*")))])
12550
12551 ;; This pattern can't accept a variable shift count, since shifts by
12552 ;; zero don't affect the flags. We assume that shifts by constant
12553 ;; zero are optimized away.
12554 (define_insn "*lshrhi3_cmp"
12555 [(set (reg 17)
12556 (compare
12557 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12559 (const_int 0)))
12560 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12561 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12562 "ix86_match_ccmode (insn, CCGOCmode)
12563 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12564 "shr{w}\t{%2, %0|%0, %2}"
12565 [(set_attr "type" "ishift")
12566 (set_attr "mode" "HI")])
12567
12568 (define_expand "lshrqi3"
12569 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12570 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12571 (match_operand:QI 2 "nonmemory_operand" "")))
12572 (clobber (reg:CC 17))]
12573 "TARGET_QIMODE_MATH"
12574 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12575
12576 (define_insn "*lshrqi3_1_one_bit"
12577 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579 (match_operand:QI 2 "const_int_1_operand" "")))
12580 (clobber (reg:CC 17))]
12581 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12582 && (TARGET_SHIFT1 || optimize_size)"
12583 "shr{b}\t%0"
12584 [(set_attr "type" "ishift")
12585 (set (attr "length")
12586 (if_then_else (match_operand 0 "register_operand" "")
12587 (const_string "2")
12588 (const_string "*")))])
12589
12590 (define_insn "*lshrqi3_1_one_bit_slp"
12591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12592 (lshiftrt:QI (match_dup 0)
12593 (match_operand:QI 1 "const_int_1_operand" "")))
12594 (clobber (reg:CC 17))]
12595 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12596 && (TARGET_SHIFT1 || optimize_size)"
12597 "shr{b}\t%0"
12598 [(set_attr "type" "ishift1")
12599 (set (attr "length")
12600 (if_then_else (match_operand 0 "register_operand" "")
12601 (const_string "2")
12602 (const_string "*")))])
12603
12604 (define_insn "*lshrqi3_1"
12605 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12606 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12608 (clobber (reg:CC 17))]
12609 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12610 "@
12611 shr{b}\t{%2, %0|%0, %2}
12612 shr{b}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "ishift")
12614 (set_attr "mode" "QI")])
12615
12616 (define_insn "*lshrqi3_1_slp"
12617 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12618 (lshiftrt:QI (match_dup 0)
12619 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12620 (clobber (reg:CC 17))]
12621 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12622 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12623 "@
12624 shr{b}\t{%1, %0|%0, %1}
12625 shr{b}\t{%b1, %0|%0, %b1}"
12626 [(set_attr "type" "ishift1")
12627 (set_attr "mode" "QI")])
12628
12629 ;; This pattern can't accept a variable shift count, since shifts by
12630 ;; zero don't affect the flags. We assume that shifts by constant
12631 ;; zero are optimized away.
12632 (define_insn "*lshrqi2_one_bit_cmp"
12633 [(set (reg 17)
12634 (compare
12635 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12636 (match_operand:QI 2 "const_int_1_operand" ""))
12637 (const_int 0)))
12638 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12639 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12640 "ix86_match_ccmode (insn, CCGOCmode)
12641 && (TARGET_SHIFT1 || optimize_size)
12642 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12643 "shr{b}\t%0"
12644 [(set_attr "type" "ishift")
12645 (set (attr "length")
12646 (if_then_else (match_operand:SI 0 "register_operand" "")
12647 (const_string "2")
12648 (const_string "*")))])
12649
12650 ;; This pattern can't accept a variable shift count, since shifts by
12651 ;; zero don't affect the flags. We assume that shifts by constant
12652 ;; zero are optimized away.
12653 (define_insn "*lshrqi2_cmp"
12654 [(set (reg 17)
12655 (compare
12656 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12657 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12658 (const_int 0)))
12659 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12661 "ix86_match_ccmode (insn, CCGOCmode)
12662 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12663 "shr{b}\t{%2, %0|%0, %2}"
12664 [(set_attr "type" "ishift")
12665 (set_attr "mode" "QI")])
12666 \f
12667 ;; Rotate instructions
12668
12669 (define_expand "rotldi3"
12670 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12671 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12672 (match_operand:QI 2 "nonmemory_operand" "")))
12673 (clobber (reg:CC 17))]
12674 "TARGET_64BIT"
12675 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12676
12677 (define_insn "*rotlsi3_1_one_bit_rex64"
12678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12679 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12680 (match_operand:QI 2 "const_int_1_operand" "")))
12681 (clobber (reg:CC 17))]
12682 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12683 && (TARGET_SHIFT1 || optimize_size)"
12684 "rol{q}\t%0"
12685 [(set_attr "type" "rotate")
12686 (set (attr "length")
12687 (if_then_else (match_operand:DI 0 "register_operand" "")
12688 (const_string "2")
12689 (const_string "*")))])
12690
12691 (define_insn "*rotldi3_1_rex64"
12692 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12693 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12694 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12695 (clobber (reg:CC 17))]
12696 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12697 "@
12698 rol{q}\t{%2, %0|%0, %2}
12699 rol{q}\t{%b2, %0|%0, %b2}"
12700 [(set_attr "type" "rotate")
12701 (set_attr "mode" "DI")])
12702
12703 (define_expand "rotlsi3"
12704 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12705 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12706 (match_operand:QI 2 "nonmemory_operand" "")))
12707 (clobber (reg:CC 17))]
12708 ""
12709 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12710
12711 (define_insn "*rotlsi3_1_one_bit"
12712 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12713 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12714 (match_operand:QI 2 "const_int_1_operand" "")))
12715 (clobber (reg:CC 17))]
12716 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12717 && (TARGET_SHIFT1 || optimize_size)"
12718 "rol{l}\t%0"
12719 [(set_attr "type" "rotate")
12720 (set (attr "length")
12721 (if_then_else (match_operand:SI 0 "register_operand" "")
12722 (const_string "2")
12723 (const_string "*")))])
12724
12725 (define_insn "*rotlsi3_1_one_bit_zext"
12726 [(set (match_operand:DI 0 "register_operand" "=r")
12727 (zero_extend:DI
12728 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12729 (match_operand:QI 2 "const_int_1_operand" ""))))
12730 (clobber (reg:CC 17))]
12731 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12732 && (TARGET_SHIFT1 || optimize_size)"
12733 "rol{l}\t%k0"
12734 [(set_attr "type" "rotate")
12735 (set_attr "length" "2")])
12736
12737 (define_insn "*rotlsi3_1"
12738 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12739 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12740 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12741 (clobber (reg:CC 17))]
12742 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12743 "@
12744 rol{l}\t{%2, %0|%0, %2}
12745 rol{l}\t{%b2, %0|%0, %b2}"
12746 [(set_attr "type" "rotate")
12747 (set_attr "mode" "SI")])
12748
12749 (define_insn "*rotlsi3_1_zext"
12750 [(set (match_operand:DI 0 "register_operand" "=r,r")
12751 (zero_extend:DI
12752 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12753 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12754 (clobber (reg:CC 17))]
12755 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12756 "@
12757 rol{l}\t{%2, %k0|%k0, %2}
12758 rol{l}\t{%b2, %k0|%k0, %b2}"
12759 [(set_attr "type" "rotate")
12760 (set_attr "mode" "SI")])
12761
12762 (define_expand "rotlhi3"
12763 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12764 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12765 (match_operand:QI 2 "nonmemory_operand" "")))
12766 (clobber (reg:CC 17))]
12767 "TARGET_HIMODE_MATH"
12768 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12769
12770 (define_insn "*rotlhi3_1_one_bit"
12771 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12772 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12773 (match_operand:QI 2 "const_int_1_operand" "")))
12774 (clobber (reg:CC 17))]
12775 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12776 && (TARGET_SHIFT1 || optimize_size)"
12777 "rol{w}\t%0"
12778 [(set_attr "type" "rotate")
12779 (set (attr "length")
12780 (if_then_else (match_operand 0 "register_operand" "")
12781 (const_string "2")
12782 (const_string "*")))])
12783
12784 (define_insn "*rotlhi3_1"
12785 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12786 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12787 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12788 (clobber (reg:CC 17))]
12789 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12790 "@
12791 rol{w}\t{%2, %0|%0, %2}
12792 rol{w}\t{%b2, %0|%0, %b2}"
12793 [(set_attr "type" "rotate")
12794 (set_attr "mode" "HI")])
12795
12796 (define_expand "rotlqi3"
12797 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12798 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12799 (match_operand:QI 2 "nonmemory_operand" "")))
12800 (clobber (reg:CC 17))]
12801 "TARGET_QIMODE_MATH"
12802 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12803
12804 (define_insn "*rotlqi3_1_one_bit_slp"
12805 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12806 (rotate:QI (match_dup 0)
12807 (match_operand:QI 1 "const_int_1_operand" "")))
12808 (clobber (reg:CC 17))]
12809 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12810 && (TARGET_SHIFT1 || optimize_size)"
12811 "rol{b}\t%0"
12812 [(set_attr "type" "rotate1")
12813 (set (attr "length")
12814 (if_then_else (match_operand 0 "register_operand" "")
12815 (const_string "2")
12816 (const_string "*")))])
12817
12818 (define_insn "*rotlqi3_1_one_bit"
12819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12821 (match_operand:QI 2 "const_int_1_operand" "")))
12822 (clobber (reg:CC 17))]
12823 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12824 && (TARGET_SHIFT1 || optimize_size)"
12825 "rol{b}\t%0"
12826 [(set_attr "type" "rotate")
12827 (set (attr "length")
12828 (if_then_else (match_operand 0 "register_operand" "")
12829 (const_string "2")
12830 (const_string "*")))])
12831
12832 (define_insn "*rotlqi3_1_slp"
12833 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12834 (rotate:QI (match_dup 0)
12835 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12836 (clobber (reg:CC 17))]
12837 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12838 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12839 "@
12840 rol{b}\t{%1, %0|%0, %1}
12841 rol{b}\t{%b1, %0|%0, %b1}"
12842 [(set_attr "type" "rotate1")
12843 (set_attr "mode" "QI")])
12844
12845 (define_insn "*rotlqi3_1"
12846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12847 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12848 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12849 (clobber (reg:CC 17))]
12850 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12851 "@
12852 rol{b}\t{%2, %0|%0, %2}
12853 rol{b}\t{%b2, %0|%0, %b2}"
12854 [(set_attr "type" "rotate")
12855 (set_attr "mode" "QI")])
12856
12857 (define_expand "rotrdi3"
12858 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12859 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12860 (match_operand:QI 2 "nonmemory_operand" "")))
12861 (clobber (reg:CC 17))]
12862 "TARGET_64BIT"
12863 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12864
12865 (define_insn "*rotrdi3_1_one_bit_rex64"
12866 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12867 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12868 (match_operand:QI 2 "const_int_1_operand" "")))
12869 (clobber (reg:CC 17))]
12870 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12871 && (TARGET_SHIFT1 || optimize_size)"
12872 "ror{q}\t%0"
12873 [(set_attr "type" "rotate")
12874 (set (attr "length")
12875 (if_then_else (match_operand:DI 0 "register_operand" "")
12876 (const_string "2")
12877 (const_string "*")))])
12878
12879 (define_insn "*rotrdi3_1_rex64"
12880 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12881 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12882 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12883 (clobber (reg:CC 17))]
12884 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12885 "@
12886 ror{q}\t{%2, %0|%0, %2}
12887 ror{q}\t{%b2, %0|%0, %b2}"
12888 [(set_attr "type" "rotate")
12889 (set_attr "mode" "DI")])
12890
12891 (define_expand "rotrsi3"
12892 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12893 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12894 (match_operand:QI 2 "nonmemory_operand" "")))
12895 (clobber (reg:CC 17))]
12896 ""
12897 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12898
12899 (define_insn "*rotrsi3_1_one_bit"
12900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12901 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12902 (match_operand:QI 2 "const_int_1_operand" "")))
12903 (clobber (reg:CC 17))]
12904 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12905 && (TARGET_SHIFT1 || optimize_size)"
12906 "ror{l}\t%0"
12907 [(set_attr "type" "rotate")
12908 (set (attr "length")
12909 (if_then_else (match_operand:SI 0 "register_operand" "")
12910 (const_string "2")
12911 (const_string "*")))])
12912
12913 (define_insn "*rotrsi3_1_one_bit_zext"
12914 [(set (match_operand:DI 0 "register_operand" "=r")
12915 (zero_extend:DI
12916 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12917 (match_operand:QI 2 "const_int_1_operand" ""))))
12918 (clobber (reg:CC 17))]
12919 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12920 && (TARGET_SHIFT1 || optimize_size)"
12921 "ror{l}\t%k0"
12922 [(set_attr "type" "rotate")
12923 (set (attr "length")
12924 (if_then_else (match_operand:SI 0 "register_operand" "")
12925 (const_string "2")
12926 (const_string "*")))])
12927
12928 (define_insn "*rotrsi3_1"
12929 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12930 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12931 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12932 (clobber (reg:CC 17))]
12933 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12934 "@
12935 ror{l}\t{%2, %0|%0, %2}
12936 ror{l}\t{%b2, %0|%0, %b2}"
12937 [(set_attr "type" "rotate")
12938 (set_attr "mode" "SI")])
12939
12940 (define_insn "*rotrsi3_1_zext"
12941 [(set (match_operand:DI 0 "register_operand" "=r,r")
12942 (zero_extend:DI
12943 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12944 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12945 (clobber (reg:CC 17))]
12946 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12947 "@
12948 ror{l}\t{%2, %k0|%k0, %2}
12949 ror{l}\t{%b2, %k0|%k0, %b2}"
12950 [(set_attr "type" "rotate")
12951 (set_attr "mode" "SI")])
12952
12953 (define_expand "rotrhi3"
12954 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12955 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12956 (match_operand:QI 2 "nonmemory_operand" "")))
12957 (clobber (reg:CC 17))]
12958 "TARGET_HIMODE_MATH"
12959 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12960
12961 (define_insn "*rotrhi3_one_bit"
12962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12963 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12964 (match_operand:QI 2 "const_int_1_operand" "")))
12965 (clobber (reg:CC 17))]
12966 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12967 && (TARGET_SHIFT1 || optimize_size)"
12968 "ror{w}\t%0"
12969 [(set_attr "type" "rotate")
12970 (set (attr "length")
12971 (if_then_else (match_operand 0 "register_operand" "")
12972 (const_string "2")
12973 (const_string "*")))])
12974
12975 (define_insn "*rotrhi3"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12977 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12978 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12979 (clobber (reg:CC 17))]
12980 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12981 "@
12982 ror{w}\t{%2, %0|%0, %2}
12983 ror{w}\t{%b2, %0|%0, %b2}"
12984 [(set_attr "type" "rotate")
12985 (set_attr "mode" "HI")])
12986
12987 (define_expand "rotrqi3"
12988 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12989 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12990 (match_operand:QI 2 "nonmemory_operand" "")))
12991 (clobber (reg:CC 17))]
12992 "TARGET_QIMODE_MATH"
12993 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12994
12995 (define_insn "*rotrqi3_1_one_bit"
12996 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12997 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12998 (match_operand:QI 2 "const_int_1_operand" "")))
12999 (clobber (reg:CC 17))]
13000 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13001 && (TARGET_SHIFT1 || optimize_size)"
13002 "ror{b}\t%0"
13003 [(set_attr "type" "rotate")
13004 (set (attr "length")
13005 (if_then_else (match_operand 0 "register_operand" "")
13006 (const_string "2")
13007 (const_string "*")))])
13008
13009 (define_insn "*rotrqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotatert:QI (match_dup 0)
13012 (match_operand:QI 1 "const_int_1_operand" "")))
13013 (clobber (reg:CC 17))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13016 "ror{b}\t%0"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13020 (const_string "2")
13021 (const_string "*")))])
13022
13023 (define_insn "*rotrqi3_1"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13025 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13026 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13027 (clobber (reg:CC 17))]
13028 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13029 "@
13030 ror{b}\t{%2, %0|%0, %2}
13031 ror{b}\t{%b2, %0|%0, %b2}"
13032 [(set_attr "type" "rotate")
13033 (set_attr "mode" "QI")])
13034
13035 (define_insn "*rotrqi3_1_slp"
13036 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13037 (rotatert:QI (match_dup 0)
13038 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13039 (clobber (reg:CC 17))]
13040 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13041 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13042 "@
13043 ror{b}\t{%1, %0|%0, %1}
13044 ror{b}\t{%b1, %0|%0, %b1}"
13045 [(set_attr "type" "rotate1")
13046 (set_attr "mode" "QI")])
13047 \f
13048 ;; Bit set / bit test instructions
13049
13050 (define_expand "extv"
13051 [(set (match_operand:SI 0 "register_operand" "")
13052 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13053 (match_operand:SI 2 "immediate_operand" "")
13054 (match_operand:SI 3 "immediate_operand" "")))]
13055 ""
13056 {
13057 /* Handle extractions from %ah et al. */
13058 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13059 FAIL;
13060
13061 /* From mips.md: extract_bit_field doesn't verify that our source
13062 matches the predicate, so check it again here. */
13063 if (! register_operand (operands[1], VOIDmode))
13064 FAIL;
13065 })
13066
13067 (define_expand "extzv"
13068 [(set (match_operand:SI 0 "register_operand" "")
13069 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13070 (match_operand:SI 2 "immediate_operand" "")
13071 (match_operand:SI 3 "immediate_operand" "")))]
13072 ""
13073 {
13074 /* Handle extractions from %ah et al. */
13075 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13076 FAIL;
13077
13078 /* From mips.md: extract_bit_field doesn't verify that our source
13079 matches the predicate, so check it again here. */
13080 if (! register_operand (operands[1], VOIDmode))
13081 FAIL;
13082 })
13083
13084 (define_expand "insv"
13085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13086 (match_operand:SI 1 "immediate_operand" "")
13087 (match_operand:SI 2 "immediate_operand" ""))
13088 (match_operand:SI 3 "register_operand" ""))]
13089 ""
13090 {
13091 /* Handle extractions from %ah et al. */
13092 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13093 FAIL;
13094
13095 /* From mips.md: insert_bit_field doesn't verify that our source
13096 matches the predicate, so check it again here. */
13097 if (! register_operand (operands[0], VOIDmode))
13098 FAIL;
13099 })
13100
13101 ;; %%% bts, btr, btc, bt.
13102 \f
13103 ;; Store-flag instructions.
13104
13105 ;; For all sCOND expanders, also expand the compare or test insn that
13106 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13107
13108 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13109 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13110 ;; way, which can later delete the movzx if only QImode is needed.
13111
13112 (define_expand "seq"
13113 [(set (match_operand:QI 0 "register_operand" "")
13114 (eq:QI (reg:CC 17) (const_int 0)))]
13115 ""
13116 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13117
13118 (define_expand "sne"
13119 [(set (match_operand:QI 0 "register_operand" "")
13120 (ne:QI (reg:CC 17) (const_int 0)))]
13121 ""
13122 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13123
13124 (define_expand "sgt"
13125 [(set (match_operand:QI 0 "register_operand" "")
13126 (gt:QI (reg:CC 17) (const_int 0)))]
13127 ""
13128 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13129
13130 (define_expand "sgtu"
13131 [(set (match_operand:QI 0 "register_operand" "")
13132 (gtu:QI (reg:CC 17) (const_int 0)))]
13133 ""
13134 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13135
13136 (define_expand "slt"
13137 [(set (match_operand:QI 0 "register_operand" "")
13138 (lt:QI (reg:CC 17) (const_int 0)))]
13139 ""
13140 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13141
13142 (define_expand "sltu"
13143 [(set (match_operand:QI 0 "register_operand" "")
13144 (ltu:QI (reg:CC 17) (const_int 0)))]
13145 ""
13146 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13147
13148 (define_expand "sge"
13149 [(set (match_operand:QI 0 "register_operand" "")
13150 (ge:QI (reg:CC 17) (const_int 0)))]
13151 ""
13152 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13153
13154 (define_expand "sgeu"
13155 [(set (match_operand:QI 0 "register_operand" "")
13156 (geu:QI (reg:CC 17) (const_int 0)))]
13157 ""
13158 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13159
13160 (define_expand "sle"
13161 [(set (match_operand:QI 0 "register_operand" "")
13162 (le:QI (reg:CC 17) (const_int 0)))]
13163 ""
13164 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13165
13166 (define_expand "sleu"
13167 [(set (match_operand:QI 0 "register_operand" "")
13168 (leu:QI (reg:CC 17) (const_int 0)))]
13169 ""
13170 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13171
13172 (define_expand "sunordered"
13173 [(set (match_operand:QI 0 "register_operand" "")
13174 (unordered:QI (reg:CC 17) (const_int 0)))]
13175 "TARGET_80387 || TARGET_SSE"
13176 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13177
13178 (define_expand "sordered"
13179 [(set (match_operand:QI 0 "register_operand" "")
13180 (ordered:QI (reg:CC 17) (const_int 0)))]
13181 "TARGET_80387"
13182 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13183
13184 (define_expand "suneq"
13185 [(set (match_operand:QI 0 "register_operand" "")
13186 (uneq:QI (reg:CC 17) (const_int 0)))]
13187 "TARGET_80387 || TARGET_SSE"
13188 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13189
13190 (define_expand "sunge"
13191 [(set (match_operand:QI 0 "register_operand" "")
13192 (unge:QI (reg:CC 17) (const_int 0)))]
13193 "TARGET_80387 || TARGET_SSE"
13194 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13195
13196 (define_expand "sungt"
13197 [(set (match_operand:QI 0 "register_operand" "")
13198 (ungt:QI (reg:CC 17) (const_int 0)))]
13199 "TARGET_80387 || TARGET_SSE"
13200 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13201
13202 (define_expand "sunle"
13203 [(set (match_operand:QI 0 "register_operand" "")
13204 (unle:QI (reg:CC 17) (const_int 0)))]
13205 "TARGET_80387 || TARGET_SSE"
13206 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13207
13208 (define_expand "sunlt"
13209 [(set (match_operand:QI 0 "register_operand" "")
13210 (unlt:QI (reg:CC 17) (const_int 0)))]
13211 "TARGET_80387 || TARGET_SSE"
13212 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13213
13214 (define_expand "sltgt"
13215 [(set (match_operand:QI 0 "register_operand" "")
13216 (ltgt:QI (reg:CC 17) (const_int 0)))]
13217 "TARGET_80387 || TARGET_SSE"
13218 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13219
13220 (define_insn "*setcc_1"
13221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13222 (match_operator:QI 1 "ix86_comparison_operator"
13223 [(reg 17) (const_int 0)]))]
13224 ""
13225 "set%C1\t%0"
13226 [(set_attr "type" "setcc")
13227 (set_attr "mode" "QI")])
13228
13229 (define_insn "setcc_2"
13230 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13231 (match_operator:QI 1 "ix86_comparison_operator"
13232 [(reg 17) (const_int 0)]))]
13233 ""
13234 "set%C1\t%0"
13235 [(set_attr "type" "setcc")
13236 (set_attr "mode" "QI")])
13237
13238 ;; In general it is not safe to assume too much about CCmode registers,
13239 ;; so simplify-rtx stops when it sees a second one. Under certain
13240 ;; conditions this is safe on x86, so help combine not create
13241 ;;
13242 ;; seta %al
13243 ;; testb %al, %al
13244 ;; sete %al
13245
13246 (define_split
13247 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13248 (ne:QI (match_operator 1 "ix86_comparison_operator"
13249 [(reg 17) (const_int 0)])
13250 (const_int 0)))]
13251 ""
13252 [(set (match_dup 0) (match_dup 1))]
13253 {
13254 PUT_MODE (operands[1], QImode);
13255 })
13256
13257 (define_split
13258 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13259 (ne:QI (match_operator 1 "ix86_comparison_operator"
13260 [(reg 17) (const_int 0)])
13261 (const_int 0)))]
13262 ""
13263 [(set (match_dup 0) (match_dup 1))]
13264 {
13265 PUT_MODE (operands[1], QImode);
13266 })
13267
13268 (define_split
13269 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13270 (eq:QI (match_operator 1 "ix86_comparison_operator"
13271 [(reg 17) (const_int 0)])
13272 (const_int 0)))]
13273 ""
13274 [(set (match_dup 0) (match_dup 1))]
13275 {
13276 rtx new_op1 = copy_rtx (operands[1]);
13277 operands[1] = new_op1;
13278 PUT_MODE (new_op1, QImode);
13279 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13280 GET_MODE (XEXP (new_op1, 0))));
13281
13282 /* Make sure that (a) the CCmode we have for the flags is strong
13283 enough for the reversed compare or (b) we have a valid FP compare. */
13284 if (! ix86_comparison_operator (new_op1, VOIDmode))
13285 FAIL;
13286 })
13287
13288 (define_split
13289 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13290 (eq:QI (match_operator 1 "ix86_comparison_operator"
13291 [(reg 17) (const_int 0)])
13292 (const_int 0)))]
13293 ""
13294 [(set (match_dup 0) (match_dup 1))]
13295 {
13296 rtx new_op1 = copy_rtx (operands[1]);
13297 operands[1] = new_op1;
13298 PUT_MODE (new_op1, QImode);
13299 PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13300 GET_MODE (XEXP (new_op1, 0))));
13301
13302 /* Make sure that (a) the CCmode we have for the flags is strong
13303 enough for the reversed compare or (b) we have a valid FP compare. */
13304 if (! ix86_comparison_operator (new_op1, VOIDmode))
13305 FAIL;
13306 })
13307
13308 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13309 ;; subsequent logical operations are used to imitate conditional moves.
13310 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13311 ;; it directly. Further holding this value in pseudo register might bring
13312 ;; problem in implicit normalization in spill code.
13313 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13314 ;; instructions after reload by splitting the conditional move patterns.
13315
13316 (define_insn "*sse_setccsf"
13317 [(set (match_operand:SF 0 "register_operand" "=x")
13318 (match_operator:SF 1 "sse_comparison_operator"
13319 [(match_operand:SF 2 "register_operand" "0")
13320 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13321 "TARGET_SSE && reload_completed"
13322 "cmp%D1ss\t{%3, %0|%0, %3}"
13323 [(set_attr "type" "ssecmp")
13324 (set_attr "mode" "SF")])
13325
13326 (define_insn "*sse_setccdf"
13327 [(set (match_operand:DF 0 "register_operand" "=Y")
13328 (match_operator:DF 1 "sse_comparison_operator"
13329 [(match_operand:DF 2 "register_operand" "0")
13330 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13331 "TARGET_SSE2 && reload_completed"
13332 "cmp%D1sd\t{%3, %0|%0, %3}"
13333 [(set_attr "type" "ssecmp")
13334 (set_attr "mode" "DF")])
13335 \f
13336 ;; Basic conditional jump instructions.
13337 ;; We ignore the overflow flag for signed branch instructions.
13338
13339 ;; For all bCOND expanders, also expand the compare or test insn that
13340 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
13341
13342 (define_expand "beq"
13343 [(set (pc)
13344 (if_then_else (match_dup 1)
13345 (label_ref (match_operand 0 "" ""))
13346 (pc)))]
13347 ""
13348 "ix86_expand_branch (EQ, operands[0]); DONE;")
13349
13350 (define_expand "bne"
13351 [(set (pc)
13352 (if_then_else (match_dup 1)
13353 (label_ref (match_operand 0 "" ""))
13354 (pc)))]
13355 ""
13356 "ix86_expand_branch (NE, operands[0]); DONE;")
13357
13358 (define_expand "bgt"
13359 [(set (pc)
13360 (if_then_else (match_dup 1)
13361 (label_ref (match_operand 0 "" ""))
13362 (pc)))]
13363 ""
13364 "ix86_expand_branch (GT, operands[0]); DONE;")
13365
13366 (define_expand "bgtu"
13367 [(set (pc)
13368 (if_then_else (match_dup 1)
13369 (label_ref (match_operand 0 "" ""))
13370 (pc)))]
13371 ""
13372 "ix86_expand_branch (GTU, operands[0]); DONE;")
13373
13374 (define_expand "blt"
13375 [(set (pc)
13376 (if_then_else (match_dup 1)
13377 (label_ref (match_operand 0 "" ""))
13378 (pc)))]
13379 ""
13380 "ix86_expand_branch (LT, operands[0]); DONE;")
13381
13382 (define_expand "bltu"
13383 [(set (pc)
13384 (if_then_else (match_dup 1)
13385 (label_ref (match_operand 0 "" ""))
13386 (pc)))]
13387 ""
13388 "ix86_expand_branch (LTU, operands[0]); DONE;")
13389
13390 (define_expand "bge"
13391 [(set (pc)
13392 (if_then_else (match_dup 1)
13393 (label_ref (match_operand 0 "" ""))
13394 (pc)))]
13395 ""
13396 "ix86_expand_branch (GE, operands[0]); DONE;")
13397
13398 (define_expand "bgeu"
13399 [(set (pc)
13400 (if_then_else (match_dup 1)
13401 (label_ref (match_operand 0 "" ""))
13402 (pc)))]
13403 ""
13404 "ix86_expand_branch (GEU, operands[0]); DONE;")
13405
13406 (define_expand "ble"
13407 [(set (pc)
13408 (if_then_else (match_dup 1)
13409 (label_ref (match_operand 0 "" ""))
13410 (pc)))]
13411 ""
13412 "ix86_expand_branch (LE, operands[0]); DONE;")
13413
13414 (define_expand "bleu"
13415 [(set (pc)
13416 (if_then_else (match_dup 1)
13417 (label_ref (match_operand 0 "" ""))
13418 (pc)))]
13419 ""
13420 "ix86_expand_branch (LEU, operands[0]); DONE;")
13421
13422 (define_expand "bunordered"
13423 [(set (pc)
13424 (if_then_else (match_dup 1)
13425 (label_ref (match_operand 0 "" ""))
13426 (pc)))]
13427 "TARGET_80387 || TARGET_SSE"
13428 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13429
13430 (define_expand "bordered"
13431 [(set (pc)
13432 (if_then_else (match_dup 1)
13433 (label_ref (match_operand 0 "" ""))
13434 (pc)))]
13435 "TARGET_80387 || TARGET_SSE"
13436 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13437
13438 (define_expand "buneq"
13439 [(set (pc)
13440 (if_then_else (match_dup 1)
13441 (label_ref (match_operand 0 "" ""))
13442 (pc)))]
13443 "TARGET_80387 || TARGET_SSE"
13444 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13445
13446 (define_expand "bunge"
13447 [(set (pc)
13448 (if_then_else (match_dup 1)
13449 (label_ref (match_operand 0 "" ""))
13450 (pc)))]
13451 "TARGET_80387 || TARGET_SSE"
13452 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13453
13454 (define_expand "bungt"
13455 [(set (pc)
13456 (if_then_else (match_dup 1)
13457 (label_ref (match_operand 0 "" ""))
13458 (pc)))]
13459 "TARGET_80387 || TARGET_SSE"
13460 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13461
13462 (define_expand "bunle"
13463 [(set (pc)
13464 (if_then_else (match_dup 1)
13465 (label_ref (match_operand 0 "" ""))
13466 (pc)))]
13467 "TARGET_80387 || TARGET_SSE"
13468 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13469
13470 (define_expand "bunlt"
13471 [(set (pc)
13472 (if_then_else (match_dup 1)
13473 (label_ref (match_operand 0 "" ""))
13474 (pc)))]
13475 "TARGET_80387 || TARGET_SSE"
13476 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13477
13478 (define_expand "bltgt"
13479 [(set (pc)
13480 (if_then_else (match_dup 1)
13481 (label_ref (match_operand 0 "" ""))
13482 (pc)))]
13483 "TARGET_80387 || TARGET_SSE"
13484 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13485
13486 (define_insn "*jcc_1"
13487 [(set (pc)
13488 (if_then_else (match_operator 1 "ix86_comparison_operator"
13489 [(reg 17) (const_int 0)])
13490 (label_ref (match_operand 0 "" ""))
13491 (pc)))]
13492 ""
13493 "%+j%C1\t%l0"
13494 [(set_attr "type" "ibr")
13495 (set_attr "modrm" "0")
13496 (set (attr "length")
13497 (if_then_else (and (ge (minus (match_dup 0) (pc))
13498 (const_int -126))
13499 (lt (minus (match_dup 0) (pc))
13500 (const_int 128)))
13501 (const_int 2)
13502 (const_int 6)))])
13503
13504 (define_insn "*jcc_2"
13505 [(set (pc)
13506 (if_then_else (match_operator 1 "ix86_comparison_operator"
13507 [(reg 17) (const_int 0)])
13508 (pc)
13509 (label_ref (match_operand 0 "" ""))))]
13510 ""
13511 "%+j%c1\t%l0"
13512 [(set_attr "type" "ibr")
13513 (set_attr "modrm" "0")
13514 (set (attr "length")
13515 (if_then_else (and (ge (minus (match_dup 0) (pc))
13516 (const_int -126))
13517 (lt (minus (match_dup 0) (pc))
13518 (const_int 128)))
13519 (const_int 2)
13520 (const_int 6)))])
13521
13522 ;; In general it is not safe to assume too much about CCmode registers,
13523 ;; so simplify-rtx stops when it sees a second one. Under certain
13524 ;; conditions this is safe on x86, so help combine not create
13525 ;;
13526 ;; seta %al
13527 ;; testb %al, %al
13528 ;; je Lfoo
13529
13530 (define_split
13531 [(set (pc)
13532 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13533 [(reg 17) (const_int 0)])
13534 (const_int 0))
13535 (label_ref (match_operand 1 "" ""))
13536 (pc)))]
13537 ""
13538 [(set (pc)
13539 (if_then_else (match_dup 0)
13540 (label_ref (match_dup 1))
13541 (pc)))]
13542 {
13543 PUT_MODE (operands[0], VOIDmode);
13544 })
13545
13546 (define_split
13547 [(set (pc)
13548 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13549 [(reg 17) (const_int 0)])
13550 (const_int 0))
13551 (label_ref (match_operand 1 "" ""))
13552 (pc)))]
13553 ""
13554 [(set (pc)
13555 (if_then_else (match_dup 0)
13556 (label_ref (match_dup 1))
13557 (pc)))]
13558 {
13559 rtx new_op0 = copy_rtx (operands[0]);
13560 operands[0] = new_op0;
13561 PUT_MODE (new_op0, VOIDmode);
13562 PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13563 GET_MODE (XEXP (new_op0, 0))));
13564
13565 /* Make sure that (a) the CCmode we have for the flags is strong
13566 enough for the reversed compare or (b) we have a valid FP compare. */
13567 if (! ix86_comparison_operator (new_op0, VOIDmode))
13568 FAIL;
13569 })
13570
13571 ;; Define combination compare-and-branch fp compare instructions to use
13572 ;; during early optimization. Splitting the operation apart early makes
13573 ;; for bad code when we want to reverse the operation.
13574
13575 (define_insn "*fp_jcc_1"
13576 [(set (pc)
13577 (if_then_else (match_operator 0 "comparison_operator"
13578 [(match_operand 1 "register_operand" "f")
13579 (match_operand 2 "register_operand" "f")])
13580 (label_ref (match_operand 3 "" ""))
13581 (pc)))
13582 (clobber (reg:CCFP 18))
13583 (clobber (reg:CCFP 17))]
13584 "TARGET_CMOVE && TARGET_80387
13585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13586 && FLOAT_MODE_P (GET_MODE (operands[1]))
13587 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13588 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13589 "#")
13590
13591 (define_insn "*fp_jcc_1_sse"
13592 [(set (pc)
13593 (if_then_else (match_operator 0 "comparison_operator"
13594 [(match_operand 1 "register_operand" "f#x,x#f")
13595 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13596 (label_ref (match_operand 3 "" ""))
13597 (pc)))
13598 (clobber (reg:CCFP 18))
13599 (clobber (reg:CCFP 17))]
13600 "TARGET_80387
13601 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13602 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13603 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13604 "#")
13605
13606 (define_insn "*fp_jcc_1_sse_only"
13607 [(set (pc)
13608 (if_then_else (match_operator 0 "comparison_operator"
13609 [(match_operand 1 "register_operand" "x")
13610 (match_operand 2 "nonimmediate_operand" "xm")])
13611 (label_ref (match_operand 3 "" ""))
13612 (pc)))
13613 (clobber (reg:CCFP 18))
13614 (clobber (reg:CCFP 17))]
13615 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13616 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13617 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13618 "#")
13619
13620 (define_insn "*fp_jcc_2"
13621 [(set (pc)
13622 (if_then_else (match_operator 0 "comparison_operator"
13623 [(match_operand 1 "register_operand" "f")
13624 (match_operand 2 "register_operand" "f")])
13625 (pc)
13626 (label_ref (match_operand 3 "" ""))))
13627 (clobber (reg:CCFP 18))
13628 (clobber (reg:CCFP 17))]
13629 "TARGET_CMOVE && TARGET_80387
13630 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13631 && FLOAT_MODE_P (GET_MODE (operands[1]))
13632 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13633 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13634 "#")
13635
13636 (define_insn "*fp_jcc_2_sse"
13637 [(set (pc)
13638 (if_then_else (match_operator 0 "comparison_operator"
13639 [(match_operand 1 "register_operand" "f#x,x#f")
13640 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13641 (pc)
13642 (label_ref (match_operand 3 "" ""))))
13643 (clobber (reg:CCFP 18))
13644 (clobber (reg:CCFP 17))]
13645 "TARGET_80387
13646 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13647 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13648 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13649 "#")
13650
13651 (define_insn "*fp_jcc_2_sse_only"
13652 [(set (pc)
13653 (if_then_else (match_operator 0 "comparison_operator"
13654 [(match_operand 1 "register_operand" "x")
13655 (match_operand 2 "nonimmediate_operand" "xm")])
13656 (pc)
13657 (label_ref (match_operand 3 "" ""))))
13658 (clobber (reg:CCFP 18))
13659 (clobber (reg:CCFP 17))]
13660 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13661 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13662 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13663 "#")
13664
13665 (define_insn "*fp_jcc_3"
13666 [(set (pc)
13667 (if_then_else (match_operator 0 "comparison_operator"
13668 [(match_operand 1 "register_operand" "f")
13669 (match_operand 2 "nonimmediate_operand" "fm")])
13670 (label_ref (match_operand 3 "" ""))
13671 (pc)))
13672 (clobber (reg:CCFP 18))
13673 (clobber (reg:CCFP 17))
13674 (clobber (match_scratch:HI 4 "=a"))]
13675 "TARGET_80387
13676 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13677 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13678 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13679 && SELECT_CC_MODE (GET_CODE (operands[0]),
13680 operands[1], operands[2]) == CCFPmode
13681 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13682 "#")
13683
13684 (define_insn "*fp_jcc_4"
13685 [(set (pc)
13686 (if_then_else (match_operator 0 "comparison_operator"
13687 [(match_operand 1 "register_operand" "f")
13688 (match_operand 2 "nonimmediate_operand" "fm")])
13689 (pc)
13690 (label_ref (match_operand 3 "" ""))))
13691 (clobber (reg:CCFP 18))
13692 (clobber (reg:CCFP 17))
13693 (clobber (match_scratch:HI 4 "=a"))]
13694 "TARGET_80387
13695 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13696 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13697 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13698 && SELECT_CC_MODE (GET_CODE (operands[0]),
13699 operands[1], operands[2]) == CCFPmode
13700 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13701 "#")
13702
13703 (define_insn "*fp_jcc_5"
13704 [(set (pc)
13705 (if_then_else (match_operator 0 "comparison_operator"
13706 [(match_operand 1 "register_operand" "f")
13707 (match_operand 2 "register_operand" "f")])
13708 (label_ref (match_operand 3 "" ""))
13709 (pc)))
13710 (clobber (reg:CCFP 18))
13711 (clobber (reg:CCFP 17))
13712 (clobber (match_scratch:HI 4 "=a"))]
13713 "TARGET_80387
13714 && FLOAT_MODE_P (GET_MODE (operands[1]))
13715 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13716 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13717 "#")
13718
13719 (define_insn "*fp_jcc_6"
13720 [(set (pc)
13721 (if_then_else (match_operator 0 "comparison_operator"
13722 [(match_operand 1 "register_operand" "f")
13723 (match_operand 2 "register_operand" "f")])
13724 (pc)
13725 (label_ref (match_operand 3 "" ""))))
13726 (clobber (reg:CCFP 18))
13727 (clobber (reg:CCFP 17))
13728 (clobber (match_scratch:HI 4 "=a"))]
13729 "TARGET_80387
13730 && FLOAT_MODE_P (GET_MODE (operands[1]))
13731 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13732 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13733 "#")
13734
13735 (define_split
13736 [(set (pc)
13737 (if_then_else (match_operator 0 "comparison_operator"
13738 [(match_operand 1 "register_operand" "")
13739 (match_operand 2 "nonimmediate_operand" "")])
13740 (match_operand 3 "" "")
13741 (match_operand 4 "" "")))
13742 (clobber (reg:CCFP 18))
13743 (clobber (reg:CCFP 17))]
13744 "reload_completed"
13745 [(const_int 0)]
13746 {
13747 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13748 operands[3], operands[4], NULL_RTX);
13749 DONE;
13750 })
13751
13752 (define_split
13753 [(set (pc)
13754 (if_then_else (match_operator 0 "comparison_operator"
13755 [(match_operand 1 "register_operand" "")
13756 (match_operand 2 "nonimmediate_operand" "")])
13757 (match_operand 3 "" "")
13758 (match_operand 4 "" "")))
13759 (clobber (reg:CCFP 18))
13760 (clobber (reg:CCFP 17))
13761 (clobber (match_scratch:HI 5 "=a"))]
13762 "reload_completed"
13763 [(set (pc)
13764 (if_then_else (match_dup 6)
13765 (match_dup 3)
13766 (match_dup 4)))]
13767 {
13768 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13769 operands[3], operands[4], operands[5]);
13770 DONE;
13771 })
13772 \f
13773 ;; Unconditional and other jump instructions
13774
13775 (define_insn "jump"
13776 [(set (pc)
13777 (label_ref (match_operand 0 "" "")))]
13778 ""
13779 "jmp\t%l0"
13780 [(set_attr "type" "ibr")
13781 (set (attr "length")
13782 (if_then_else (and (ge (minus (match_dup 0) (pc))
13783 (const_int -126))
13784 (lt (minus (match_dup 0) (pc))
13785 (const_int 128)))
13786 (const_int 2)
13787 (const_int 5)))
13788 (set_attr "modrm" "0")])
13789
13790 (define_expand "indirect_jump"
13791 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13792 ""
13793 "")
13794
13795 (define_insn "*indirect_jump"
13796 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13797 "!TARGET_64BIT"
13798 "jmp\t%A0"
13799 [(set_attr "type" "ibr")
13800 (set_attr "length_immediate" "0")])
13801
13802 (define_insn "*indirect_jump_rtx64"
13803 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13804 "TARGET_64BIT"
13805 "jmp\t%A0"
13806 [(set_attr "type" "ibr")
13807 (set_attr "length_immediate" "0")])
13808
13809 (define_expand "tablejump"
13810 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13811 (use (label_ref (match_operand 1 "" "")))])]
13812 ""
13813 {
13814 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13815 relative. Convert the relative address to an absolute address. */
13816 if (flag_pic)
13817 {
13818 rtx op0, op1;
13819 enum rtx_code code;
13820
13821 if (TARGET_64BIT)
13822 {
13823 code = PLUS;
13824 op0 = operands[0];
13825 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13826 }
13827 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13828 {
13829 code = PLUS;
13830 op0 = operands[0];
13831 op1 = pic_offset_table_rtx;
13832 }
13833 else
13834 {
13835 code = MINUS;
13836 op0 = pic_offset_table_rtx;
13837 op1 = operands[0];
13838 }
13839
13840 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13841 OPTAB_DIRECT);
13842 }
13843 })
13844
13845 (define_insn "*tablejump_1"
13846 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13847 (use (label_ref (match_operand 1 "" "")))]
13848 "!TARGET_64BIT"
13849 "jmp\t%A0"
13850 [(set_attr "type" "ibr")
13851 (set_attr "length_immediate" "0")])
13852
13853 (define_insn "*tablejump_1_rtx64"
13854 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13855 (use (label_ref (match_operand 1 "" "")))]
13856 "TARGET_64BIT"
13857 "jmp\t%A0"
13858 [(set_attr "type" "ibr")
13859 (set_attr "length_immediate" "0")])
13860 \f
13861 ;; Loop instruction
13862 ;;
13863 ;; This is all complicated by the fact that since this is a jump insn
13864 ;; we must handle our own reloads.
13865
13866 (define_expand "doloop_end"
13867 [(use (match_operand 0 "" "")) ; loop pseudo
13868 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13869 (use (match_operand 2 "" "")) ; max iterations
13870 (use (match_operand 3 "" "")) ; loop level
13871 (use (match_operand 4 "" ""))] ; label
13872 "!TARGET_64BIT && TARGET_USE_LOOP"
13873 "
13874 {
13875 /* Only use cloop on innermost loops. */
13876 if (INTVAL (operands[3]) > 1)
13877 FAIL;
13878 if (GET_MODE (operands[0]) != SImode)
13879 FAIL;
13880 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13881 operands[0]));
13882 DONE;
13883 }")
13884
13885 (define_insn "doloop_end_internal"
13886 [(set (pc)
13887 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13888 (const_int 1))
13889 (label_ref (match_operand 0 "" ""))
13890 (pc)))
13891 (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13892 (plus:SI (match_dup 1)
13893 (const_int -1)))
13894 (clobber (match_scratch:SI 3 "=X,X,r"))
13895 (clobber (reg:CC 17))]
13896 "!TARGET_64BIT && TARGET_USE_LOOP"
13897 {
13898 if (which_alternative != 0)
13899 return "#";
13900 if (get_attr_length (insn) == 2)
13901 return "%+loop\t%l0";
13902 else
13903 return "dec{l}\t%1\;%+jne\t%l0";
13904 }
13905 [(set_attr "ppro_uops" "many")
13906 (set (attr "length")
13907 (if_then_else (and (eq_attr "alternative" "0")
13908 (and (ge (minus (match_dup 0) (pc))
13909 (const_int -126))
13910 (lt (minus (match_dup 0) (pc))
13911 (const_int 128))))
13912 (const_int 2)
13913 (const_int 16)))
13914 ;; We don't know the type before shorten branches. Optimistically expect
13915 ;; the loop instruction to match.
13916 (set (attr "type") (const_string "ibr"))])
13917
13918 (define_split
13919 [(set (pc)
13920 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13921 (const_int 1))
13922 (match_operand 0 "" "")
13923 (pc)))
13924 (set (match_dup 1)
13925 (plus:SI (match_dup 1)
13926 (const_int -1)))
13927 (clobber (match_scratch:SI 2 ""))
13928 (clobber (reg:CC 17))]
13929 "!TARGET_64BIT && TARGET_USE_LOOP
13930 && reload_completed
13931 && REGNO (operands[1]) != 2"
13932 [(parallel [(set (reg:CCZ 17)
13933 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13934 (const_int 0)))
13935 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13936 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13937 (match_dup 0)
13938 (pc)))]
13939 "")
13940
13941 (define_split
13942 [(set (pc)
13943 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13944 (const_int 1))
13945 (match_operand 0 "" "")
13946 (pc)))
13947 (set (match_operand:SI 2 "nonimmediate_operand" "")
13948 (plus:SI (match_dup 1)
13949 (const_int -1)))
13950 (clobber (match_scratch:SI 3 ""))
13951 (clobber (reg:CC 17))]
13952 "!TARGET_64BIT && TARGET_USE_LOOP
13953 && reload_completed
13954 && (! REG_P (operands[2])
13955 || ! rtx_equal_p (operands[1], operands[2]))"
13956 [(set (match_dup 3) (match_dup 1))
13957 (parallel [(set (reg:CCZ 17)
13958 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13959 (const_int 0)))
13960 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13961 (set (match_dup 2) (match_dup 3))
13962 (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13963 (match_dup 0)
13964 (pc)))]
13965 "")
13966
13967 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13968
13969 (define_peephole2
13970 [(set (reg 17) (match_operand 0 "" ""))
13971 (set (match_operand:QI 1 "register_operand" "")
13972 (match_operator:QI 2 "ix86_comparison_operator"
13973 [(reg 17) (const_int 0)]))
13974 (set (match_operand 3 "q_regs_operand" "")
13975 (zero_extend (match_dup 1)))]
13976 "(peep2_reg_dead_p (3, operands[1])
13977 || operands_match_p (operands[1], operands[3]))
13978 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13979 [(set (match_dup 4) (match_dup 0))
13980 (set (strict_low_part (match_dup 5))
13981 (match_dup 2))]
13982 {
13983 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13984 operands[5] = gen_lowpart (QImode, operands[3]);
13985 ix86_expand_clear (operands[3]);
13986 })
13987
13988 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13989
13990 (define_peephole2
13991 [(set (reg 17) (match_operand 0 "" ""))
13992 (set (match_operand:QI 1 "register_operand" "")
13993 (match_operator:QI 2 "ix86_comparison_operator"
13994 [(reg 17) (const_int 0)]))
13995 (parallel [(set (match_operand 3 "q_regs_operand" "")
13996 (zero_extend (match_dup 1)))
13997 (clobber (reg:CC 17))])]
13998 "(peep2_reg_dead_p (3, operands[1])
13999 || operands_match_p (operands[1], operands[3]))
14000 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14001 [(set (match_dup 4) (match_dup 0))
14002 (set (strict_low_part (match_dup 5))
14003 (match_dup 2))]
14004 {
14005 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
14006 operands[5] = gen_lowpart (QImode, operands[3]);
14007 ix86_expand_clear (operands[3]);
14008 })
14009 \f
14010 ;; Call instructions.
14011
14012 ;; The predicates normally associated with named expanders are not properly
14013 ;; checked for calls. This is a bug in the generic code, but it isn't that
14014 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14015
14016 ;; Call subroutine returning no value.
14017
14018 (define_expand "call_pop"
14019 [(parallel [(call (match_operand:QI 0 "" "")
14020 (match_operand:SI 1 "" ""))
14021 (set (reg:SI 7)
14022 (plus:SI (reg:SI 7)
14023 (match_operand:SI 3 "" "")))])]
14024 "!TARGET_64BIT"
14025 {
14026 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14027 DONE;
14028 })
14029
14030 (define_insn "*call_pop_0"
14031 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14032 (match_operand:SI 1 "" ""))
14033 (set (reg:SI 7) (plus:SI (reg:SI 7)
14034 (match_operand:SI 2 "immediate_operand" "")))]
14035 "!TARGET_64BIT"
14036 {
14037 if (SIBLING_CALL_P (insn))
14038 return "jmp\t%P0";
14039 else
14040 return "call\t%P0";
14041 }
14042 [(set_attr "type" "call")])
14043
14044 (define_insn "*call_pop_1"
14045 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14046 (match_operand:SI 1 "" ""))
14047 (set (reg:SI 7) (plus:SI (reg:SI 7)
14048 (match_operand:SI 2 "immediate_operand" "i")))]
14049 "!TARGET_64BIT"
14050 {
14051 if (constant_call_address_operand (operands[0], Pmode))
14052 {
14053 if (SIBLING_CALL_P (insn))
14054 return "jmp\t%P0";
14055 else
14056 return "call\t%P0";
14057 }
14058 if (SIBLING_CALL_P (insn))
14059 return "jmp\t%A0";
14060 else
14061 return "call\t%A0";
14062 }
14063 [(set_attr "type" "call")])
14064
14065 (define_expand "call"
14066 [(call (match_operand:QI 0 "" "")
14067 (match_operand 1 "" ""))
14068 (use (match_operand 2 "" ""))]
14069 ""
14070 {
14071 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14072 DONE;
14073 })
14074
14075 (define_expand "sibcall"
14076 [(call (match_operand:QI 0 "" "")
14077 (match_operand 1 "" ""))
14078 (use (match_operand 2 "" ""))]
14079 ""
14080 {
14081 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14082 DONE;
14083 })
14084
14085 (define_insn "*call_0"
14086 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14087 (match_operand 1 "" ""))]
14088 ""
14089 {
14090 if (SIBLING_CALL_P (insn))
14091 return "jmp\t%P0";
14092 else
14093 return "call\t%P0";
14094 }
14095 [(set_attr "type" "call")])
14096
14097 (define_insn "*call_1"
14098 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14099 (match_operand 1 "" ""))]
14100 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14101 {
14102 if (constant_call_address_operand (operands[0], QImode))
14103 return "call\t%P0";
14104 return "call\t%A0";
14105 }
14106 [(set_attr "type" "call")])
14107
14108 (define_insn "*sibcall_1"
14109 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14110 (match_operand 1 "" ""))]
14111 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14112 {
14113 if (constant_call_address_operand (operands[0], QImode))
14114 return "jmp\t%P0";
14115 return "jmp\t%A0";
14116 }
14117 [(set_attr "type" "call")])
14118
14119 (define_insn "*call_1_rex64"
14120 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14121 (match_operand 1 "" ""))]
14122 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14123 {
14124 if (constant_call_address_operand (operands[0], QImode))
14125 return "call\t%P0";
14126 return "call\t%A0";
14127 }
14128 [(set_attr "type" "call")])
14129
14130 (define_insn "*sibcall_1_rex64"
14131 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14132 (match_operand 1 "" ""))]
14133 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14134 "jmp\t%P0"
14135 [(set_attr "type" "call")])
14136
14137 (define_insn "*sibcall_1_rex64_v"
14138 [(call (mem:QI (reg:DI 40))
14139 (match_operand 0 "" ""))]
14140 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14141 "jmp\t*%%r11"
14142 [(set_attr "type" "call")])
14143
14144
14145 ;; Call subroutine, returning value in operand 0
14146
14147 (define_expand "call_value_pop"
14148 [(parallel [(set (match_operand 0 "" "")
14149 (call (match_operand:QI 1 "" "")
14150 (match_operand:SI 2 "" "")))
14151 (set (reg:SI 7)
14152 (plus:SI (reg:SI 7)
14153 (match_operand:SI 4 "" "")))])]
14154 "!TARGET_64BIT"
14155 {
14156 ix86_expand_call (operands[0], operands[1], operands[2],
14157 operands[3], operands[4], 0);
14158 DONE;
14159 })
14160
14161 (define_expand "call_value"
14162 [(set (match_operand 0 "" "")
14163 (call (match_operand:QI 1 "" "")
14164 (match_operand:SI 2 "" "")))
14165 (use (match_operand:SI 3 "" ""))]
14166 ;; Operand 2 not used on the i386.
14167 ""
14168 {
14169 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14170 DONE;
14171 })
14172
14173 (define_expand "sibcall_value"
14174 [(set (match_operand 0 "" "")
14175 (call (match_operand:QI 1 "" "")
14176 (match_operand:SI 2 "" "")))
14177 (use (match_operand:SI 3 "" ""))]
14178 ;; Operand 2 not used on the i386.
14179 ""
14180 {
14181 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14182 DONE;
14183 })
14184
14185 ;; Call subroutine returning any type.
14186
14187 (define_expand "untyped_call"
14188 [(parallel [(call (match_operand 0 "" "")
14189 (const_int 0))
14190 (match_operand 1 "" "")
14191 (match_operand 2 "" "")])]
14192 ""
14193 {
14194 int i;
14195
14196 /* In order to give reg-stack an easier job in validating two
14197 coprocessor registers as containing a possible return value,
14198 simply pretend the untyped call returns a complex long double
14199 value. */
14200
14201 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14202 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14203 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14204 NULL, 0);
14205
14206 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14207 {
14208 rtx set = XVECEXP (operands[2], 0, i);
14209 emit_move_insn (SET_DEST (set), SET_SRC (set));
14210 }
14211
14212 /* The optimizer does not know that the call sets the function value
14213 registers we stored in the result block. We avoid problems by
14214 claiming that all hard registers are used and clobbered at this
14215 point. */
14216 emit_insn (gen_blockage (const0_rtx));
14217
14218 DONE;
14219 })
14220 \f
14221 ;; Prologue and epilogue instructions
14222
14223 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14224 ;; all of memory. This blocks insns from being moved across this point.
14225
14226 (define_insn "blockage"
14227 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14228 ""
14229 ""
14230 [(set_attr "length" "0")])
14231
14232 ;; Insn emitted into the body of a function to return from a function.
14233 ;; This is only done if the function's epilogue is known to be simple.
14234 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14235
14236 (define_expand "return"
14237 [(return)]
14238 "ix86_can_use_return_insn_p ()"
14239 {
14240 if (current_function_pops_args)
14241 {
14242 rtx popc = GEN_INT (current_function_pops_args);
14243 emit_jump_insn (gen_return_pop_internal (popc));
14244 DONE;
14245 }
14246 })
14247
14248 (define_insn "return_internal"
14249 [(return)]
14250 "reload_completed"
14251 "ret"
14252 [(set_attr "length" "1")
14253 (set_attr "length_immediate" "0")
14254 (set_attr "modrm" "0")])
14255
14256 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14257 ;; instruction Athlon and K8 have.
14258
14259 (define_insn "return_internal_long"
14260 [(return)
14261 (unspec [(const_int 0)] UNSPEC_REP)]
14262 "reload_completed"
14263 "rep {;} ret"
14264 [(set_attr "length" "1")
14265 (set_attr "length_immediate" "0")
14266 (set_attr "prefix_rep" "1")
14267 (set_attr "modrm" "0")])
14268
14269 (define_insn "return_pop_internal"
14270 [(return)
14271 (use (match_operand:SI 0 "const_int_operand" ""))]
14272 "reload_completed"
14273 "ret\t%0"
14274 [(set_attr "length" "3")
14275 (set_attr "length_immediate" "2")
14276 (set_attr "modrm" "0")])
14277
14278 (define_insn "return_indirect_internal"
14279 [(return)
14280 (use (match_operand:SI 0 "register_operand" "r"))]
14281 "reload_completed"
14282 "jmp\t%A0"
14283 [(set_attr "type" "ibr")
14284 (set_attr "length_immediate" "0")])
14285
14286 (define_insn "nop"
14287 [(const_int 0)]
14288 ""
14289 "nop"
14290 [(set_attr "length" "1")
14291 (set_attr "length_immediate" "0")
14292 (set_attr "modrm" "0")
14293 (set_attr "ppro_uops" "one")])
14294
14295 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14296 ;; branch prediction penalty for the third jump in a 16-byte
14297 ;; block on K8.
14298
14299 (define_insn "align"
14300 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14301 ""
14302 {
14303 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14304 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14305 #else
14306 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14307 The align insn is used to avoid 3 jump instructions in the row to improve
14308 branch prediction and the benefits hardly outweight the cost of extra 8
14309 nops on the average inserted by full alignment pseudo operation. */
14310 #endif
14311 return "";
14312 }
14313 [(set_attr "length" "16")])
14314
14315 (define_expand "prologue"
14316 [(const_int 1)]
14317 ""
14318 "ix86_expand_prologue (); DONE;")
14319
14320 (define_insn "set_got"
14321 [(set (match_operand:SI 0 "register_operand" "=r")
14322 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14323 (clobber (reg:CC 17))]
14324 "!TARGET_64BIT"
14325 { return output_set_got (operands[0]); }
14326 [(set_attr "type" "multi")
14327 (set_attr "length" "12")])
14328
14329 (define_expand "epilogue"
14330 [(const_int 1)]
14331 ""
14332 "ix86_expand_epilogue (1); DONE;")
14333
14334 (define_expand "sibcall_epilogue"
14335 [(const_int 1)]
14336 ""
14337 "ix86_expand_epilogue (0); DONE;")
14338
14339 (define_expand "eh_return"
14340 [(use (match_operand 0 "register_operand" ""))]
14341 ""
14342 {
14343 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14344
14345 /* Tricky bit: we write the address of the handler to which we will
14346 be returning into someone else's stack frame, one word below the
14347 stack address we wish to restore. */
14348 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14349 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14350 tmp = gen_rtx_MEM (Pmode, tmp);
14351 emit_move_insn (tmp, ra);
14352
14353 if (Pmode == SImode)
14354 emit_insn (gen_eh_return_si (sa));
14355 else
14356 emit_insn (gen_eh_return_di (sa));
14357 emit_barrier ();
14358 DONE;
14359 })
14360
14361 (define_insn_and_split "eh_return_si"
14362 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14363 UNSPECV_EH_RETURN)]
14364 "!TARGET_64BIT"
14365 "#"
14366 "reload_completed"
14367 [(const_int 1)]
14368 "ix86_expand_epilogue (2); DONE;")
14369
14370 (define_insn_and_split "eh_return_di"
14371 [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14372 UNSPECV_EH_RETURN)]
14373 "TARGET_64BIT"
14374 "#"
14375 "reload_completed"
14376 [(const_int 1)]
14377 "ix86_expand_epilogue (2); DONE;")
14378
14379 (define_insn "leave"
14380 [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14381 (set (reg:SI 6) (mem:SI (reg:SI 6)))
14382 (clobber (mem:BLK (scratch)))]
14383 "!TARGET_64BIT"
14384 "leave"
14385 [(set_attr "type" "leave")])
14386
14387 (define_insn "leave_rex64"
14388 [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14389 (set (reg:DI 6) (mem:DI (reg:DI 6)))
14390 (clobber (mem:BLK (scratch)))]
14391 "TARGET_64BIT"
14392 "leave"
14393 [(set_attr "type" "leave")])
14394 \f
14395 (define_expand "ffssi2"
14396 [(parallel
14397 [(set (match_operand:SI 0 "register_operand" "")
14398 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14399 (clobber (match_scratch:SI 2 ""))
14400 (clobber (reg:CC 17))])]
14401 ""
14402 "")
14403
14404 (define_insn_and_split "*ffs_cmove"
14405 [(set (match_operand:SI 0 "register_operand" "=r")
14406 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14407 (clobber (match_scratch:SI 2 "=&r"))
14408 (clobber (reg:CC 17))]
14409 "TARGET_CMOVE"
14410 "#"
14411 "&& reload_completed"
14412 [(set (match_dup 2) (const_int -1))
14413 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14414 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14415 (set (match_dup 0) (if_then_else:SI
14416 (eq (reg:CCZ 17) (const_int 0))
14417 (match_dup 2)
14418 (match_dup 0)))
14419 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14420 (clobber (reg:CC 17))])]
14421 "")
14422
14423 (define_insn_and_split "*ffs_no_cmove"
14424 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14425 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14426 (clobber (match_scratch:SI 2 "=&r"))
14427 (clobber (reg:CC 17))]
14428 ""
14429 "#"
14430 "reload_completed"
14431 [(parallel [(set (match_dup 2) (const_int 0))
14432 (clobber (reg:CC 17))])
14433 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14434 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14435 (set (strict_low_part (match_dup 3))
14436 (eq:QI (reg:CCZ 17) (const_int 0)))
14437 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14438 (clobber (reg:CC 17))])
14439 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14440 (clobber (reg:CC 17))])
14441 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14442 (clobber (reg:CC 17))])]
14443 {
14444 operands[3] = gen_lowpart (QImode, operands[2]);
14445 })
14446
14447 (define_insn "*ffssi_1"
14448 [(set (reg:CCZ 17)
14449 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14450 (const_int 0)))
14451 (set (match_operand:SI 0 "register_operand" "=r")
14452 (ctz:SI (match_dup 1)))]
14453 ""
14454 "bsf{l}\t{%1, %0|%0, %1}"
14455 [(set_attr "prefix_0f" "1")
14456 (set_attr "ppro_uops" "few")])
14457
14458 (define_insn "ctzsi2"
14459 [(set (match_operand:SI 0 "register_operand" "=r")
14460 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14461 (clobber (reg:CC 17))]
14462 ""
14463 "bsf{l}\t{%1, %0|%0, %1}"
14464 [(set_attr "prefix_0f" "1")
14465 (set_attr "ppro_uops" "few")])
14466
14467 (define_expand "clzsi2"
14468 [(parallel
14469 [(set (match_operand:SI 0 "register_operand" "")
14470 (minus:SI (const_int 31)
14471 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14472 (clobber (reg:CC 17))])
14473 (parallel
14474 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14475 (clobber (reg:CC 17))])]
14476 ""
14477 "")
14478
14479 (define_insn "*bsr"
14480 [(set (match_operand:SI 0 "register_operand" "=r")
14481 (minus:SI (const_int 31)
14482 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14483 (clobber (reg:CC 17))]
14484 ""
14485 "bsr{l}\t{%1, %0|%0, %1}"
14486 [(set_attr "prefix_0f" "1")
14487 (set_attr "ppro_uops" "few")])
14488 \f
14489 ;; Thread-local storage patterns for ELF.
14490 ;;
14491 ;; Note that these code sequences must appear exactly as shown
14492 ;; in order to allow linker relaxation.
14493
14494 (define_insn "*tls_global_dynamic_32_gnu"
14495 [(set (match_operand:SI 0 "register_operand" "=a")
14496 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14497 (match_operand:SI 2 "tls_symbolic_operand" "")
14498 (match_operand:SI 3 "call_insn_operand" "")]
14499 UNSPEC_TLS_GD))
14500 (clobber (match_scratch:SI 4 "=d"))
14501 (clobber (match_scratch:SI 5 "=c"))
14502 (clobber (reg:CC 17))]
14503 "!TARGET_64BIT && TARGET_GNU_TLS"
14504 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14505 [(set_attr "type" "multi")
14506 (set_attr "length" "12")])
14507
14508 (define_insn "*tls_global_dynamic_32_sun"
14509 [(set (match_operand:SI 0 "register_operand" "=a")
14510 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14511 (match_operand:SI 2 "tls_symbolic_operand" "")
14512 (match_operand:SI 3 "call_insn_operand" "")]
14513 UNSPEC_TLS_GD))
14514 (clobber (match_scratch:SI 4 "=d"))
14515 (clobber (match_scratch:SI 5 "=c"))
14516 (clobber (reg:CC 17))]
14517 "!TARGET_64BIT && TARGET_SUN_TLS"
14518 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14519 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14520 [(set_attr "type" "multi")
14521 (set_attr "length" "14")])
14522
14523 (define_expand "tls_global_dynamic_32"
14524 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14525 (unspec:SI
14526 [(match_dup 2)
14527 (match_operand:SI 1 "tls_symbolic_operand" "")
14528 (match_dup 3)]
14529 UNSPEC_TLS_GD))
14530 (clobber (match_scratch:SI 4 ""))
14531 (clobber (match_scratch:SI 5 ""))
14532 (clobber (reg:CC 17))])]
14533 ""
14534 {
14535 if (flag_pic)
14536 operands[2] = pic_offset_table_rtx;
14537 else
14538 {
14539 operands[2] = gen_reg_rtx (Pmode);
14540 emit_insn (gen_set_got (operands[2]));
14541 }
14542 operands[3] = ix86_tls_get_addr ();
14543 })
14544
14545 (define_insn "*tls_global_dynamic_64"
14546 [(set (match_operand:DI 0 "register_operand" "=a")
14547 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14548 (match_operand:DI 3 "" "")))
14549 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14550 UNSPEC_TLS_GD)]
14551 "TARGET_64BIT"
14552 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14553 [(set_attr "type" "multi")
14554 (set_attr "length" "16")])
14555
14556 (define_expand "tls_global_dynamic_64"
14557 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14558 (call (mem:QI (match_dup 2)) (const_int 0)))
14559 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14560 UNSPEC_TLS_GD)])]
14561 ""
14562 {
14563 operands[2] = ix86_tls_get_addr ();
14564 })
14565
14566 (define_insn "*tls_local_dynamic_base_32_gnu"
14567 [(set (match_operand:SI 0 "register_operand" "=a")
14568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14569 (match_operand:SI 2 "call_insn_operand" "")]
14570 UNSPEC_TLS_LD_BASE))
14571 (clobber (match_scratch:SI 3 "=d"))
14572 (clobber (match_scratch:SI 4 "=c"))
14573 (clobber (reg:CC 17))]
14574 "!TARGET_64BIT && TARGET_GNU_TLS"
14575 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14576 [(set_attr "type" "multi")
14577 (set_attr "length" "11")])
14578
14579 (define_insn "*tls_local_dynamic_base_32_sun"
14580 [(set (match_operand:SI 0 "register_operand" "=a")
14581 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14582 (match_operand:SI 2 "call_insn_operand" "")]
14583 UNSPEC_TLS_LD_BASE))
14584 (clobber (match_scratch:SI 3 "=d"))
14585 (clobber (match_scratch:SI 4 "=c"))
14586 (clobber (reg:CC 17))]
14587 "!TARGET_64BIT && TARGET_SUN_TLS"
14588 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14589 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14590 [(set_attr "type" "multi")
14591 (set_attr "length" "13")])
14592
14593 (define_expand "tls_local_dynamic_base_32"
14594 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14595 (unspec:SI [(match_dup 1) (match_dup 2)]
14596 UNSPEC_TLS_LD_BASE))
14597 (clobber (match_scratch:SI 3 ""))
14598 (clobber (match_scratch:SI 4 ""))
14599 (clobber (reg:CC 17))])]
14600 ""
14601 {
14602 if (flag_pic)
14603 operands[1] = pic_offset_table_rtx;
14604 else
14605 {
14606 operands[1] = gen_reg_rtx (Pmode);
14607 emit_insn (gen_set_got (operands[1]));
14608 }
14609 operands[2] = ix86_tls_get_addr ();
14610 })
14611
14612 (define_insn "*tls_local_dynamic_base_64"
14613 [(set (match_operand:DI 0 "register_operand" "=a")
14614 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14615 (match_operand:DI 2 "" "")))
14616 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14617 "TARGET_64BIT"
14618 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14619 [(set_attr "type" "multi")
14620 (set_attr "length" "12")])
14621
14622 (define_expand "tls_local_dynamic_base_64"
14623 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14624 (call (mem:QI (match_dup 1)) (const_int 0)))
14625 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14626 ""
14627 {
14628 operands[1] = ix86_tls_get_addr ();
14629 })
14630
14631 ;; Local dynamic of a single variable is a lose. Show combine how
14632 ;; to convert that back to global dynamic.
14633
14634 (define_insn_and_split "*tls_local_dynamic_32_once"
14635 [(set (match_operand:SI 0 "register_operand" "=a")
14636 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14637 (match_operand:SI 2 "call_insn_operand" "")]
14638 UNSPEC_TLS_LD_BASE)
14639 (const:SI (unspec:SI
14640 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14641 UNSPEC_DTPOFF))))
14642 (clobber (match_scratch:SI 4 "=d"))
14643 (clobber (match_scratch:SI 5 "=c"))
14644 (clobber (reg:CC 17))]
14645 ""
14646 "#"
14647 ""
14648 [(parallel [(set (match_dup 0)
14649 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14650 UNSPEC_TLS_GD))
14651 (clobber (match_dup 4))
14652 (clobber (match_dup 5))
14653 (clobber (reg:CC 17))])]
14654 "")
14655
14656 ;; Load and add the thread base pointer from %gs:0.
14657
14658 (define_insn "*load_tp_si"
14659 [(set (match_operand:SI 0 "register_operand" "=r")
14660 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14661 "!TARGET_64BIT"
14662 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14663 [(set_attr "type" "imov")
14664 (set_attr "modrm" "0")
14665 (set_attr "length" "7")
14666 (set_attr "memory" "load")
14667 (set_attr "imm_disp" "false")])
14668
14669 (define_insn "*add_tp_si"
14670 [(set (match_operand:SI 0 "register_operand" "=r")
14671 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14672 (match_operand:SI 1 "register_operand" "0")))
14673 (clobber (reg:CC 17))]
14674 "!TARGET_64BIT"
14675 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14676 [(set_attr "type" "alu")
14677 (set_attr "modrm" "0")
14678 (set_attr "length" "7")
14679 (set_attr "memory" "load")
14680 (set_attr "imm_disp" "false")])
14681
14682 (define_insn "*load_tp_di"
14683 [(set (match_operand:DI 0 "register_operand" "=r")
14684 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14685 "TARGET_64BIT"
14686 "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14687 [(set_attr "type" "imov")
14688 (set_attr "modrm" "0")
14689 (set_attr "length" "7")
14690 (set_attr "memory" "load")
14691 (set_attr "imm_disp" "false")])
14692
14693 (define_insn "*add_tp_di"
14694 [(set (match_operand:DI 0 "register_operand" "=r")
14695 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14696 (match_operand:DI 1 "register_operand" "0")))
14697 (clobber (reg:CC 17))]
14698 "TARGET_64BIT"
14699 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14700 [(set_attr "type" "alu")
14701 (set_attr "modrm" "0")
14702 (set_attr "length" "7")
14703 (set_attr "memory" "load")
14704 (set_attr "imm_disp" "false")])
14705 \f
14706 ;; These patterns match the binary 387 instructions for addM3, subM3,
14707 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14708 ;; SFmode. The first is the normal insn, the second the same insn but
14709 ;; with one operand a conversion, and the third the same insn but with
14710 ;; the other operand a conversion. The conversion may be SFmode or
14711 ;; SImode if the target mode DFmode, but only SImode if the target mode
14712 ;; is SFmode.
14713
14714 ;; Gcc is slightly more smart about handling normal two address instructions
14715 ;; so use special patterns for add and mull.
14716 (define_insn "*fop_sf_comm_nosse"
14717 [(set (match_operand:SF 0 "register_operand" "=f")
14718 (match_operator:SF 3 "binary_fp_operator"
14719 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14720 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14721 "TARGET_80387 && !TARGET_SSE_MATH
14722 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14723 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14724 "* return output_387_binary_op (insn, operands);"
14725 [(set (attr "type")
14726 (if_then_else (match_operand:SF 3 "mult_operator" "")
14727 (const_string "fmul")
14728 (const_string "fop")))
14729 (set_attr "mode" "SF")])
14730
14731 (define_insn "*fop_sf_comm"
14732 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14733 (match_operator:SF 3 "binary_fp_operator"
14734 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14735 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14736 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14737 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14738 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14739 "* return output_387_binary_op (insn, operands);"
14740 [(set (attr "type")
14741 (if_then_else (eq_attr "alternative" "1")
14742 (if_then_else (match_operand:SF 3 "mult_operator" "")
14743 (const_string "ssemul")
14744 (const_string "sseadd"))
14745 (if_then_else (match_operand:SF 3 "mult_operator" "")
14746 (const_string "fmul")
14747 (const_string "fop"))))
14748 (set_attr "mode" "SF")])
14749
14750 (define_insn "*fop_sf_comm_sse"
14751 [(set (match_operand:SF 0 "register_operand" "=x")
14752 (match_operator:SF 3 "binary_fp_operator"
14753 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14754 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14755 "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14756 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14757 "* return output_387_binary_op (insn, operands);"
14758 [(set (attr "type")
14759 (if_then_else (match_operand:SF 3 "mult_operator" "")
14760 (const_string "ssemul")
14761 (const_string "sseadd")))
14762 (set_attr "mode" "SF")])
14763
14764 (define_insn "*fop_df_comm_nosse"
14765 [(set (match_operand:DF 0 "register_operand" "=f")
14766 (match_operator:DF 3 "binary_fp_operator"
14767 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14768 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14769 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14770 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14771 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14772 "* return output_387_binary_op (insn, operands);"
14773 [(set (attr "type")
14774 (if_then_else (match_operand:SF 3 "mult_operator" "")
14775 (const_string "fmul")
14776 (const_string "fop")))
14777 (set_attr "mode" "DF")])
14778
14779 (define_insn "*fop_df_comm"
14780 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14781 (match_operator:DF 3 "binary_fp_operator"
14782 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14783 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14784 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14785 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14787 "* return output_387_binary_op (insn, operands);"
14788 [(set (attr "type")
14789 (if_then_else (eq_attr "alternative" "1")
14790 (if_then_else (match_operand:SF 3 "mult_operator" "")
14791 (const_string "ssemul")
14792 (const_string "sseadd"))
14793 (if_then_else (match_operand:SF 3 "mult_operator" "")
14794 (const_string "fmul")
14795 (const_string "fop"))))
14796 (set_attr "mode" "DF")])
14797
14798 (define_insn "*fop_df_comm_sse"
14799 [(set (match_operand:DF 0 "register_operand" "=Y")
14800 (match_operator:DF 3 "binary_fp_operator"
14801 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14802 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14803 "TARGET_SSE2 && TARGET_SSE_MATH
14804 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14805 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14806 "* return output_387_binary_op (insn, operands);"
14807 [(set (attr "type")
14808 (if_then_else (match_operand:SF 3 "mult_operator" "")
14809 (const_string "ssemul")
14810 (const_string "sseadd")))
14811 (set_attr "mode" "DF")])
14812
14813 (define_insn "*fop_xf_comm"
14814 [(set (match_operand:XF 0 "register_operand" "=f")
14815 (match_operator:XF 3 "binary_fp_operator"
14816 [(match_operand:XF 1 "register_operand" "%0")
14817 (match_operand:XF 2 "register_operand" "f")]))]
14818 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14819 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14820 "* return output_387_binary_op (insn, operands);"
14821 [(set (attr "type")
14822 (if_then_else (match_operand:XF 3 "mult_operator" "")
14823 (const_string "fmul")
14824 (const_string "fop")))
14825 (set_attr "mode" "XF")])
14826
14827 (define_insn "*fop_tf_comm"
14828 [(set (match_operand:TF 0 "register_operand" "=f")
14829 (match_operator:TF 3 "binary_fp_operator"
14830 [(match_operand:TF 1 "register_operand" "%0")
14831 (match_operand:TF 2 "register_operand" "f")]))]
14832 "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14833 "* return output_387_binary_op (insn, operands);"
14834 [(set (attr "type")
14835 (if_then_else (match_operand:TF 3 "mult_operator" "")
14836 (const_string "fmul")
14837 (const_string "fop")))
14838 (set_attr "mode" "XF")])
14839
14840 (define_insn "*fop_sf_1_nosse"
14841 [(set (match_operand:SF 0 "register_operand" "=f,f")
14842 (match_operator:SF 3 "binary_fp_operator"
14843 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14844 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14845 "TARGET_80387 && !TARGET_SSE_MATH
14846 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14847 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14848 "* return output_387_binary_op (insn, operands);"
14849 [(set (attr "type")
14850 (cond [(match_operand:SF 3 "mult_operator" "")
14851 (const_string "fmul")
14852 (match_operand:SF 3 "div_operator" "")
14853 (const_string "fdiv")
14854 ]
14855 (const_string "fop")))
14856 (set_attr "mode" "SF")])
14857
14858 (define_insn "*fop_sf_1"
14859 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14860 (match_operator:SF 3 "binary_fp_operator"
14861 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14862 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14863 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14864 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14865 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14866 "* return output_387_binary_op (insn, operands);"
14867 [(set (attr "type")
14868 (cond [(and (eq_attr "alternative" "2")
14869 (match_operand:SF 3 "mult_operator" ""))
14870 (const_string "ssemul")
14871 (and (eq_attr "alternative" "2")
14872 (match_operand:SF 3 "div_operator" ""))
14873 (const_string "ssediv")
14874 (eq_attr "alternative" "2")
14875 (const_string "sseadd")
14876 (match_operand:SF 3 "mult_operator" "")
14877 (const_string "fmul")
14878 (match_operand:SF 3 "div_operator" "")
14879 (const_string "fdiv")
14880 ]
14881 (const_string "fop")))
14882 (set_attr "mode" "SF")])
14883
14884 (define_insn "*fop_sf_1_sse"
14885 [(set (match_operand:SF 0 "register_operand" "=x")
14886 (match_operator:SF 3 "binary_fp_operator"
14887 [(match_operand:SF 1 "register_operand" "0")
14888 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14889 "TARGET_SSE_MATH
14890 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14891 "* return output_387_binary_op (insn, operands);"
14892 [(set (attr "type")
14893 (cond [(match_operand:SF 3 "mult_operator" "")
14894 (const_string "ssemul")
14895 (match_operand:SF 3 "div_operator" "")
14896 (const_string "ssediv")
14897 ]
14898 (const_string "sseadd")))
14899 (set_attr "mode" "SF")])
14900
14901 ;; ??? Add SSE splitters for these!
14902 (define_insn "*fop_sf_2"
14903 [(set (match_operand:SF 0 "register_operand" "=f,f")
14904 (match_operator:SF 3 "binary_fp_operator"
14905 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14906 (match_operand:SF 2 "register_operand" "0,0")]))]
14907 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14909 [(set (attr "type")
14910 (cond [(match_operand:SF 3 "mult_operator" "")
14911 (const_string "fmul")
14912 (match_operand:SF 3 "div_operator" "")
14913 (const_string "fdiv")
14914 ]
14915 (const_string "fop")))
14916 (set_attr "fp_int_src" "true")
14917 (set_attr "ppro_uops" "many")
14918 (set_attr "mode" "SI")])
14919
14920 (define_insn "*fop_sf_3"
14921 [(set (match_operand:SF 0 "register_operand" "=f,f")
14922 (match_operator:SF 3 "binary_fp_operator"
14923 [(match_operand:SF 1 "register_operand" "0,0")
14924 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14925 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14926 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14927 [(set (attr "type")
14928 (cond [(match_operand:SF 3 "mult_operator" "")
14929 (const_string "fmul")
14930 (match_operand:SF 3 "div_operator" "")
14931 (const_string "fdiv")
14932 ]
14933 (const_string "fop")))
14934 (set_attr "fp_int_src" "true")
14935 (set_attr "ppro_uops" "many")
14936 (set_attr "mode" "SI")])
14937
14938 (define_insn "*fop_df_1_nosse"
14939 [(set (match_operand:DF 0 "register_operand" "=f,f")
14940 (match_operator:DF 3 "binary_fp_operator"
14941 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14942 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14943 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14944 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14945 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14946 "* return output_387_binary_op (insn, operands);"
14947 [(set (attr "type")
14948 (cond [(match_operand:DF 3 "mult_operator" "")
14949 (const_string "fmul")
14950 (match_operand:DF 3 "div_operator" "")
14951 (const_string "fdiv")
14952 ]
14953 (const_string "fop")))
14954 (set_attr "mode" "DF")])
14955
14956
14957 (define_insn "*fop_df_1"
14958 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14959 (match_operator:DF 3 "binary_fp_operator"
14960 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14961 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14962 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14963 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14964 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14965 "* return output_387_binary_op (insn, operands);"
14966 [(set (attr "type")
14967 (cond [(and (eq_attr "alternative" "2")
14968 (match_operand:SF 3 "mult_operator" ""))
14969 (const_string "ssemul")
14970 (and (eq_attr "alternative" "2")
14971 (match_operand:SF 3 "div_operator" ""))
14972 (const_string "ssediv")
14973 (eq_attr "alternative" "2")
14974 (const_string "sseadd")
14975 (match_operand:DF 3 "mult_operator" "")
14976 (const_string "fmul")
14977 (match_operand:DF 3 "div_operator" "")
14978 (const_string "fdiv")
14979 ]
14980 (const_string "fop")))
14981 (set_attr "mode" "DF")])
14982
14983 (define_insn "*fop_df_1_sse"
14984 [(set (match_operand:DF 0 "register_operand" "=Y")
14985 (match_operator:DF 3 "binary_fp_operator"
14986 [(match_operand:DF 1 "register_operand" "0")
14987 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14988 "TARGET_SSE2 && TARGET_SSE_MATH
14989 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14990 "* return output_387_binary_op (insn, operands);"
14991 [(set_attr "mode" "DF")
14992 (set (attr "type")
14993 (cond [(match_operand:SF 3 "mult_operator" "")
14994 (const_string "ssemul")
14995 (match_operand:SF 3 "div_operator" "")
14996 (const_string "ssediv")
14997 ]
14998 (const_string "sseadd")))])
14999
15000 ;; ??? Add SSE splitters for these!
15001 (define_insn "*fop_df_2"
15002 [(set (match_operand:DF 0 "register_operand" "=f,f")
15003 (match_operator:DF 3 "binary_fp_operator"
15004 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15005 (match_operand:DF 2 "register_operand" "0,0")]))]
15006 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15007 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15008 [(set (attr "type")
15009 (cond [(match_operand:DF 3 "mult_operator" "")
15010 (const_string "fmul")
15011 (match_operand:DF 3 "div_operator" "")
15012 (const_string "fdiv")
15013 ]
15014 (const_string "fop")))
15015 (set_attr "fp_int_src" "true")
15016 (set_attr "ppro_uops" "many")
15017 (set_attr "mode" "SI")])
15018
15019 (define_insn "*fop_df_3"
15020 [(set (match_operand:DF 0 "register_operand" "=f,f")
15021 (match_operator:DF 3 "binary_fp_operator"
15022 [(match_operand:DF 1 "register_operand" "0,0")
15023 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15024 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15025 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15026 [(set (attr "type")
15027 (cond [(match_operand:DF 3 "mult_operator" "")
15028 (const_string "fmul")
15029 (match_operand:DF 3 "div_operator" "")
15030 (const_string "fdiv")
15031 ]
15032 (const_string "fop")))
15033 (set_attr "fp_int_src" "true")
15034 (set_attr "ppro_uops" "many")
15035 (set_attr "mode" "SI")])
15036
15037 (define_insn "*fop_df_4"
15038 [(set (match_operand:DF 0 "register_operand" "=f,f")
15039 (match_operator:DF 3 "binary_fp_operator"
15040 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15041 (match_operand:DF 2 "register_operand" "0,f")]))]
15042 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15043 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15044 "* return output_387_binary_op (insn, operands);"
15045 [(set (attr "type")
15046 (cond [(match_operand:DF 3 "mult_operator" "")
15047 (const_string "fmul")
15048 (match_operand:DF 3 "div_operator" "")
15049 (const_string "fdiv")
15050 ]
15051 (const_string "fop")))
15052 (set_attr "mode" "SF")])
15053
15054 (define_insn "*fop_df_5"
15055 [(set (match_operand:DF 0 "register_operand" "=f,f")
15056 (match_operator:DF 3 "binary_fp_operator"
15057 [(match_operand:DF 1 "register_operand" "0,f")
15058 (float_extend:DF
15059 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15060 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15061 "* return output_387_binary_op (insn, operands);"
15062 [(set (attr "type")
15063 (cond [(match_operand:DF 3 "mult_operator" "")
15064 (const_string "fmul")
15065 (match_operand:DF 3 "div_operator" "")
15066 (const_string "fdiv")
15067 ]
15068 (const_string "fop")))
15069 (set_attr "mode" "SF")])
15070
15071 (define_insn "*fop_df_6"
15072 [(set (match_operand:DF 0 "register_operand" "=f,f")
15073 (match_operator:DF 3 "binary_fp_operator"
15074 [(float_extend:DF
15075 (match_operand:SF 1 "register_operand" "0,f"))
15076 (float_extend:DF
15077 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15078 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15079 "* return output_387_binary_op (insn, operands);"
15080 [(set (attr "type")
15081 (cond [(match_operand:DF 3 "mult_operator" "")
15082 (const_string "fmul")
15083 (match_operand:DF 3 "div_operator" "")
15084 (const_string "fdiv")
15085 ]
15086 (const_string "fop")))
15087 (set_attr "mode" "SF")])
15088
15089 (define_insn "*fop_xf_1"
15090 [(set (match_operand:XF 0 "register_operand" "=f,f")
15091 (match_operator:XF 3 "binary_fp_operator"
15092 [(match_operand:XF 1 "register_operand" "0,f")
15093 (match_operand:XF 2 "register_operand" "f,0")]))]
15094 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15095 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15096 "* return output_387_binary_op (insn, operands);"
15097 [(set (attr "type")
15098 (cond [(match_operand:XF 3 "mult_operator" "")
15099 (const_string "fmul")
15100 (match_operand:XF 3 "div_operator" "")
15101 (const_string "fdiv")
15102 ]
15103 (const_string "fop")))
15104 (set_attr "mode" "XF")])
15105
15106 (define_insn "*fop_tf_1"
15107 [(set (match_operand:TF 0 "register_operand" "=f,f")
15108 (match_operator:TF 3 "binary_fp_operator"
15109 [(match_operand:TF 1 "register_operand" "0,f")
15110 (match_operand:TF 2 "register_operand" "f,0")]))]
15111 "TARGET_80387
15112 && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15113 "* return output_387_binary_op (insn, operands);"
15114 [(set (attr "type")
15115 (cond [(match_operand:TF 3 "mult_operator" "")
15116 (const_string "fmul")
15117 (match_operand:TF 3 "div_operator" "")
15118 (const_string "fdiv")
15119 ]
15120 (const_string "fop")))
15121 (set_attr "mode" "XF")])
15122
15123 (define_insn "*fop_xf_2"
15124 [(set (match_operand:XF 0 "register_operand" "=f,f")
15125 (match_operator:XF 3 "binary_fp_operator"
15126 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15127 (match_operand:XF 2 "register_operand" "0,0")]))]
15128 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15129 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15130 [(set (attr "type")
15131 (cond [(match_operand:XF 3 "mult_operator" "")
15132 (const_string "fmul")
15133 (match_operand:XF 3 "div_operator" "")
15134 (const_string "fdiv")
15135 ]
15136 (const_string "fop")))
15137 (set_attr "fp_int_src" "true")
15138 (set_attr "mode" "SI")
15139 (set_attr "ppro_uops" "many")])
15140
15141 (define_insn "*fop_tf_2"
15142 [(set (match_operand:TF 0 "register_operand" "=f,f")
15143 (match_operator:TF 3 "binary_fp_operator"
15144 [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15145 (match_operand:TF 2 "register_operand" "0,0")]))]
15146 "TARGET_80387 && TARGET_USE_FIOP"
15147 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15148 [(set (attr "type")
15149 (cond [(match_operand:TF 3 "mult_operator" "")
15150 (const_string "fmul")
15151 (match_operand:TF 3 "div_operator" "")
15152 (const_string "fdiv")
15153 ]
15154 (const_string "fop")))
15155 (set_attr "fp_int_src" "true")
15156 (set_attr "mode" "SI")
15157 (set_attr "ppro_uops" "many")])
15158
15159 (define_insn "*fop_xf_3"
15160 [(set (match_operand:XF 0 "register_operand" "=f,f")
15161 (match_operator:XF 3 "binary_fp_operator"
15162 [(match_operand:XF 1 "register_operand" "0,0")
15163 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15164 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15165 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15166 [(set (attr "type")
15167 (cond [(match_operand:XF 3 "mult_operator" "")
15168 (const_string "fmul")
15169 (match_operand:XF 3 "div_operator" "")
15170 (const_string "fdiv")
15171 ]
15172 (const_string "fop")))
15173 (set_attr "fp_int_src" "true")
15174 (set_attr "mode" "SI")
15175 (set_attr "ppro_uops" "many")])
15176
15177 (define_insn "*fop_tf_3"
15178 [(set (match_operand:TF 0 "register_operand" "=f,f")
15179 (match_operator:TF 3 "binary_fp_operator"
15180 [(match_operand:TF 1 "register_operand" "0,0")
15181 (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15182 "TARGET_80387 && TARGET_USE_FIOP"
15183 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15184 [(set (attr "type")
15185 (cond [(match_operand:TF 3 "mult_operator" "")
15186 (const_string "fmul")
15187 (match_operand:TF 3 "div_operator" "")
15188 (const_string "fdiv")
15189 ]
15190 (const_string "fop")))
15191 (set_attr "fp_int_src" "true")
15192 (set_attr "mode" "SI")
15193 (set_attr "ppro_uops" "many")])
15194
15195 (define_insn "*fop_xf_4"
15196 [(set (match_operand:XF 0 "register_operand" "=f,f")
15197 (match_operator:XF 3 "binary_fp_operator"
15198 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15199 (match_operand:XF 2 "register_operand" "0,f")]))]
15200 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15201 "* return output_387_binary_op (insn, operands);"
15202 [(set (attr "type")
15203 (cond [(match_operand:XF 3 "mult_operator" "")
15204 (const_string "fmul")
15205 (match_operand:XF 3 "div_operator" "")
15206 (const_string "fdiv")
15207 ]
15208 (const_string "fop")))
15209 (set_attr "mode" "SF")])
15210
15211 (define_insn "*fop_tf_4"
15212 [(set (match_operand:TF 0 "register_operand" "=f,f")
15213 (match_operator:TF 3 "binary_fp_operator"
15214 [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15215 (match_operand:TF 2 "register_operand" "0,f")]))]
15216 "TARGET_80387"
15217 "* return output_387_binary_op (insn, operands);"
15218 [(set (attr "type")
15219 (cond [(match_operand:TF 3 "mult_operator" "")
15220 (const_string "fmul")
15221 (match_operand:TF 3 "div_operator" "")
15222 (const_string "fdiv")
15223 ]
15224 (const_string "fop")))
15225 (set_attr "mode" "SF")])
15226
15227 (define_insn "*fop_xf_5"
15228 [(set (match_operand:XF 0 "register_operand" "=f,f")
15229 (match_operator:XF 3 "binary_fp_operator"
15230 [(match_operand:XF 1 "register_operand" "0,f")
15231 (float_extend:XF
15232 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15233 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15234 "* return output_387_binary_op (insn, operands);"
15235 [(set (attr "type")
15236 (cond [(match_operand:XF 3 "mult_operator" "")
15237 (const_string "fmul")
15238 (match_operand:XF 3 "div_operator" "")
15239 (const_string "fdiv")
15240 ]
15241 (const_string "fop")))
15242 (set_attr "mode" "SF")])
15243
15244 (define_insn "*fop_tf_5"
15245 [(set (match_operand:TF 0 "register_operand" "=f,f")
15246 (match_operator:TF 3 "binary_fp_operator"
15247 [(match_operand:TF 1 "register_operand" "0,f")
15248 (float_extend:TF
15249 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15250 "TARGET_80387"
15251 "* return output_387_binary_op (insn, operands);"
15252 [(set (attr "type")
15253 (cond [(match_operand:TF 3 "mult_operator" "")
15254 (const_string "fmul")
15255 (match_operand:TF 3 "div_operator" "")
15256 (const_string "fdiv")
15257 ]
15258 (const_string "fop")))
15259 (set_attr "mode" "SF")])
15260
15261 (define_insn "*fop_xf_6"
15262 [(set (match_operand:XF 0 "register_operand" "=f,f")
15263 (match_operator:XF 3 "binary_fp_operator"
15264 [(float_extend:XF
15265 (match_operand 1 "register_operand" "0,f"))
15266 (float_extend:XF
15267 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15268 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15269 "* return output_387_binary_op (insn, operands);"
15270 [(set (attr "type")
15271 (cond [(match_operand:XF 3 "mult_operator" "")
15272 (const_string "fmul")
15273 (match_operand:XF 3 "div_operator" "")
15274 (const_string "fdiv")
15275 ]
15276 (const_string "fop")))
15277 (set_attr "mode" "SF")])
15278
15279 (define_insn "*fop_tf_6"
15280 [(set (match_operand:TF 0 "register_operand" "=f,f")
15281 (match_operator:TF 3 "binary_fp_operator"
15282 [(float_extend:TF
15283 (match_operand 1 "register_operand" "0,f"))
15284 (float_extend:TF
15285 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15286 "TARGET_80387"
15287 "* return output_387_binary_op (insn, operands);"
15288 [(set (attr "type")
15289 (cond [(match_operand:TF 3 "mult_operator" "")
15290 (const_string "fmul")
15291 (match_operand:TF 3 "div_operator" "")
15292 (const_string "fdiv")
15293 ]
15294 (const_string "fop")))
15295 (set_attr "mode" "SF")])
15296
15297 (define_split
15298 [(set (match_operand 0 "register_operand" "")
15299 (match_operator 3 "binary_fp_operator"
15300 [(float (match_operand:SI 1 "register_operand" ""))
15301 (match_operand 2 "register_operand" "")]))]
15302 "TARGET_80387 && reload_completed
15303 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15304 [(const_int 0)]
15305 {
15306 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15307 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15308 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15309 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15310 GET_MODE (operands[3]),
15311 operands[4],
15312 operands[2])));
15313 ix86_free_from_memory (GET_MODE (operands[1]));
15314 DONE;
15315 })
15316
15317 (define_split
15318 [(set (match_operand 0 "register_operand" "")
15319 (match_operator 3 "binary_fp_operator"
15320 [(match_operand 1 "register_operand" "")
15321 (float (match_operand:SI 2 "register_operand" ""))]))]
15322 "TARGET_80387 && reload_completed
15323 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15324 [(const_int 0)]
15325 {
15326 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15327 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15328 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15329 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15330 GET_MODE (operands[3]),
15331 operands[1],
15332 operands[4])));
15333 ix86_free_from_memory (GET_MODE (operands[2]));
15334 DONE;
15335 })
15336 \f
15337 ;; FPU special functions.
15338
15339 (define_expand "sqrtsf2"
15340 [(set (match_operand:SF 0 "register_operand" "")
15341 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15342 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15343 {
15344 if (!TARGET_SSE_MATH)
15345 operands[1] = force_reg (SFmode, operands[1]);
15346 })
15347
15348 (define_insn "sqrtsf2_1"
15349 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15350 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15351 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15352 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15353 "@
15354 fsqrt
15355 sqrtss\t{%1, %0|%0, %1}"
15356 [(set_attr "type" "fpspc,sse")
15357 (set_attr "mode" "SF,SF")
15358 (set_attr "athlon_decode" "direct,*")])
15359
15360 (define_insn "sqrtsf2_1_sse_only"
15361 [(set (match_operand:SF 0 "register_operand" "=x")
15362 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15363 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15364 "sqrtss\t{%1, %0|%0, %1}"
15365 [(set_attr "type" "sse")
15366 (set_attr "mode" "SF")
15367 (set_attr "athlon_decode" "*")])
15368
15369 (define_insn "sqrtsf2_i387"
15370 [(set (match_operand:SF 0 "register_operand" "=f")
15371 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15372 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15373 && !TARGET_SSE_MATH"
15374 "fsqrt"
15375 [(set_attr "type" "fpspc")
15376 (set_attr "mode" "SF")
15377 (set_attr "athlon_decode" "direct")])
15378
15379 (define_expand "sqrtdf2"
15380 [(set (match_operand:DF 0 "register_operand" "")
15381 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15382 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15383 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15384 {
15385 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15386 operands[1] = force_reg (DFmode, operands[1]);
15387 })
15388
15389 (define_insn "sqrtdf2_1"
15390 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15391 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15392 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15393 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15394 "@
15395 fsqrt
15396 sqrtsd\t{%1, %0|%0, %1}"
15397 [(set_attr "type" "fpspc,sse")
15398 (set_attr "mode" "DF,DF")
15399 (set_attr "athlon_decode" "direct,*")])
15400
15401 (define_insn "sqrtdf2_1_sse_only"
15402 [(set (match_operand:DF 0 "register_operand" "=Y")
15403 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15404 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15405 "sqrtsd\t{%1, %0|%0, %1}"
15406 [(set_attr "type" "sse")
15407 (set_attr "mode" "DF")
15408 (set_attr "athlon_decode" "*")])
15409
15410 (define_insn "sqrtdf2_i387"
15411 [(set (match_operand:DF 0 "register_operand" "=f")
15412 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15413 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15414 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15415 "fsqrt"
15416 [(set_attr "type" "fpspc")
15417 (set_attr "mode" "DF")
15418 (set_attr "athlon_decode" "direct")])
15419
15420 (define_insn "*sqrtextendsfdf2"
15421 [(set (match_operand:DF 0 "register_operand" "=f")
15422 (sqrt:DF (float_extend:DF
15423 (match_operand:SF 1 "register_operand" "0"))))]
15424 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15425 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15426 "fsqrt"
15427 [(set_attr "type" "fpspc")
15428 (set_attr "mode" "DF")
15429 (set_attr "athlon_decode" "direct")])
15430
15431 (define_insn "sqrtxf2"
15432 [(set (match_operand:XF 0 "register_operand" "=f")
15433 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15434 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15435 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15436 "fsqrt"
15437 [(set_attr "type" "fpspc")
15438 (set_attr "mode" "XF")
15439 (set_attr "athlon_decode" "direct")])
15440
15441 (define_insn "sqrttf2"
15442 [(set (match_operand:TF 0 "register_operand" "=f")
15443 (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15444 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15445 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15446 "fsqrt"
15447 [(set_attr "type" "fpspc")
15448 (set_attr "mode" "XF")
15449 (set_attr "athlon_decode" "direct")])
15450
15451 (define_insn "*sqrtextenddfxf2"
15452 [(set (match_operand:XF 0 "register_operand" "=f")
15453 (sqrt:XF (float_extend:XF
15454 (match_operand:DF 1 "register_operand" "0"))))]
15455 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15456 "fsqrt"
15457 [(set_attr "type" "fpspc")
15458 (set_attr "mode" "XF")
15459 (set_attr "athlon_decode" "direct")])
15460
15461 (define_insn "*sqrtextenddftf2"
15462 [(set (match_operand:TF 0 "register_operand" "=f")
15463 (sqrt:TF (float_extend:TF
15464 (match_operand:DF 1 "register_operand" "0"))))]
15465 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15466 "fsqrt"
15467 [(set_attr "type" "fpspc")
15468 (set_attr "mode" "XF")
15469 (set_attr "athlon_decode" "direct")])
15470
15471 (define_insn "*sqrtextendsfxf2"
15472 [(set (match_operand:XF 0 "register_operand" "=f")
15473 (sqrt:XF (float_extend:XF
15474 (match_operand:SF 1 "register_operand" "0"))))]
15475 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15476 "fsqrt"
15477 [(set_attr "type" "fpspc")
15478 (set_attr "mode" "XF")
15479 (set_attr "athlon_decode" "direct")])
15480
15481 (define_insn "*sqrtextendsftf2"
15482 [(set (match_operand:TF 0 "register_operand" "=f")
15483 (sqrt:TF (float_extend:TF
15484 (match_operand:SF 1 "register_operand" "0"))))]
15485 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15486 "fsqrt"
15487 [(set_attr "type" "fpspc")
15488 (set_attr "mode" "XF")
15489 (set_attr "athlon_decode" "direct")])
15490
15491 (define_insn "sindf2"
15492 [(set (match_operand:DF 0 "register_operand" "=f")
15493 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15494 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15495 && flag_unsafe_math_optimizations"
15496 "fsin"
15497 [(set_attr "type" "fpspc")
15498 (set_attr "mode" "DF")])
15499
15500 (define_insn "sinsf2"
15501 [(set (match_operand:SF 0 "register_operand" "=f")
15502 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15503 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15504 && flag_unsafe_math_optimizations"
15505 "fsin"
15506 [(set_attr "type" "fpspc")
15507 (set_attr "mode" "SF")])
15508
15509 (define_insn "*sinextendsfdf2"
15510 [(set (match_operand:DF 0 "register_operand" "=f")
15511 (unspec:DF [(float_extend:DF
15512 (match_operand:SF 1 "register_operand" "0"))]
15513 UNSPEC_SIN))]
15514 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15515 && flag_unsafe_math_optimizations"
15516 "fsin"
15517 [(set_attr "type" "fpspc")
15518 (set_attr "mode" "DF")])
15519
15520 (define_insn "sinxf2"
15521 [(set (match_operand:XF 0 "register_operand" "=f")
15522 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15523 "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15524 && flag_unsafe_math_optimizations"
15525 "fsin"
15526 [(set_attr "type" "fpspc")
15527 (set_attr "mode" "XF")])
15528
15529 (define_insn "sintf2"
15530 [(set (match_operand:TF 0 "register_operand" "=f")
15531 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15532 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15533 && flag_unsafe_math_optimizations"
15534 "fsin"
15535 [(set_attr "type" "fpspc")
15536 (set_attr "mode" "XF")])
15537
15538 (define_insn "cosdf2"
15539 [(set (match_operand:DF 0 "register_operand" "=f")
15540 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15541 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15542 && flag_unsafe_math_optimizations"
15543 "fcos"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "DF")])
15546
15547 (define_insn "cossf2"
15548 [(set (match_operand:SF 0 "register_operand" "=f")
15549 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15550 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15551 && flag_unsafe_math_optimizations"
15552 "fcos"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "mode" "SF")])
15555
15556 (define_insn "*cosextendsfdf2"
15557 [(set (match_operand:DF 0 "register_operand" "=f")
15558 (unspec:DF [(float_extend:DF
15559 (match_operand:SF 1 "register_operand" "0"))]
15560 UNSPEC_COS))]
15561 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15562 && flag_unsafe_math_optimizations"
15563 "fcos"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "DF")])
15566
15567 (define_insn "cosxf2"
15568 [(set (match_operand:XF 0 "register_operand" "=f")
15569 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15570 "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15571 && flag_unsafe_math_optimizations"
15572 "fcos"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "XF")])
15575
15576 (define_insn "costf2"
15577 [(set (match_operand:TF 0 "register_operand" "=f")
15578 (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15579 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15580 && flag_unsafe_math_optimizations"
15581 "fcos"
15582 [(set_attr "type" "fpspc")
15583 (set_attr "mode" "XF")])
15584
15585 (define_insn "atan2df3"
15586 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15587 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15588 (match_operand:DF 1 "register_operand" "u")]
15589 UNSPEC_FPATAN))
15590 (clobber (match_dup 1))])]
15591 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15592 && flag_unsafe_math_optimizations"
15593 "fpatan"
15594 [(set_attr "type" "fpspc")
15595 (set_attr "mode" "DF")])
15596
15597 (define_insn "atan2sf3"
15598 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15599 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15600 (match_operand:SF 1 "register_operand" "u")]
15601 UNSPEC_FPATAN))
15602 (clobber (match_dup 1))])]
15603 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15604 && flag_unsafe_math_optimizations"
15605 "fpatan"
15606 [(set_attr "type" "fpspc")
15607 (set_attr "mode" "SF")])
15608
15609 (define_insn "atan2xf3"
15610 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15611 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15612 (match_operand:XF 1 "register_operand" "u")]
15613 UNSPEC_FPATAN))
15614 (clobber (match_dup 1))])]
15615 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15616 && flag_unsafe_math_optimizations"
15617 "fpatan"
15618 [(set_attr "type" "fpspc")
15619 (set_attr "mode" "XF")])
15620
15621 (define_insn "atan2tf3"
15622 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15623 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15624 (match_operand:TF 1 "register_operand" "u")]
15625 UNSPEC_FPATAN))
15626 (clobber (match_dup 1))])]
15627 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15628 && flag_unsafe_math_optimizations"
15629 "fpatan"
15630 [(set_attr "type" "fpspc")
15631 (set_attr "mode" "XF")])
15632
15633 (define_insn "*fyl2x_sfxf3"
15634 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15635 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15636 (match_operand:XF 1 "register_operand" "u")]
15637 UNSPEC_FYL2X))
15638 (clobber (match_dup 1))])]
15639 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15640 && flag_unsafe_math_optimizations"
15641 "fyl2x"
15642 [(set_attr "type" "fpspc")
15643 (set_attr "mode" "SF")])
15644
15645 (define_insn "*fyl2x_dfxf3"
15646 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15647 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15648 (match_operand:XF 1 "register_operand" "u")]
15649 UNSPEC_FYL2X))
15650 (clobber (match_dup 1))])]
15651 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15652 && flag_unsafe_math_optimizations"
15653 "fyl2x"
15654 [(set_attr "type" "fpspc")
15655 (set_attr "mode" "DF")])
15656
15657 (define_insn "*fyl2x_xf3"
15658 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15659 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15660 (match_operand:XF 1 "register_operand" "u")]
15661 UNSPEC_FYL2X))
15662 (clobber (match_dup 1))])]
15663 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15664 && flag_unsafe_math_optimizations"
15665 "fyl2x"
15666 [(set_attr "type" "fpspc")
15667 (set_attr "mode" "XF")])
15668
15669 (define_insn "*fyl2x_tfxf3"
15670 [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15671 (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15672 (match_operand:XF 1 "register_operand" "u")]
15673 UNSPEC_FYL2X))
15674 (clobber (match_dup 1))])]
15675 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15676 && flag_unsafe_math_optimizations"
15677 "fyl2x"
15678 [(set_attr "type" "fpspc")
15679 (set_attr "mode" "XF")])
15680
15681 (define_expand "logsf2"
15682 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15683 (unspec:SF [(match_operand:SF 1 "register_operand" "")
15684 (match_dup 2)] UNSPEC_FYL2X))
15685 (clobber (match_dup 2))])]
15686 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15687 && flag_unsafe_math_optimizations"
15688 {
15689 rtx temp;
15690
15691 operands[2] = gen_reg_rtx (XFmode);
15692 temp = standard_80387_constant_rtx (4); /* fldln2 */
15693 emit_move_insn (operands[2], temp);
15694 })
15695
15696 (define_expand "logdf2"
15697 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15698 (unspec:DF [(match_operand:DF 1 "register_operand" "")
15699 (match_dup 2)] UNSPEC_FYL2X))
15700 (clobber (match_dup 2))])]
15701 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15702 && flag_unsafe_math_optimizations"
15703 {
15704 rtx temp;
15705
15706 operands[2] = gen_reg_rtx (XFmode);
15707 temp = standard_80387_constant_rtx (4); /* fldln2 */
15708 emit_move_insn (operands[2], temp);
15709 })
15710
15711 (define_expand "logxf2"
15712 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15713 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15714 (match_dup 2)] UNSPEC_FYL2X))
15715 (clobber (match_dup 2))])]
15716 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15717 && flag_unsafe_math_optimizations"
15718 {
15719 rtx temp;
15720
15721 operands[2] = gen_reg_rtx (XFmode);
15722 temp = standard_80387_constant_rtx (4); /* fldln2 */
15723 emit_move_insn (operands[2], temp);
15724 })
15725
15726 (define_expand "logtf2"
15727 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15728 (unspec:TF [(match_operand:TF 1 "register_operand" "")
15729 (match_dup 2)] UNSPEC_FYL2X))
15730 (clobber (match_dup 2))])]
15731 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15732 && flag_unsafe_math_optimizations"
15733 {
15734 rtx temp;
15735
15736 operands[2] = gen_reg_rtx (XFmode);
15737 temp = standard_80387_constant_rtx (4); /* fldln2 */
15738 emit_move_insn (operands[2], temp);
15739 })
15740
15741 (define_insn "*fscale_sfxf3"
15742 [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15743 (unspec:SF [(match_operand:XF 2 "register_operand" "0")
15744 (match_operand:XF 1 "register_operand" "u")]
15745 UNSPEC_FSCALE))
15746 (clobber (match_dup 1))])]
15747 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15748 && flag_unsafe_math_optimizations"
15749 "fscale\;fstp\t%y1"
15750 [(set_attr "type" "fpspc")
15751 (set_attr "mode" "SF")])
15752
15753 (define_insn "*fscale_dfxf3"
15754 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15755 (unspec:DF [(match_operand:XF 2 "register_operand" "0")
15756 (match_operand:XF 1 "register_operand" "u")]
15757 UNSPEC_FSCALE))
15758 (clobber (match_dup 1))])]
15759 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15760 && flag_unsafe_math_optimizations"
15761 "fscale\;fstp\t%y1"
15762 [(set_attr "type" "fpspc")
15763 (set_attr "mode" "DF")])
15764
15765 (define_insn "*fscale_xf3"
15766 [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15767 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15768 (match_operand:XF 1 "register_operand" "u")]
15769 UNSPEC_FSCALE))
15770 (clobber (match_dup 1))])]
15771 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15772 && flag_unsafe_math_optimizations"
15773 "fscale\;fstp\t%y1"
15774 [(set_attr "type" "fpspc")
15775 (set_attr "mode" "XF")])
15776
15777 (define_insn "*frndintxf2"
15778 [(set (match_operand:XF 0 "register_operand" "=f")
15779 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15780 UNSPEC_FRNDINT))]
15781 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15782 && flag_unsafe_math_optimizations"
15783 "frndint"
15784 [(set_attr "type" "fpspc")
15785 (set_attr "mode" "XF")])
15786
15787 (define_insn "*f2xm1xf2"
15788 [(set (match_operand:XF 0 "register_operand" "=f")
15789 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15790 UNSPEC_F2XM1))]
15791 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15792 && flag_unsafe_math_optimizations"
15793 "f2xm1"
15794 [(set_attr "type" "fpspc")
15795 (set_attr "mode" "XF")])
15796
15797 (define_expand "expsf2"
15798 [(set (match_dup 2)
15799 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15800 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15801 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15802 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15803 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15804 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15805 (parallel [(set (match_operand:SF 0 "register_operand" "")
15806 (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15807 (clobber (match_dup 5))])]
15808 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15809 && flag_unsafe_math_optimizations"
15810 {
15811 rtx temp;
15812 int i;
15813
15814 for (i=2; i<10; i++)
15815 operands[i] = gen_reg_rtx (XFmode);
15816 temp = standard_80387_constant_rtx (5); /* fldl2e */
15817 emit_move_insn (operands[3], temp);
15818 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15819 })
15820
15821 (define_expand "expdf2"
15822 [(set (match_dup 2)
15823 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15824 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15825 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15826 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15827 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15828 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15829 (parallel [(set (match_operand:DF 0 "register_operand" "")
15830 (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
15831 (clobber (match_dup 5))])]
15832 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15833 && flag_unsafe_math_optimizations"
15834 {
15835 rtx temp;
15836 int i;
15837
15838 for (i=2; i<10; i++)
15839 operands[i] = gen_reg_rtx (XFmode);
15840 temp = standard_80387_constant_rtx (5); /* fldl2e */
15841 emit_move_insn (operands[3], temp);
15842 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15843 })
15844
15845 (define_expand "expxf2"
15846 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15847 (match_dup 2)))
15848 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15849 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15850 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15851 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15852 (parallel [(set (match_operand:XF 0 "register_operand" "")
15853 (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
15854 (clobber (match_dup 4))])]
15855 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15856 && flag_unsafe_math_optimizations"
15857 {
15858 rtx temp;
15859 int i;
15860
15861 for (i=2; i<9; i++)
15862 operands[i] = gen_reg_rtx (XFmode);
15863 temp = standard_80387_constant_rtx (5); /* fldl2e */
15864 emit_move_insn (operands[2], temp);
15865 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15866 })
15867
15868 (define_expand "atansf2"
15869 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15870 (unspec:SF [(match_dup 2)
15871 (match_operand:SF 1 "register_operand" "")]
15872 UNSPEC_FPATAN))
15873 (clobber (match_dup 1))])]
15874 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15875 && flag_unsafe_math_optimizations"
15876 {
15877 operands[2] = gen_reg_rtx (SFmode);
15878 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15879 })
15880
15881 (define_expand "atandf2"
15882 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15883 (unspec:DF [(match_dup 2)
15884 (match_operand:DF 1 "register_operand" "")]
15885 UNSPEC_FPATAN))
15886 (clobber (match_dup 1))])]
15887 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15888 && flag_unsafe_math_optimizations"
15889 {
15890 operands[2] = gen_reg_rtx (DFmode);
15891 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15892 })
15893
15894 (define_expand "atanxf2"
15895 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15896 (unspec:XF [(match_dup 2)
15897 (match_operand:XF 1 "register_operand" "")]
15898 UNSPEC_FPATAN))
15899 (clobber (match_dup 1))])]
15900 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15901 && flag_unsafe_math_optimizations"
15902 {
15903 operands[2] = gen_reg_rtx (XFmode);
15904 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15905 })
15906
15907 (define_expand "atantf2"
15908 [(parallel [(set (match_operand:TF 0 "register_operand" "")
15909 (unspec:TF [(match_dup 2)
15910 (match_operand:TF 1 "register_operand" "")]
15911 UNSPEC_FPATAN))
15912 (clobber (match_dup 1))])]
15913 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15914 && flag_unsafe_math_optimizations"
15915 {
15916 operands[2] = gen_reg_rtx (TFmode);
15917 emit_move_insn (operands[2], CONST1_RTX (TFmode)); /* fld1 */
15918 })
15919 \f
15920 ;; Block operation instructions
15921
15922 (define_insn "cld"
15923 [(set (reg:SI 19) (const_int 0))]
15924 ""
15925 "cld"
15926 [(set_attr "type" "cld")])
15927
15928 (define_expand "movstrsi"
15929 [(use (match_operand:BLK 0 "memory_operand" ""))
15930 (use (match_operand:BLK 1 "memory_operand" ""))
15931 (use (match_operand:SI 2 "nonmemory_operand" ""))
15932 (use (match_operand:SI 3 "const_int_operand" ""))]
15933 ""
15934 {
15935 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15936 DONE;
15937 else
15938 FAIL;
15939 })
15940
15941 (define_expand "movstrdi"
15942 [(use (match_operand:BLK 0 "memory_operand" ""))
15943 (use (match_operand:BLK 1 "memory_operand" ""))
15944 (use (match_operand:DI 2 "nonmemory_operand" ""))
15945 (use (match_operand:DI 3 "const_int_operand" ""))]
15946 "TARGET_64BIT"
15947 {
15948 if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15949 DONE;
15950 else
15951 FAIL;
15952 })
15953
15954 ;; Most CPUs don't like single string operations
15955 ;; Handle this case here to simplify previous expander.
15956
15957 (define_expand "strmovdi_rex64"
15958 [(set (match_dup 2)
15959 (mem:DI (match_operand:DI 1 "register_operand" "")))
15960 (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15961 (match_dup 2))
15962 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15963 (clobber (reg:CC 17))])
15964 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15965 (clobber (reg:CC 17))])]
15966 "TARGET_64BIT"
15967 {
15968 if (TARGET_SINGLE_STRINGOP || optimize_size)
15969 {
15970 emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15971 operands[1]));
15972 DONE;
15973 }
15974 else
15975 operands[2] = gen_reg_rtx (DImode);
15976 })
15977
15978
15979 (define_expand "strmovsi"
15980 [(set (match_dup 2)
15981 (mem:SI (match_operand:SI 1 "register_operand" "")))
15982 (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15983 (match_dup 2))
15984 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15985 (clobber (reg:CC 17))])
15986 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15987 (clobber (reg:CC 17))])]
15988 ""
15989 {
15990 if (TARGET_64BIT)
15991 {
15992 emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15993 DONE;
15994 }
15995 if (TARGET_SINGLE_STRINGOP || optimize_size)
15996 {
15997 emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15998 operands[1]));
15999 DONE;
16000 }
16001 else
16002 operands[2] = gen_reg_rtx (SImode);
16003 })
16004
16005 (define_expand "strmovsi_rex64"
16006 [(set (match_dup 2)
16007 (mem:SI (match_operand:DI 1 "register_operand" "")))
16008 (set (mem:SI (match_operand:DI 0 "register_operand" ""))
16009 (match_dup 2))
16010 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16011 (clobber (reg:CC 17))])
16012 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
16013 (clobber (reg:CC 17))])]
16014 "TARGET_64BIT"
16015 {
16016 if (TARGET_SINGLE_STRINGOP || optimize_size)
16017 {
16018 emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
16019 operands[1]));
16020 DONE;
16021 }
16022 else
16023 operands[2] = gen_reg_rtx (SImode);
16024 })
16025
16026 (define_expand "strmovhi"
16027 [(set (match_dup 2)
16028 (mem:HI (match_operand:SI 1 "register_operand" "")))
16029 (set (mem:HI (match_operand:SI 0 "register_operand" ""))
16030 (match_dup 2))
16031 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16032 (clobber (reg:CC 17))])
16033 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
16034 (clobber (reg:CC 17))])]
16035 ""
16036 {
16037 if (TARGET_64BIT)
16038 {
16039 emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
16040 DONE;
16041 }
16042 if (TARGET_SINGLE_STRINGOP || optimize_size)
16043 {
16044 emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
16045 operands[1]));
16046 DONE;
16047 }
16048 else
16049 operands[2] = gen_reg_rtx (HImode);
16050 })
16051
16052 (define_expand "strmovhi_rex64"
16053 [(set (match_dup 2)
16054 (mem:HI (match_operand:DI 1 "register_operand" "")))
16055 (set (mem:HI (match_operand:DI 0 "register_operand" ""))
16056 (match_dup 2))
16057 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16058 (clobber (reg:CC 17))])
16059 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
16060 (clobber (reg:CC 17))])]
16061 "TARGET_64BIT"
16062 {
16063 if (TARGET_SINGLE_STRINGOP || optimize_size)
16064 {
16065 emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
16066 operands[1]));
16067 DONE;
16068 }
16069 else
16070 operands[2] = gen_reg_rtx (HImode);
16071 })
16072
16073 (define_expand "strmovqi"
16074 [(set (match_dup 2)
16075 (mem:QI (match_operand:SI 1 "register_operand" "")))
16076 (set (mem:QI (match_operand:SI 0 "register_operand" ""))
16077 (match_dup 2))
16078 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16079 (clobber (reg:CC 17))])
16080 (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
16081 (clobber (reg:CC 17))])]
16082 ""
16083 {
16084 if (TARGET_64BIT)
16085 {
16086 emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
16087 DONE;
16088 }
16089 if (TARGET_SINGLE_STRINGOP || optimize_size)
16090 {
16091 emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
16092 operands[1]));
16093 DONE;
16094 }
16095 else
16096 operands[2] = gen_reg_rtx (QImode);
16097 })
16098
16099 (define_expand "strmovqi_rex64"
16100 [(set (match_dup 2)
16101 (mem:QI (match_operand:DI 1 "register_operand" "")))
16102 (set (mem:QI (match_operand:DI 0 "register_operand" ""))
16103 (match_dup 2))
16104 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16105 (clobber (reg:CC 17))])
16106 (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
16107 (clobber (reg:CC 17))])]
16108 "TARGET_64BIT"
16109 {
16110 if (TARGET_SINGLE_STRINGOP || optimize_size)
16111 {
16112 emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
16113 operands[1]));
16114 DONE;
16115 }
16116 else
16117 operands[2] = gen_reg_rtx (QImode);
16118 })
16119
16120 (define_insn "strmovdi_rex_1"
16121 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16122 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16123 (set (match_operand:DI 0 "register_operand" "=D")
16124 (plus:DI (match_dup 2)
16125 (const_int 8)))
16126 (set (match_operand:DI 1 "register_operand" "=S")
16127 (plus:DI (match_dup 3)
16128 (const_int 8)))
16129 (use (reg:SI 19))]
16130 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16131 "movsq"
16132 [(set_attr "type" "str")
16133 (set_attr "mode" "DI")
16134 (set_attr "memory" "both")])
16135
16136 (define_insn "strmovsi_1"
16137 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16138 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16139 (set (match_operand:SI 0 "register_operand" "=D")
16140 (plus:SI (match_dup 2)
16141 (const_int 4)))
16142 (set (match_operand:SI 1 "register_operand" "=S")
16143 (plus:SI (match_dup 3)
16144 (const_int 4)))
16145 (use (reg:SI 19))]
16146 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16147 "{movsl|movsd}"
16148 [(set_attr "type" "str")
16149 (set_attr "mode" "SI")
16150 (set_attr "memory" "both")])
16151
16152 (define_insn "strmovsi_rex_1"
16153 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16154 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16155 (set (match_operand:DI 0 "register_operand" "=D")
16156 (plus:DI (match_dup 2)
16157 (const_int 4)))
16158 (set (match_operand:DI 1 "register_operand" "=S")
16159 (plus:DI (match_dup 3)
16160 (const_int 4)))
16161 (use (reg:SI 19))]
16162 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16163 "{movsl|movsd}"
16164 [(set_attr "type" "str")
16165 (set_attr "mode" "SI")
16166 (set_attr "memory" "both")])
16167
16168 (define_insn "strmovhi_1"
16169 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16170 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16171 (set (match_operand:SI 0 "register_operand" "=D")
16172 (plus:SI (match_dup 2)
16173 (const_int 2)))
16174 (set (match_operand:SI 1 "register_operand" "=S")
16175 (plus:SI (match_dup 3)
16176 (const_int 2)))
16177 (use (reg:SI 19))]
16178 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16179 "movsw"
16180 [(set_attr "type" "str")
16181 (set_attr "memory" "both")
16182 (set_attr "mode" "HI")])
16183
16184 (define_insn "strmovhi_rex_1"
16185 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16186 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16187 (set (match_operand:DI 0 "register_operand" "=D")
16188 (plus:DI (match_dup 2)
16189 (const_int 2)))
16190 (set (match_operand:DI 1 "register_operand" "=S")
16191 (plus:DI (match_dup 3)
16192 (const_int 2)))
16193 (use (reg:SI 19))]
16194 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16195 "movsw"
16196 [(set_attr "type" "str")
16197 (set_attr "memory" "both")
16198 (set_attr "mode" "HI")])
16199
16200 (define_insn "strmovqi_1"
16201 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16202 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16203 (set (match_operand:SI 0 "register_operand" "=D")
16204 (plus:SI (match_dup 2)
16205 (const_int 1)))
16206 (set (match_operand:SI 1 "register_operand" "=S")
16207 (plus:SI (match_dup 3)
16208 (const_int 1)))
16209 (use (reg:SI 19))]
16210 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16211 "movsb"
16212 [(set_attr "type" "str")
16213 (set_attr "memory" "both")
16214 (set_attr "mode" "QI")])
16215
16216 (define_insn "strmovqi_rex_1"
16217 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16218 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16219 (set (match_operand:DI 0 "register_operand" "=D")
16220 (plus:DI (match_dup 2)
16221 (const_int 1)))
16222 (set (match_operand:DI 1 "register_operand" "=S")
16223 (plus:DI (match_dup 3)
16224 (const_int 1)))
16225 (use (reg:SI 19))]
16226 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16227 "movsb"
16228 [(set_attr "type" "str")
16229 (set_attr "memory" "both")
16230 (set_attr "mode" "QI")])
16231
16232 (define_insn "rep_movdi_rex64"
16233 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16234 (set (match_operand:DI 0 "register_operand" "=D")
16235 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16236 (const_int 3))
16237 (match_operand:DI 3 "register_operand" "0")))
16238 (set (match_operand:DI 1 "register_operand" "=S")
16239 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16240 (match_operand:DI 4 "register_operand" "1")))
16241 (set (mem:BLK (match_dup 3))
16242 (mem:BLK (match_dup 4)))
16243 (use (match_dup 5))
16244 (use (reg:SI 19))]
16245 "TARGET_64BIT"
16246 "{rep\;movsq|rep movsq}"
16247 [(set_attr "type" "str")
16248 (set_attr "prefix_rep" "1")
16249 (set_attr "memory" "both")
16250 (set_attr "mode" "DI")])
16251
16252 (define_insn "rep_movsi"
16253 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16254 (set (match_operand:SI 0 "register_operand" "=D")
16255 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16256 (const_int 2))
16257 (match_operand:SI 3 "register_operand" "0")))
16258 (set (match_operand:SI 1 "register_operand" "=S")
16259 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16260 (match_operand:SI 4 "register_operand" "1")))
16261 (set (mem:BLK (match_dup 3))
16262 (mem:BLK (match_dup 4)))
16263 (use (match_dup 5))
16264 (use (reg:SI 19))]
16265 "!TARGET_64BIT"
16266 "{rep\;movsl|rep movsd}"
16267 [(set_attr "type" "str")
16268 (set_attr "prefix_rep" "1")
16269 (set_attr "memory" "both")
16270 (set_attr "mode" "SI")])
16271
16272 (define_insn "rep_movsi_rex64"
16273 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16274 (set (match_operand:DI 0 "register_operand" "=D")
16275 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16276 (const_int 2))
16277 (match_operand:DI 3 "register_operand" "0")))
16278 (set (match_operand:DI 1 "register_operand" "=S")
16279 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16280 (match_operand:DI 4 "register_operand" "1")))
16281 (set (mem:BLK (match_dup 3))
16282 (mem:BLK (match_dup 4)))
16283 (use (match_dup 5))
16284 (use (reg:SI 19))]
16285 "TARGET_64BIT"
16286 "{rep\;movsl|rep movsd}"
16287 [(set_attr "type" "str")
16288 (set_attr "prefix_rep" "1")
16289 (set_attr "memory" "both")
16290 (set_attr "mode" "SI")])
16291
16292 (define_insn "rep_movqi"
16293 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16294 (set (match_operand:SI 0 "register_operand" "=D")
16295 (plus:SI (match_operand:SI 3 "register_operand" "0")
16296 (match_operand:SI 5 "register_operand" "2")))
16297 (set (match_operand:SI 1 "register_operand" "=S")
16298 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16299 (set (mem:BLK (match_dup 3))
16300 (mem:BLK (match_dup 4)))
16301 (use (match_dup 5))
16302 (use (reg:SI 19))]
16303 "!TARGET_64BIT"
16304 "{rep\;movsb|rep movsb}"
16305 [(set_attr "type" "str")
16306 (set_attr "prefix_rep" "1")
16307 (set_attr "memory" "both")
16308 (set_attr "mode" "SI")])
16309
16310 (define_insn "rep_movqi_rex64"
16311 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16312 (set (match_operand:DI 0 "register_operand" "=D")
16313 (plus:DI (match_operand:DI 3 "register_operand" "0")
16314 (match_operand:DI 5 "register_operand" "2")))
16315 (set (match_operand:DI 1 "register_operand" "=S")
16316 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16317 (set (mem:BLK (match_dup 3))
16318 (mem:BLK (match_dup 4)))
16319 (use (match_dup 5))
16320 (use (reg:SI 19))]
16321 "TARGET_64BIT"
16322 "{rep\;movsb|rep movsb}"
16323 [(set_attr "type" "str")
16324 (set_attr "prefix_rep" "1")
16325 (set_attr "memory" "both")
16326 (set_attr "mode" "SI")])
16327
16328 (define_expand "clrstrsi"
16329 [(use (match_operand:BLK 0 "memory_operand" ""))
16330 (use (match_operand:SI 1 "nonmemory_operand" ""))
16331 (use (match_operand 2 "const_int_operand" ""))]
16332 ""
16333 {
16334 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16335 DONE;
16336 else
16337 FAIL;
16338 })
16339
16340 (define_expand "clrstrdi"
16341 [(use (match_operand:BLK 0 "memory_operand" ""))
16342 (use (match_operand:DI 1 "nonmemory_operand" ""))
16343 (use (match_operand 2 "const_int_operand" ""))]
16344 "TARGET_64BIT"
16345 {
16346 if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16347 DONE;
16348 else
16349 FAIL;
16350 })
16351
16352 ;; Most CPUs don't like single string operations
16353 ;; Handle this case here to simplify previous expander.
16354
16355 (define_expand "strsetdi_rex64"
16356 [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16357 (match_operand:DI 1 "register_operand" ""))
16358 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16359 (clobber (reg:CC 17))])]
16360 "TARGET_64BIT"
16361 {
16362 if (TARGET_SINGLE_STRINGOP || optimize_size)
16363 {
16364 emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16365 DONE;
16366 }
16367 })
16368
16369 (define_expand "strsetsi"
16370 [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16371 (match_operand:SI 1 "register_operand" ""))
16372 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16373 (clobber (reg:CC 17))])]
16374 ""
16375 {
16376 if (TARGET_64BIT)
16377 {
16378 emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16379 DONE;
16380 }
16381 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16382 {
16383 emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16384 DONE;
16385 }
16386 })
16387
16388 (define_expand "strsetsi_rex64"
16389 [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16390 (match_operand:SI 1 "register_operand" ""))
16391 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16392 (clobber (reg:CC 17))])]
16393 "TARGET_64BIT"
16394 {
16395 if (TARGET_SINGLE_STRINGOP || optimize_size)
16396 {
16397 emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16398 DONE;
16399 }
16400 })
16401
16402 (define_expand "strsethi"
16403 [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16404 (match_operand:HI 1 "register_operand" ""))
16405 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16406 (clobber (reg:CC 17))])]
16407 ""
16408 {
16409 if (TARGET_64BIT)
16410 {
16411 emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16412 DONE;
16413 }
16414 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16415 {
16416 emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16417 DONE;
16418 }
16419 })
16420
16421 (define_expand "strsethi_rex64"
16422 [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16423 (match_operand:HI 1 "register_operand" ""))
16424 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16425 (clobber (reg:CC 17))])]
16426 "TARGET_64BIT"
16427 {
16428 if (TARGET_SINGLE_STRINGOP || optimize_size)
16429 {
16430 emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16431 DONE;
16432 }
16433 })
16434
16435 (define_expand "strsetqi"
16436 [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16437 (match_operand:QI 1 "register_operand" ""))
16438 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16439 (clobber (reg:CC 17))])]
16440 ""
16441 {
16442 if (TARGET_64BIT)
16443 {
16444 emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16445 DONE;
16446 }
16447 else if (TARGET_SINGLE_STRINGOP || optimize_size)
16448 {
16449 emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16450 DONE;
16451 }
16452 })
16453
16454 (define_expand "strsetqi_rex64"
16455 [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16456 (match_operand:QI 1 "register_operand" ""))
16457 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16458 (clobber (reg:CC 17))])]
16459 "TARGET_64BIT"
16460 {
16461 if (TARGET_SINGLE_STRINGOP || optimize_size)
16462 {
16463 emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16464 DONE;
16465 }
16466 })
16467
16468 (define_insn "strsetdi_rex_1"
16469 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16470 (match_operand:SI 2 "register_operand" "a"))
16471 (set (match_operand:DI 0 "register_operand" "=D")
16472 (plus:DI (match_dup 1)
16473 (const_int 8)))
16474 (use (reg:SI 19))]
16475 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16476 "stosq"
16477 [(set_attr "type" "str")
16478 (set_attr "memory" "store")
16479 (set_attr "mode" "DI")])
16480
16481 (define_insn "strsetsi_1"
16482 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16483 (match_operand:SI 2 "register_operand" "a"))
16484 (set (match_operand:SI 0 "register_operand" "=D")
16485 (plus:SI (match_dup 1)
16486 (const_int 4)))
16487 (use (reg:SI 19))]
16488 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16489 "{stosl|stosd}"
16490 [(set_attr "type" "str")
16491 (set_attr "memory" "store")
16492 (set_attr "mode" "SI")])
16493
16494 (define_insn "strsetsi_rex_1"
16495 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16496 (match_operand:SI 2 "register_operand" "a"))
16497 (set (match_operand:DI 0 "register_operand" "=D")
16498 (plus:DI (match_dup 1)
16499 (const_int 4)))
16500 (use (reg:SI 19))]
16501 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16502 "{stosl|stosd}"
16503 [(set_attr "type" "str")
16504 (set_attr "memory" "store")
16505 (set_attr "mode" "SI")])
16506
16507 (define_insn "strsethi_1"
16508 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16509 (match_operand:HI 2 "register_operand" "a"))
16510 (set (match_operand:SI 0 "register_operand" "=D")
16511 (plus:SI (match_dup 1)
16512 (const_int 2)))
16513 (use (reg:SI 19))]
16514 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16515 "stosw"
16516 [(set_attr "type" "str")
16517 (set_attr "memory" "store")
16518 (set_attr "mode" "HI")])
16519
16520 (define_insn "strsethi_rex_1"
16521 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16522 (match_operand:HI 2 "register_operand" "a"))
16523 (set (match_operand:DI 0 "register_operand" "=D")
16524 (plus:DI (match_dup 1)
16525 (const_int 2)))
16526 (use (reg:SI 19))]
16527 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16528 "stosw"
16529 [(set_attr "type" "str")
16530 (set_attr "memory" "store")
16531 (set_attr "mode" "HI")])
16532
16533 (define_insn "strsetqi_1"
16534 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16535 (match_operand:QI 2 "register_operand" "a"))
16536 (set (match_operand:SI 0 "register_operand" "=D")
16537 (plus:SI (match_dup 1)
16538 (const_int 1)))
16539 (use (reg:SI 19))]
16540 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16541 "stosb"
16542 [(set_attr "type" "str")
16543 (set_attr "memory" "store")
16544 (set_attr "mode" "QI")])
16545
16546 (define_insn "strsetqi_rex_1"
16547 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16548 (match_operand:QI 2 "register_operand" "a"))
16549 (set (match_operand:DI 0 "register_operand" "=D")
16550 (plus:DI (match_dup 1)
16551 (const_int 1)))
16552 (use (reg:SI 19))]
16553 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16554 "stosb"
16555 [(set_attr "type" "str")
16556 (set_attr "memory" "store")
16557 (set_attr "mode" "QI")])
16558
16559 (define_insn "rep_stosdi_rex64"
16560 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16561 (set (match_operand:DI 0 "register_operand" "=D")
16562 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16563 (const_int 3))
16564 (match_operand:DI 3 "register_operand" "0")))
16565 (set (mem:BLK (match_dup 3))
16566 (const_int 0))
16567 (use (match_operand:DI 2 "register_operand" "a"))
16568 (use (match_dup 4))
16569 (use (reg:SI 19))]
16570 "TARGET_64BIT"
16571 "{rep\;stosq|rep stosq}"
16572 [(set_attr "type" "str")
16573 (set_attr "prefix_rep" "1")
16574 (set_attr "memory" "store")
16575 (set_attr "mode" "DI")])
16576
16577 (define_insn "rep_stossi"
16578 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16579 (set (match_operand:SI 0 "register_operand" "=D")
16580 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16581 (const_int 2))
16582 (match_operand:SI 3 "register_operand" "0")))
16583 (set (mem:BLK (match_dup 3))
16584 (const_int 0))
16585 (use (match_operand:SI 2 "register_operand" "a"))
16586 (use (match_dup 4))
16587 (use (reg:SI 19))]
16588 "!TARGET_64BIT"
16589 "{rep\;stosl|rep stosd}"
16590 [(set_attr "type" "str")
16591 (set_attr "prefix_rep" "1")
16592 (set_attr "memory" "store")
16593 (set_attr "mode" "SI")])
16594
16595 (define_insn "rep_stossi_rex64"
16596 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16597 (set (match_operand:DI 0 "register_operand" "=D")
16598 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16599 (const_int 2))
16600 (match_operand:DI 3 "register_operand" "0")))
16601 (set (mem:BLK (match_dup 3))
16602 (const_int 0))
16603 (use (match_operand:SI 2 "register_operand" "a"))
16604 (use (match_dup 4))
16605 (use (reg:SI 19))]
16606 "TARGET_64BIT"
16607 "{rep\;stosl|rep stosd}"
16608 [(set_attr "type" "str")
16609 (set_attr "prefix_rep" "1")
16610 (set_attr "memory" "store")
16611 (set_attr "mode" "SI")])
16612
16613 (define_insn "rep_stosqi"
16614 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16615 (set (match_operand:SI 0 "register_operand" "=D")
16616 (plus:SI (match_operand:SI 3 "register_operand" "0")
16617 (match_operand:SI 4 "register_operand" "1")))
16618 (set (mem:BLK (match_dup 3))
16619 (const_int 0))
16620 (use (match_operand:QI 2 "register_operand" "a"))
16621 (use (match_dup 4))
16622 (use (reg:SI 19))]
16623 "!TARGET_64BIT"
16624 "{rep\;stosb|rep stosb}"
16625 [(set_attr "type" "str")
16626 (set_attr "prefix_rep" "1")
16627 (set_attr "memory" "store")
16628 (set_attr "mode" "QI")])
16629
16630 (define_insn "rep_stosqi_rex64"
16631 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16632 (set (match_operand:DI 0 "register_operand" "=D")
16633 (plus:DI (match_operand:DI 3 "register_operand" "0")
16634 (match_operand:DI 4 "register_operand" "1")))
16635 (set (mem:BLK (match_dup 3))
16636 (const_int 0))
16637 (use (match_operand:QI 2 "register_operand" "a"))
16638 (use (match_dup 4))
16639 (use (reg:DI 19))]
16640 "TARGET_64BIT"
16641 "{rep\;stosb|rep stosb}"
16642 [(set_attr "type" "str")
16643 (set_attr "prefix_rep" "1")
16644 (set_attr "memory" "store")
16645 (set_attr "mode" "QI")])
16646
16647 (define_expand "cmpstrsi"
16648 [(set (match_operand:SI 0 "register_operand" "")
16649 (compare:SI (match_operand:BLK 1 "general_operand" "")
16650 (match_operand:BLK 2 "general_operand" "")))
16651 (use (match_operand 3 "general_operand" ""))
16652 (use (match_operand 4 "immediate_operand" ""))]
16653 ""
16654 {
16655 rtx addr1, addr2, out, outlow, count, countreg, align;
16656
16657 /* Can't use this if the user has appropriated esi or edi. */
16658 if (global_regs[4] || global_regs[5])
16659 FAIL;
16660
16661 out = operands[0];
16662 if (GET_CODE (out) != REG)
16663 out = gen_reg_rtx (SImode);
16664
16665 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16666 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16667
16668 count = operands[3];
16669 countreg = ix86_zero_extend_to_Pmode (count);
16670
16671 /* %%% Iff we are testing strict equality, we can use known alignment
16672 to good advantage. This may be possible with combine, particularly
16673 once cc0 is dead. */
16674 align = operands[4];
16675
16676 emit_insn (gen_cld ());
16677 if (GET_CODE (count) == CONST_INT)
16678 {
16679 if (INTVAL (count) == 0)
16680 {
16681 emit_move_insn (operands[0], const0_rtx);
16682 DONE;
16683 }
16684 if (TARGET_64BIT)
16685 emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16686 addr1, addr2, countreg));
16687 else
16688 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16689 addr1, addr2, countreg));
16690 }
16691 else
16692 {
16693 if (TARGET_64BIT)
16694 {
16695 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16696 emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16697 addr1, addr2, countreg));
16698 }
16699 else
16700 {
16701 emit_insn (gen_cmpsi_1 (countreg, countreg));
16702 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16703 addr1, addr2, countreg));
16704 }
16705 }
16706
16707 outlow = gen_lowpart (QImode, out);
16708 emit_insn (gen_cmpintqi (outlow));
16709 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16710
16711 if (operands[0] != out)
16712 emit_move_insn (operands[0], out);
16713
16714 DONE;
16715 })
16716
16717 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16718
16719 (define_expand "cmpintqi"
16720 [(set (match_dup 1)
16721 (gtu:QI (reg:CC 17) (const_int 0)))
16722 (set (match_dup 2)
16723 (ltu:QI (reg:CC 17) (const_int 0)))
16724 (parallel [(set (match_operand:QI 0 "register_operand" "")
16725 (minus:QI (match_dup 1)
16726 (match_dup 2)))
16727 (clobber (reg:CC 17))])]
16728 ""
16729 "operands[1] = gen_reg_rtx (QImode);
16730 operands[2] = gen_reg_rtx (QImode);")
16731
16732 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16733 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16734
16735 (define_insn "cmpstrqi_nz_1"
16736 [(set (reg:CC 17)
16737 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16738 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16739 (use (match_operand:SI 6 "register_operand" "2"))
16740 (use (match_operand:SI 3 "immediate_operand" "i"))
16741 (use (reg:SI 19))
16742 (clobber (match_operand:SI 0 "register_operand" "=S"))
16743 (clobber (match_operand:SI 1 "register_operand" "=D"))
16744 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16745 "!TARGET_64BIT"
16746 "repz{\;| }cmpsb"
16747 [(set_attr "type" "str")
16748 (set_attr "mode" "QI")
16749 (set_attr "prefix_rep" "1")])
16750
16751 (define_insn "cmpstrqi_nz_rex_1"
16752 [(set (reg:CC 17)
16753 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16754 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16755 (use (match_operand:DI 6 "register_operand" "2"))
16756 (use (match_operand:SI 3 "immediate_operand" "i"))
16757 (use (reg:SI 19))
16758 (clobber (match_operand:DI 0 "register_operand" "=S"))
16759 (clobber (match_operand:DI 1 "register_operand" "=D"))
16760 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16761 "TARGET_64BIT"
16762 "repz{\;| }cmpsb"
16763 [(set_attr "type" "str")
16764 (set_attr "mode" "QI")
16765 (set_attr "prefix_rep" "1")])
16766
16767 ;; The same, but the count is not known to not be zero.
16768
16769 (define_insn "cmpstrqi_1"
16770 [(set (reg:CC 17)
16771 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16772 (const_int 0))
16773 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16774 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16775 (const_int 0)))
16776 (use (match_operand:SI 3 "immediate_operand" "i"))
16777 (use (reg:CC 17))
16778 (use (reg:SI 19))
16779 (clobber (match_operand:SI 0 "register_operand" "=S"))
16780 (clobber (match_operand:SI 1 "register_operand" "=D"))
16781 (clobber (match_operand:SI 2 "register_operand" "=c"))]
16782 "!TARGET_64BIT"
16783 "repz{\;| }cmpsb"
16784 [(set_attr "type" "str")
16785 (set_attr "mode" "QI")
16786 (set_attr "prefix_rep" "1")])
16787
16788 (define_insn "cmpstrqi_rex_1"
16789 [(set (reg:CC 17)
16790 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16791 (const_int 0))
16792 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16793 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16794 (const_int 0)))
16795 (use (match_operand:SI 3 "immediate_operand" "i"))
16796 (use (reg:CC 17))
16797 (use (reg:SI 19))
16798 (clobber (match_operand:DI 0 "register_operand" "=S"))
16799 (clobber (match_operand:DI 1 "register_operand" "=D"))
16800 (clobber (match_operand:DI 2 "register_operand" "=c"))]
16801 "TARGET_64BIT"
16802 "repz{\;| }cmpsb"
16803 [(set_attr "type" "str")
16804 (set_attr "mode" "QI")
16805 (set_attr "prefix_rep" "1")])
16806
16807 (define_expand "strlensi"
16808 [(set (match_operand:SI 0 "register_operand" "")
16809 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16810 (match_operand:QI 2 "immediate_operand" "")
16811 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16812 ""
16813 {
16814 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16815 DONE;
16816 else
16817 FAIL;
16818 })
16819
16820 (define_expand "strlendi"
16821 [(set (match_operand:DI 0 "register_operand" "")
16822 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16823 (match_operand:QI 2 "immediate_operand" "")
16824 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16825 ""
16826 {
16827 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16828 DONE;
16829 else
16830 FAIL;
16831 })
16832
16833 (define_insn "strlenqi_1"
16834 [(set (match_operand:SI 0 "register_operand" "=&c")
16835 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16836 (match_operand:QI 2 "register_operand" "a")
16837 (match_operand:SI 3 "immediate_operand" "i")
16838 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16839 (use (reg:SI 19))
16840 (clobber (match_operand:SI 1 "register_operand" "=D"))
16841 (clobber (reg:CC 17))]
16842 "!TARGET_64BIT"
16843 "repnz{\;| }scasb"
16844 [(set_attr "type" "str")
16845 (set_attr "mode" "QI")
16846 (set_attr "prefix_rep" "1")])
16847
16848 (define_insn "strlenqi_rex_1"
16849 [(set (match_operand:DI 0 "register_operand" "=&c")
16850 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16851 (match_operand:QI 2 "register_operand" "a")
16852 (match_operand:DI 3 "immediate_operand" "i")
16853 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16854 (use (reg:SI 19))
16855 (clobber (match_operand:DI 1 "register_operand" "=D"))
16856 (clobber (reg:CC 17))]
16857 "TARGET_64BIT"
16858 "repnz{\;| }scasb"
16859 [(set_attr "type" "str")
16860 (set_attr "mode" "QI")
16861 (set_attr "prefix_rep" "1")])
16862
16863 ;; Peephole optimizations to clean up after cmpstr*. This should be
16864 ;; handled in combine, but it is not currently up to the task.
16865 ;; When used for their truth value, the cmpstr* expanders generate
16866 ;; code like this:
16867 ;;
16868 ;; repz cmpsb
16869 ;; seta %al
16870 ;; setb %dl
16871 ;; cmpb %al, %dl
16872 ;; jcc label
16873 ;;
16874 ;; The intermediate three instructions are unnecessary.
16875
16876 ;; This one handles cmpstr*_nz_1...
16877 (define_peephole2
16878 [(parallel[
16879 (set (reg:CC 17)
16880 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16881 (mem:BLK (match_operand 5 "register_operand" ""))))
16882 (use (match_operand 6 "register_operand" ""))
16883 (use (match_operand:SI 3 "immediate_operand" ""))
16884 (use (reg:SI 19))
16885 (clobber (match_operand 0 "register_operand" ""))
16886 (clobber (match_operand 1 "register_operand" ""))
16887 (clobber (match_operand 2 "register_operand" ""))])
16888 (set (match_operand:QI 7 "register_operand" "")
16889 (gtu:QI (reg:CC 17) (const_int 0)))
16890 (set (match_operand:QI 8 "register_operand" "")
16891 (ltu:QI (reg:CC 17) (const_int 0)))
16892 (set (reg 17)
16893 (compare (match_dup 7) (match_dup 8)))
16894 ]
16895 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16896 [(parallel[
16897 (set (reg:CC 17)
16898 (compare:CC (mem:BLK (match_dup 4))
16899 (mem:BLK (match_dup 5))))
16900 (use (match_dup 6))
16901 (use (match_dup 3))
16902 (use (reg:SI 19))
16903 (clobber (match_dup 0))
16904 (clobber (match_dup 1))
16905 (clobber (match_dup 2))])]
16906 "")
16907
16908 ;; ...and this one handles cmpstr*_1.
16909 (define_peephole2
16910 [(parallel[
16911 (set (reg:CC 17)
16912 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16913 (const_int 0))
16914 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16915 (mem:BLK (match_operand 5 "register_operand" "")))
16916 (const_int 0)))
16917 (use (match_operand:SI 3 "immediate_operand" ""))
16918 (use (reg:CC 17))
16919 (use (reg:SI 19))
16920 (clobber (match_operand 0 "register_operand" ""))
16921 (clobber (match_operand 1 "register_operand" ""))
16922 (clobber (match_operand 2 "register_operand" ""))])
16923 (set (match_operand:QI 7 "register_operand" "")
16924 (gtu:QI (reg:CC 17) (const_int 0)))
16925 (set (match_operand:QI 8 "register_operand" "")
16926 (ltu:QI (reg:CC 17) (const_int 0)))
16927 (set (reg 17)
16928 (compare (match_dup 7) (match_dup 8)))
16929 ]
16930 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16931 [(parallel[
16932 (set (reg:CC 17)
16933 (if_then_else:CC (ne (match_dup 6)
16934 (const_int 0))
16935 (compare:CC (mem:BLK (match_dup 4))
16936 (mem:BLK (match_dup 5)))
16937 (const_int 0)))
16938 (use (match_dup 3))
16939 (use (reg:CC 17))
16940 (use (reg:SI 19))
16941 (clobber (match_dup 0))
16942 (clobber (match_dup 1))
16943 (clobber (match_dup 2))])]
16944 "")
16945
16946
16947 \f
16948 ;; Conditional move instructions.
16949
16950 (define_expand "movdicc"
16951 [(set (match_operand:DI 0 "register_operand" "")
16952 (if_then_else:DI (match_operand 1 "comparison_operator" "")
16953 (match_operand:DI 2 "general_operand" "")
16954 (match_operand:DI 3 "general_operand" "")))]
16955 "TARGET_64BIT"
16956 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16957
16958 (define_insn "x86_movdicc_0_m1_rex64"
16959 [(set (match_operand:DI 0 "register_operand" "=r")
16960 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16961 (const_int -1)
16962 (const_int 0)))
16963 (clobber (reg:CC 17))]
16964 "TARGET_64BIT"
16965 "sbb{q}\t%0, %0"
16966 ; Since we don't have the proper number of operands for an alu insn,
16967 ; fill in all the blanks.
16968 [(set_attr "type" "alu")
16969 (set_attr "pent_pair" "pu")
16970 (set_attr "memory" "none")
16971 (set_attr "imm_disp" "false")
16972 (set_attr "mode" "DI")
16973 (set_attr "length_immediate" "0")])
16974
16975 (define_insn "movdicc_c_rex64"
16976 [(set (match_operand:DI 0 "register_operand" "=r,r")
16977 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16978 [(reg 17) (const_int 0)])
16979 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16980 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16981 "TARGET_64BIT && TARGET_CMOVE
16982 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16983 "@
16984 cmov%O2%C1\t{%2, %0|%0, %2}
16985 cmov%O2%c1\t{%3, %0|%0, %3}"
16986 [(set_attr "type" "icmov")
16987 (set_attr "mode" "DI")])
16988
16989 (define_expand "movsicc"
16990 [(set (match_operand:SI 0 "register_operand" "")
16991 (if_then_else:SI (match_operand 1 "comparison_operator" "")
16992 (match_operand:SI 2 "general_operand" "")
16993 (match_operand:SI 3 "general_operand" "")))]
16994 ""
16995 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16996
16997 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16998 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16999 ;; So just document what we're doing explicitly.
17000
17001 (define_insn "x86_movsicc_0_m1"
17002 [(set (match_operand:SI 0 "register_operand" "=r")
17003 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17004 (const_int -1)
17005 (const_int 0)))
17006 (clobber (reg:CC 17))]
17007 ""
17008 "sbb{l}\t%0, %0"
17009 ; Since we don't have the proper number of operands for an alu insn,
17010 ; fill in all the blanks.
17011 [(set_attr "type" "alu")
17012 (set_attr "pent_pair" "pu")
17013 (set_attr "memory" "none")
17014 (set_attr "imm_disp" "false")
17015 (set_attr "mode" "SI")
17016 (set_attr "length_immediate" "0")])
17017
17018 (define_insn "*movsicc_noc"
17019 [(set (match_operand:SI 0 "register_operand" "=r,r")
17020 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17021 [(reg 17) (const_int 0)])
17022 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17023 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17024 "TARGET_CMOVE
17025 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17026 "@
17027 cmov%O2%C1\t{%2, %0|%0, %2}
17028 cmov%O2%c1\t{%3, %0|%0, %3}"
17029 [(set_attr "type" "icmov")
17030 (set_attr "mode" "SI")])
17031
17032 (define_expand "movhicc"
17033 [(set (match_operand:HI 0 "register_operand" "")
17034 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17035 (match_operand:HI 2 "general_operand" "")
17036 (match_operand:HI 3 "general_operand" "")))]
17037 "TARGET_HIMODE_MATH"
17038 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17039
17040 (define_insn "*movhicc_noc"
17041 [(set (match_operand:HI 0 "register_operand" "=r,r")
17042 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17043 [(reg 17) (const_int 0)])
17044 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17045 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17046 "TARGET_CMOVE
17047 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17048 "@
17049 cmov%O2%C1\t{%2, %0|%0, %2}
17050 cmov%O2%c1\t{%3, %0|%0, %3}"
17051 [(set_attr "type" "icmov")
17052 (set_attr "mode" "HI")])
17053
17054 (define_expand "movqicc"
17055 [(set (match_operand:QI 0 "register_operand" "")
17056 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17057 (match_operand:QI 2 "general_operand" "")
17058 (match_operand:QI 3 "general_operand" "")))]
17059 "TARGET_QIMODE_MATH"
17060 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17061
17062 (define_insn_and_split "*movqicc_noc"
17063 [(set (match_operand:QI 0 "register_operand" "=r,r")
17064 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17065 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17066 (match_operand:QI 2 "register_operand" "r,0")
17067 (match_operand:QI 3 "register_operand" "0,r")))]
17068 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17069 "#"
17070 "&& reload_completed"
17071 [(set (match_dup 0)
17072 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17073 (match_dup 2)
17074 (match_dup 3)))]
17075 "operands[0] = gen_lowpart (SImode, operands[0]);
17076 operands[2] = gen_lowpart (SImode, operands[2]);
17077 operands[3] = gen_lowpart (SImode, operands[3]);"
17078 [(set_attr "type" "icmov")
17079 (set_attr "mode" "SI")])
17080
17081 (define_expand "movsfcc"
17082 [(set (match_operand:SF 0 "register_operand" "")
17083 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17084 (match_operand:SF 2 "register_operand" "")
17085 (match_operand:SF 3 "register_operand" "")))]
17086 "TARGET_CMOVE"
17087 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17088
17089 (define_insn "*movsfcc_1"
17090 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17091 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17092 [(reg 17) (const_int 0)])
17093 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17094 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17095 "TARGET_CMOVE
17096 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17097 "@
17098 fcmov%F1\t{%2, %0|%0, %2}
17099 fcmov%f1\t{%3, %0|%0, %3}
17100 cmov%O2%C1\t{%2, %0|%0, %2}
17101 cmov%O2%c1\t{%3, %0|%0, %3}"
17102 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17103 (set_attr "mode" "SF,SF,SI,SI")])
17104
17105 (define_expand "movdfcc"
17106 [(set (match_operand:DF 0 "register_operand" "")
17107 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17108 (match_operand:DF 2 "register_operand" "")
17109 (match_operand:DF 3 "register_operand" "")))]
17110 "TARGET_CMOVE"
17111 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17112
17113 (define_insn "*movdfcc_1"
17114 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17115 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17116 [(reg 17) (const_int 0)])
17117 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17118 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17119 "!TARGET_64BIT && TARGET_CMOVE
17120 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17121 "@
17122 fcmov%F1\t{%2, %0|%0, %2}
17123 fcmov%f1\t{%3, %0|%0, %3}
17124 #
17125 #"
17126 [(set_attr "type" "fcmov,fcmov,multi,multi")
17127 (set_attr "mode" "DF")])
17128
17129 (define_insn "*movdfcc_1_rex64"
17130 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17131 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17132 [(reg 17) (const_int 0)])
17133 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17134 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17135 "TARGET_64BIT && TARGET_CMOVE
17136 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17137 "@
17138 fcmov%F1\t{%2, %0|%0, %2}
17139 fcmov%f1\t{%3, %0|%0, %3}
17140 cmov%O2%C1\t{%2, %0|%0, %2}
17141 cmov%O2%c1\t{%3, %0|%0, %3}"
17142 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17143 (set_attr "mode" "DF")])
17144
17145 (define_split
17146 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17147 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17148 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17149 (match_operand:DF 2 "nonimmediate_operand" "")
17150 (match_operand:DF 3 "nonimmediate_operand" "")))]
17151 "!TARGET_64BIT && reload_completed"
17152 [(set (match_dup 2)
17153 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17154 (match_dup 5)
17155 (match_dup 7)))
17156 (set (match_dup 3)
17157 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17158 (match_dup 6)
17159 (match_dup 8)))]
17160 "split_di (operands+2, 1, operands+5, operands+6);
17161 split_di (operands+3, 1, operands+7, operands+8);
17162 split_di (operands, 1, operands+2, operands+3);")
17163
17164 (define_expand "movxfcc"
17165 [(set (match_operand:XF 0 "register_operand" "")
17166 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17167 (match_operand:XF 2 "register_operand" "")
17168 (match_operand:XF 3 "register_operand" "")))]
17169 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17170 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17171
17172 (define_expand "movtfcc"
17173 [(set (match_operand:TF 0 "register_operand" "")
17174 (if_then_else:TF (match_operand 1 "comparison_operator" "")
17175 (match_operand:TF 2 "register_operand" "")
17176 (match_operand:TF 3 "register_operand" "")))]
17177 "TARGET_CMOVE"
17178 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17179
17180 (define_insn "*movxfcc_1"
17181 [(set (match_operand:XF 0 "register_operand" "=f,f")
17182 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17183 [(reg 17) (const_int 0)])
17184 (match_operand:XF 2 "register_operand" "f,0")
17185 (match_operand:XF 3 "register_operand" "0,f")))]
17186 "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
17187 "@
17188 fcmov%F1\t{%2, %0|%0, %2}
17189 fcmov%f1\t{%3, %0|%0, %3}"
17190 [(set_attr "type" "fcmov")
17191 (set_attr "mode" "XF")])
17192
17193 (define_insn "*movtfcc_1"
17194 [(set (match_operand:TF 0 "register_operand" "=f,f")
17195 (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
17196 [(reg 17) (const_int 0)])
17197 (match_operand:TF 2 "register_operand" "f,0")
17198 (match_operand:TF 3 "register_operand" "0,f")))]
17199 "TARGET_CMOVE"
17200 "@
17201 fcmov%F1\t{%2, %0|%0, %2}
17202 fcmov%f1\t{%3, %0|%0, %3}"
17203 [(set_attr "type" "fcmov")
17204 (set_attr "mode" "XF")])
17205
17206 (define_expand "minsf3"
17207 [(parallel [
17208 (set (match_operand:SF 0 "register_operand" "")
17209 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17210 (match_operand:SF 2 "nonimmediate_operand" ""))
17211 (match_dup 1)
17212 (match_dup 2)))
17213 (clobber (reg:CC 17))])]
17214 "TARGET_SSE"
17215 "")
17216
17217 (define_insn "*minsf"
17218 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17219 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17220 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17221 (match_dup 1)
17222 (match_dup 2)))
17223 (clobber (reg:CC 17))]
17224 "TARGET_SSE && TARGET_IEEE_FP"
17225 "#")
17226
17227 (define_insn "*minsf_nonieee"
17228 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17229 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17230 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17231 (match_dup 1)
17232 (match_dup 2)))
17233 (clobber (reg:CC 17))]
17234 "TARGET_SSE && !TARGET_IEEE_FP
17235 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17236 "#")
17237
17238 (define_split
17239 [(set (match_operand:SF 0 "register_operand" "")
17240 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17241 (match_operand:SF 2 "nonimmediate_operand" ""))
17242 (match_operand:SF 3 "register_operand" "")
17243 (match_operand:SF 4 "nonimmediate_operand" "")))
17244 (clobber (reg:CC 17))]
17245 "SSE_REG_P (operands[0]) && reload_completed
17246 && ((operands_match_p (operands[1], operands[3])
17247 && operands_match_p (operands[2], operands[4]))
17248 || (operands_match_p (operands[1], operands[4])
17249 && operands_match_p (operands[2], operands[3])))"
17250 [(set (match_dup 0)
17251 (if_then_else:SF (lt (match_dup 1)
17252 (match_dup 2))
17253 (match_dup 1)
17254 (match_dup 2)))])
17255
17256 ;; Conditional addition patterns
17257 (define_expand "addqicc"
17258 [(match_operand:QI 0 "register_operand" "")
17259 (match_operand 1 "comparison_operator" "")
17260 (match_operand:QI 2 "register_operand" "")
17261 (match_operand:QI 3 "const_int_operand" "")]
17262 ""
17263 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17264
17265 (define_expand "addhicc"
17266 [(match_operand:HI 0 "register_operand" "")
17267 (match_operand 1 "comparison_operator" "")
17268 (match_operand:HI 2 "register_operand" "")
17269 (match_operand:HI 3 "const_int_operand" "")]
17270 ""
17271 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17272
17273 (define_expand "addsicc"
17274 [(match_operand:SI 0 "register_operand" "")
17275 (match_operand 1 "comparison_operator" "")
17276 (match_operand:SI 2 "register_operand" "")
17277 (match_operand:SI 3 "const_int_operand" "")]
17278 ""
17279 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17280
17281 (define_expand "adddicc"
17282 [(match_operand:DI 0 "register_operand" "")
17283 (match_operand 1 "comparison_operator" "")
17284 (match_operand:DI 2 "register_operand" "")
17285 (match_operand:DI 3 "const_int_operand" "")]
17286 "TARGET_64BIT"
17287 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17288
17289 ;; We can't represent the LT test directly. Do this by swapping the operands.
17290
17291 (define_split
17292 [(set (match_operand:SF 0 "fp_register_operand" "")
17293 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17294 (match_operand:SF 2 "register_operand" ""))
17295 (match_operand:SF 3 "register_operand" "")
17296 (match_operand:SF 4 "register_operand" "")))
17297 (clobber (reg:CC 17))]
17298 "reload_completed
17299 && ((operands_match_p (operands[1], operands[3])
17300 && operands_match_p (operands[2], operands[4]))
17301 || (operands_match_p (operands[1], operands[4])
17302 && operands_match_p (operands[2], operands[3])))"
17303 [(set (reg:CCFP 17)
17304 (compare:CCFP (match_dup 2)
17305 (match_dup 1)))
17306 (set (match_dup 0)
17307 (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17308 (match_dup 1)
17309 (match_dup 2)))])
17310
17311 (define_insn "*minsf_sse"
17312 [(set (match_operand:SF 0 "register_operand" "=x")
17313 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17314 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17315 (match_dup 1)
17316 (match_dup 2)))]
17317 "TARGET_SSE && reload_completed"
17318 "minss\t{%2, %0|%0, %2}"
17319 [(set_attr "type" "sse")
17320 (set_attr "mode" "SF")])
17321
17322 (define_expand "mindf3"
17323 [(parallel [
17324 (set (match_operand:DF 0 "register_operand" "")
17325 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17326 (match_operand:DF 2 "nonimmediate_operand" ""))
17327 (match_dup 1)
17328 (match_dup 2)))
17329 (clobber (reg:CC 17))])]
17330 "TARGET_SSE2 && TARGET_SSE_MATH"
17331 "#")
17332
17333 (define_insn "*mindf"
17334 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17335 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17336 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17337 (match_dup 1)
17338 (match_dup 2)))
17339 (clobber (reg:CC 17))]
17340 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17341 "#")
17342
17343 (define_insn "*mindf_nonieee"
17344 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17345 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17346 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17347 (match_dup 1)
17348 (match_dup 2)))
17349 (clobber (reg:CC 17))]
17350 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17351 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17352 "#")
17353
17354 (define_split
17355 [(set (match_operand:DF 0 "register_operand" "")
17356 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17357 (match_operand:DF 2 "nonimmediate_operand" ""))
17358 (match_operand:DF 3 "register_operand" "")
17359 (match_operand:DF 4 "nonimmediate_operand" "")))
17360 (clobber (reg:CC 17))]
17361 "SSE_REG_P (operands[0]) && reload_completed
17362 && ((operands_match_p (operands[1], operands[3])
17363 && operands_match_p (operands[2], operands[4]))
17364 || (operands_match_p (operands[1], operands[4])
17365 && operands_match_p (operands[2], operands[3])))"
17366 [(set (match_dup 0)
17367 (if_then_else:DF (lt (match_dup 1)
17368 (match_dup 2))
17369 (match_dup 1)
17370 (match_dup 2)))])
17371
17372 ;; We can't represent the LT test directly. Do this by swapping the operands.
17373 (define_split
17374 [(set (match_operand:DF 0 "fp_register_operand" "")
17375 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17376 (match_operand:DF 2 "register_operand" ""))
17377 (match_operand:DF 3 "register_operand" "")
17378 (match_operand:DF 4 "register_operand" "")))
17379 (clobber (reg:CC 17))]
17380 "reload_completed
17381 && ((operands_match_p (operands[1], operands[3])
17382 && operands_match_p (operands[2], operands[4]))
17383 || (operands_match_p (operands[1], operands[4])
17384 && operands_match_p (operands[2], operands[3])))"
17385 [(set (reg:CCFP 17)
17386 (compare:CCFP (match_dup 2)
17387 (match_dup 2)))
17388 (set (match_dup 0)
17389 (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17390 (match_dup 1)
17391 (match_dup 2)))])
17392
17393 (define_insn "*mindf_sse"
17394 [(set (match_operand:DF 0 "register_operand" "=Y")
17395 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17396 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17397 (match_dup 1)
17398 (match_dup 2)))]
17399 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17400 "minsd\t{%2, %0|%0, %2}"
17401 [(set_attr "type" "sse")
17402 (set_attr "mode" "DF")])
17403
17404 (define_expand "maxsf3"
17405 [(parallel [
17406 (set (match_operand:SF 0 "register_operand" "")
17407 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17408 (match_operand:SF 2 "nonimmediate_operand" ""))
17409 (match_dup 1)
17410 (match_dup 2)))
17411 (clobber (reg:CC 17))])]
17412 "TARGET_SSE"
17413 "#")
17414
17415 (define_insn "*maxsf"
17416 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17417 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17418 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17419 (match_dup 1)
17420 (match_dup 2)))
17421 (clobber (reg:CC 17))]
17422 "TARGET_SSE && TARGET_IEEE_FP"
17423 "#")
17424
17425 (define_insn "*maxsf_nonieee"
17426 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17427 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17428 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17429 (match_dup 1)
17430 (match_dup 2)))
17431 (clobber (reg:CC 17))]
17432 "TARGET_SSE && !TARGET_IEEE_FP
17433 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17434 "#")
17435
17436 (define_split
17437 [(set (match_operand:SF 0 "register_operand" "")
17438 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17439 (match_operand:SF 2 "nonimmediate_operand" ""))
17440 (match_operand:SF 3 "register_operand" "")
17441 (match_operand:SF 4 "nonimmediate_operand" "")))
17442 (clobber (reg:CC 17))]
17443 "SSE_REG_P (operands[0]) && reload_completed
17444 && ((operands_match_p (operands[1], operands[3])
17445 && operands_match_p (operands[2], operands[4]))
17446 || (operands_match_p (operands[1], operands[4])
17447 && operands_match_p (operands[2], operands[3])))"
17448 [(set (match_dup 0)
17449 (if_then_else:SF (gt (match_dup 1)
17450 (match_dup 2))
17451 (match_dup 1)
17452 (match_dup 2)))])
17453
17454 (define_split
17455 [(set (match_operand:SF 0 "fp_register_operand" "")
17456 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17457 (match_operand:SF 2 "register_operand" ""))
17458 (match_operand:SF 3 "register_operand" "")
17459 (match_operand:SF 4 "register_operand" "")))
17460 (clobber (reg:CC 17))]
17461 "reload_completed
17462 && ((operands_match_p (operands[1], operands[3])
17463 && operands_match_p (operands[2], operands[4]))
17464 || (operands_match_p (operands[1], operands[4])
17465 && operands_match_p (operands[2], operands[3])))"
17466 [(set (reg:CCFP 17)
17467 (compare:CCFP (match_dup 1)
17468 (match_dup 2)))
17469 (set (match_dup 0)
17470 (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17471 (match_dup 1)
17472 (match_dup 2)))])
17473
17474 (define_insn "*maxsf_sse"
17475 [(set (match_operand:SF 0 "register_operand" "=x")
17476 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17477 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17478 (match_dup 1)
17479 (match_dup 2)))]
17480 "TARGET_SSE && reload_completed"
17481 "maxss\t{%2, %0|%0, %2}"
17482 [(set_attr "type" "sse")
17483 (set_attr "mode" "SF")])
17484
17485 (define_expand "maxdf3"
17486 [(parallel [
17487 (set (match_operand:DF 0 "register_operand" "")
17488 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17489 (match_operand:DF 2 "nonimmediate_operand" ""))
17490 (match_dup 1)
17491 (match_dup 2)))
17492 (clobber (reg:CC 17))])]
17493 "TARGET_SSE2 && TARGET_SSE_MATH"
17494 "#")
17495
17496 (define_insn "*maxdf"
17497 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17498 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17499 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17500 (match_dup 1)
17501 (match_dup 2)))
17502 (clobber (reg:CC 17))]
17503 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17504 "#")
17505
17506 (define_insn "*maxdf_nonieee"
17507 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17508 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17509 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17510 (match_dup 1)
17511 (match_dup 2)))
17512 (clobber (reg:CC 17))]
17513 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17514 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17515 "#")
17516
17517 (define_split
17518 [(set (match_operand:DF 0 "register_operand" "")
17519 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17520 (match_operand:DF 2 "nonimmediate_operand" ""))
17521 (match_operand:DF 3 "register_operand" "")
17522 (match_operand:DF 4 "nonimmediate_operand" "")))
17523 (clobber (reg:CC 17))]
17524 "SSE_REG_P (operands[0]) && reload_completed
17525 && ((operands_match_p (operands[1], operands[3])
17526 && operands_match_p (operands[2], operands[4]))
17527 || (operands_match_p (operands[1], operands[4])
17528 && operands_match_p (operands[2], operands[3])))"
17529 [(set (match_dup 0)
17530 (if_then_else:DF (gt (match_dup 1)
17531 (match_dup 2))
17532 (match_dup 1)
17533 (match_dup 2)))])
17534
17535 (define_split
17536 [(set (match_operand:DF 0 "fp_register_operand" "")
17537 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17538 (match_operand:DF 2 "register_operand" ""))
17539 (match_operand:DF 3 "register_operand" "")
17540 (match_operand:DF 4 "register_operand" "")))
17541 (clobber (reg:CC 17))]
17542 "reload_completed
17543 && ((operands_match_p (operands[1], operands[3])
17544 && operands_match_p (operands[2], operands[4]))
17545 || (operands_match_p (operands[1], operands[4])
17546 && operands_match_p (operands[2], operands[3])))"
17547 [(set (reg:CCFP 17)
17548 (compare:CCFP (match_dup 1)
17549 (match_dup 2)))
17550 (set (match_dup 0)
17551 (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17552 (match_dup 1)
17553 (match_dup 2)))])
17554
17555 (define_insn "*maxdf_sse"
17556 [(set (match_operand:DF 0 "register_operand" "=Y")
17557 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17558 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17559 (match_dup 1)
17560 (match_dup 2)))]
17561 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17562 "maxsd\t{%2, %0|%0, %2}"
17563 [(set_attr "type" "sse")
17564 (set_attr "mode" "DF")])
17565 \f
17566 ;; Misc patterns (?)
17567
17568 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17569 ;; Otherwise there will be nothing to keep
17570 ;;
17571 ;; [(set (reg ebp) (reg esp))]
17572 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17573 ;; (clobber (eflags)]
17574 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17575 ;;
17576 ;; in proper program order.
17577 (define_expand "pro_epilogue_adjust_stack"
17578 [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17579 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17580 (match_operand:SI 2 "immediate_operand" "i,i")))
17581 (clobber (reg:CC 17))
17582 (clobber (mem:BLK (scratch)))])]
17583 ""
17584 {
17585 if (TARGET_64BIT)
17586 {
17587 emit_insn (gen_pro_epilogue_adjust_stack_rex64
17588 (operands[0], operands[1], operands[2]));
17589 DONE;
17590 }
17591 })
17592
17593 (define_insn "*pro_epilogue_adjust_stack_1"
17594 [(set (match_operand:SI 0 "register_operand" "=r,r")
17595 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17596 (match_operand:SI 2 "immediate_operand" "i,i")))
17597 (clobber (reg:CC 17))
17598 (clobber (mem:BLK (scratch)))]
17599 "!TARGET_64BIT"
17600 {
17601 switch (get_attr_type (insn))
17602 {
17603 case TYPE_IMOV:
17604 return "mov{l}\t{%1, %0|%0, %1}";
17605
17606 case TYPE_ALU:
17607 if (GET_CODE (operands[2]) == CONST_INT
17608 && (INTVAL (operands[2]) == 128
17609 || (INTVAL (operands[2]) < 0
17610 && INTVAL (operands[2]) != -128)))
17611 {
17612 operands[2] = GEN_INT (-INTVAL (operands[2]));
17613 return "sub{l}\t{%2, %0|%0, %2}";
17614 }
17615 return "add{l}\t{%2, %0|%0, %2}";
17616
17617 case TYPE_LEA:
17618 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17619 return "lea{l}\t{%a2, %0|%0, %a2}";
17620
17621 default:
17622 abort ();
17623 }
17624 }
17625 [(set (attr "type")
17626 (cond [(eq_attr "alternative" "0")
17627 (const_string "alu")
17628 (match_operand:SI 2 "const0_operand" "")
17629 (const_string "imov")
17630 ]
17631 (const_string "lea")))
17632 (set_attr "mode" "SI")])
17633
17634 (define_insn "pro_epilogue_adjust_stack_rex64"
17635 [(set (match_operand:DI 0 "register_operand" "=r,r")
17636 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17637 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17638 (clobber (reg:CC 17))
17639 (clobber (mem:BLK (scratch)))]
17640 "TARGET_64BIT"
17641 {
17642 switch (get_attr_type (insn))
17643 {
17644 case TYPE_IMOV:
17645 return "mov{q}\t{%1, %0|%0, %1}";
17646
17647 case TYPE_ALU:
17648 if (GET_CODE (operands[2]) == CONST_INT
17649 && (INTVAL (operands[2]) == 128
17650 || (INTVAL (operands[2]) < 0
17651 && INTVAL (operands[2]) != -128)))
17652 {
17653 operands[2] = GEN_INT (-INTVAL (operands[2]));
17654 return "sub{q}\t{%2, %0|%0, %2}";
17655 }
17656 return "add{q}\t{%2, %0|%0, %2}";
17657
17658 case TYPE_LEA:
17659 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17660 return "lea{q}\t{%a2, %0|%0, %a2}";
17661
17662 default:
17663 abort ();
17664 }
17665 }
17666 [(set (attr "type")
17667 (cond [(eq_attr "alternative" "0")
17668 (const_string "alu")
17669 (match_operand:DI 2 "const0_operand" "")
17670 (const_string "imov")
17671 ]
17672 (const_string "lea")))
17673 (set_attr "mode" "DI")])
17674
17675
17676 ;; Placeholder for the conditional moves. This one is split either to SSE
17677 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
17678 ;; fact is that compares supported by the cmp??ss instructions are exactly
17679 ;; swapped of those supported by cmove sequence.
17680 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17681 ;; supported by i387 comparisons and we do need to emit two conditional moves
17682 ;; in tandem.
17683
17684 (define_insn "sse_movsfcc"
17685 [(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")
17686 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17687 [(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")
17688 (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")])
17689 (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")
17690 (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")))
17691 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17692 (clobber (reg:CC 17))]
17693 "TARGET_SSE
17694 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17695 /* Avoid combine from being smart and converting min/max
17696 instruction patterns into conditional moves. */
17697 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17698 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17699 || !rtx_equal_p (operands[4], operands[2])
17700 || !rtx_equal_p (operands[5], operands[3]))
17701 && (!TARGET_IEEE_FP
17702 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17703 "#")
17704
17705 (define_insn "sse_movsfcc_eq"
17706 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17707 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17708 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17709 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17710 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17711 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17712 (clobber (reg:CC 17))]
17713 "TARGET_SSE
17714 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17715 "#")
17716
17717 (define_insn "sse_movdfcc"
17718 [(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")
17719 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17720 [(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")
17721 (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")])
17722 (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")
17723 (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")))
17724 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17725 (clobber (reg:CC 17))]
17726 "TARGET_SSE2
17727 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17728 /* Avoid combine from being smart and converting min/max
17729 instruction patterns into conditional moves. */
17730 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17731 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17732 || !rtx_equal_p (operands[4], operands[2])
17733 || !rtx_equal_p (operands[5], operands[3]))
17734 && (!TARGET_IEEE_FP
17735 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17736 "#")
17737
17738 (define_insn "sse_movdfcc_eq"
17739 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17740 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17741 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17742 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17743 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17744 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17745 (clobber (reg:CC 17))]
17746 "TARGET_SSE
17747 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17748 "#")
17749
17750 ;; For non-sse moves just expand the usual cmove sequence.
17751 (define_split
17752 [(set (match_operand 0 "register_operand" "")
17753 (if_then_else (match_operator 1 "comparison_operator"
17754 [(match_operand 4 "nonimmediate_operand" "")
17755 (match_operand 5 "register_operand" "")])
17756 (match_operand 2 "nonimmediate_operand" "")
17757 (match_operand 3 "nonimmediate_operand" "")))
17758 (clobber (match_operand 6 "" ""))
17759 (clobber (reg:CC 17))]
17760 "!SSE_REG_P (operands[0]) && reload_completed
17761 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17762 [(const_int 0)]
17763 {
17764 ix86_compare_op0 = operands[5];
17765 ix86_compare_op1 = operands[4];
17766 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17767 VOIDmode, operands[5], operands[4]);
17768 ix86_expand_fp_movcc (operands);
17769 DONE;
17770 })
17771
17772 ;; Split SSE based conditional move into sequence:
17773 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
17774 ;; and op2, op0 - zero op2 if comparison was false
17775 ;; nand op0, op3 - load op3 to op0 if comparison was false
17776 ;; or op2, op0 - get the nonzero one into the result.
17777 (define_split
17778 [(set (match_operand 0 "register_operand" "")
17779 (if_then_else (match_operator 1 "sse_comparison_operator"
17780 [(match_operand 4 "register_operand" "")
17781 (match_operand 5 "nonimmediate_operand" "")])
17782 (match_operand 2 "register_operand" "")
17783 (match_operand 3 "register_operand" "")))
17784 (clobber (match_operand 6 "" ""))
17785 (clobber (reg:CC 17))]
17786 "SSE_REG_P (operands[0]) && reload_completed"
17787 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17788 (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17789 (subreg:TI (match_dup 4) 0)))
17790 (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17791 (subreg:TI (match_dup 3) 0)))
17792 (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17793 (subreg:TI (match_dup 7) 0)))]
17794 {
17795 if (GET_MODE (operands[2]) == DFmode
17796 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17797 {
17798 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17799 emit_insn (gen_sse2_unpcklpd (op, op, op));
17800 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17801 emit_insn (gen_sse2_unpcklpd (op, op, op));
17802 }
17803
17804 /* If op2 == op3, op3 would be clobbered before it is used. */
17805 if (operands_match_p (operands[2], operands[3]))
17806 {
17807 emit_move_insn (operands[0], operands[2]);
17808 DONE;
17809 }
17810
17811 PUT_MODE (operands[1], GET_MODE (operands[0]));
17812 if (operands_match_p (operands[0], operands[4]))
17813 operands[6] = operands[4], operands[7] = operands[2];
17814 else
17815 operands[6] = operands[2], operands[7] = operands[4];
17816 })
17817
17818 ;; Special case of conditional move we can handle effectively.
17819 ;; Do not brother with the integer/floating point case, since these are
17820 ;; bot considerably slower, unlike in the generic case.
17821 (define_insn "*sse_movsfcc_const0_1"
17822 [(set (match_operand:SF 0 "register_operand" "=&x")
17823 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17824 [(match_operand:SF 4 "register_operand" "0")
17825 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17826 (match_operand:SF 2 "register_operand" "x")
17827 (match_operand:SF 3 "const0_operand" "X")))]
17828 "TARGET_SSE"
17829 "#")
17830
17831 (define_insn "*sse_movsfcc_const0_2"
17832 [(set (match_operand:SF 0 "register_operand" "=&x")
17833 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17834 [(match_operand:SF 4 "register_operand" "0")
17835 (match_operand:SF 5 "nonimmediate_operand" "xm")])
17836 (match_operand:SF 2 "const0_operand" "X")
17837 (match_operand:SF 3 "register_operand" "x")))]
17838 "TARGET_SSE"
17839 "#")
17840
17841 (define_insn "*sse_movsfcc_const0_3"
17842 [(set (match_operand:SF 0 "register_operand" "=&x")
17843 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17844 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17845 (match_operand:SF 5 "register_operand" "0")])
17846 (match_operand:SF 2 "register_operand" "x")
17847 (match_operand:SF 3 "const0_operand" "X")))]
17848 "TARGET_SSE"
17849 "#")
17850
17851 (define_insn "*sse_movsfcc_const0_4"
17852 [(set (match_operand:SF 0 "register_operand" "=&x")
17853 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17854 [(match_operand:SF 4 "nonimmediate_operand" "xm")
17855 (match_operand:SF 5 "register_operand" "0")])
17856 (match_operand:SF 2 "const0_operand" "X")
17857 (match_operand:SF 3 "register_operand" "x")))]
17858 "TARGET_SSE"
17859 "#")
17860
17861 (define_insn "*sse_movdfcc_const0_1"
17862 [(set (match_operand:DF 0 "register_operand" "=&Y")
17863 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17864 [(match_operand:DF 4 "register_operand" "0")
17865 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17866 (match_operand:DF 2 "register_operand" "Y")
17867 (match_operand:DF 3 "const0_operand" "X")))]
17868 "TARGET_SSE2"
17869 "#")
17870
17871 (define_insn "*sse_movdfcc_const0_2"
17872 [(set (match_operand:DF 0 "register_operand" "=&Y")
17873 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17874 [(match_operand:DF 4 "register_operand" "0")
17875 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17876 (match_operand:DF 2 "const0_operand" "X")
17877 (match_operand:DF 3 "register_operand" "Y")))]
17878 "TARGET_SSE2"
17879 "#")
17880
17881 (define_insn "*sse_movdfcc_const0_3"
17882 [(set (match_operand:DF 0 "register_operand" "=&Y")
17883 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17884 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17885 (match_operand:DF 5 "register_operand" "0")])
17886 (match_operand:DF 2 "register_operand" "Y")
17887 (match_operand:DF 3 "const0_operand" "X")))]
17888 "TARGET_SSE2"
17889 "#")
17890
17891 (define_insn "*sse_movdfcc_const0_4"
17892 [(set (match_operand:DF 0 "register_operand" "=&Y")
17893 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17894 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17895 (match_operand:DF 5 "register_operand" "0")])
17896 (match_operand:DF 2 "const0_operand" "X")
17897 (match_operand:DF 3 "register_operand" "Y")))]
17898 "TARGET_SSE2"
17899 "#")
17900
17901 (define_split
17902 [(set (match_operand 0 "register_operand" "")
17903 (if_then_else (match_operator 1 "comparison_operator"
17904 [(match_operand 4 "nonimmediate_operand" "")
17905 (match_operand 5 "nonimmediate_operand" "")])
17906 (match_operand 2 "nonmemory_operand" "")
17907 (match_operand 3 "nonmemory_operand" "")))]
17908 "SSE_REG_P (operands[0]) && reload_completed
17909 && (const0_operand (operands[2], GET_MODE (operands[0]))
17910 || const0_operand (operands[3], GET_MODE (operands[0])))"
17911 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17912 (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17913 (match_dup 7)))]
17914 {
17915 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17916 && GET_MODE (operands[2]) == DFmode)
17917 {
17918 if (REG_P (operands[2]))
17919 {
17920 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17921 emit_insn (gen_sse2_unpcklpd (op, op, op));
17922 }
17923 if (REG_P (operands[3]))
17924 {
17925 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17926 emit_insn (gen_sse2_unpcklpd (op, op, op));
17927 }
17928 }
17929 PUT_MODE (operands[1], GET_MODE (operands[0]));
17930 if (!sse_comparison_operator (operands[1], VOIDmode)
17931 || !rtx_equal_p (operands[0], operands[4]))
17932 {
17933 rtx tmp = operands[5];
17934 operands[5] = operands[4];
17935 operands[4] = tmp;
17936 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17937 }
17938 if (!rtx_equal_p (operands[0], operands[4]))
17939 abort ();
17940 if (const0_operand (operands[2], GET_MODE (operands[0])))
17941 {
17942 operands[7] = operands[3];
17943 operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17944 0));
17945 }
17946 else
17947 {
17948 operands[7] = operands[2];
17949 operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17950 }
17951 operands[7] = simplify_gen_subreg (TImode, operands[7],
17952 GET_MODE (operands[7]), 0);
17953 })
17954
17955 (define_expand "allocate_stack_worker"
17956 [(match_operand:SI 0 "register_operand" "")]
17957 "TARGET_STACK_PROBE"
17958 {
17959 if (TARGET_64BIT)
17960 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17961 else
17962 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17963 DONE;
17964 })
17965
17966 (define_insn "allocate_stack_worker_1"
17967 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17968 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17969 (clobber (match_dup 0))
17970 (clobber (reg:CC 17))]
17971 "!TARGET_64BIT && TARGET_STACK_PROBE"
17972 "call\t__alloca"
17973 [(set_attr "type" "multi")
17974 (set_attr "length" "5")])
17975
17976 (define_insn "allocate_stack_worker_rex64"
17977 [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17978 (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17979 (clobber (match_dup 0))
17980 (clobber (reg:CC 17))]
17981 "TARGET_64BIT && TARGET_STACK_PROBE"
17982 "call\t__alloca"
17983 [(set_attr "type" "multi")
17984 (set_attr "length" "5")])
17985
17986 (define_expand "allocate_stack"
17987 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17988 (minus:SI (reg:SI 7)
17989 (match_operand:SI 1 "general_operand" "")))
17990 (clobber (reg:CC 17))])
17991 (parallel [(set (reg:SI 7)
17992 (minus:SI (reg:SI 7) (match_dup 1)))
17993 (clobber (reg:CC 17))])]
17994 "TARGET_STACK_PROBE"
17995 {
17996 #ifdef CHECK_STACK_LIMIT
17997 if (GET_CODE (operands[1]) == CONST_INT
17998 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17999 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18000 operands[1]));
18001 else
18002 #endif
18003 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18004 operands[1])));
18005
18006 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18007 DONE;
18008 })
18009
18010 (define_expand "builtin_setjmp_receiver"
18011 [(label_ref (match_operand 0 "" ""))]
18012 "!TARGET_64BIT && flag_pic"
18013 {
18014 emit_insn (gen_set_got (pic_offset_table_rtx));
18015 DONE;
18016 })
18017 \f
18018 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18019
18020 (define_split
18021 [(set (match_operand 0 "register_operand" "")
18022 (match_operator 3 "promotable_binary_operator"
18023 [(match_operand 1 "register_operand" "")
18024 (match_operand 2 "aligned_operand" "")]))
18025 (clobber (reg:CC 17))]
18026 "! TARGET_PARTIAL_REG_STALL && reload_completed
18027 && ((GET_MODE (operands[0]) == HImode
18028 && ((!optimize_size && !TARGET_FAST_PREFIX)
18029 || GET_CODE (operands[2]) != CONST_INT
18030 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18031 || (GET_MODE (operands[0]) == QImode
18032 && (TARGET_PROMOTE_QImode || optimize_size)))"
18033 [(parallel [(set (match_dup 0)
18034 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18035 (clobber (reg:CC 17))])]
18036 "operands[0] = gen_lowpart (SImode, operands[0]);
18037 operands[1] = gen_lowpart (SImode, operands[1]);
18038 if (GET_CODE (operands[3]) != ASHIFT)
18039 operands[2] = gen_lowpart (SImode, operands[2]);
18040 PUT_MODE (operands[3], SImode);")
18041
18042 ; Promote the QImode tests, as i386 has encoding of the AND
18043 ; instruction with 32-bit sign-extended immediate and thus the
18044 ; instruction size is unchanged, except in the %eax case for
18045 ; which it is increased by one byte, hence the ! optimize_size.
18046 (define_split
18047 [(set (reg 17)
18048 (compare (and (match_operand 1 "aligned_operand" "")
18049 (match_operand 2 "const_int_operand" ""))
18050 (const_int 0)))
18051 (set (match_operand 0 "register_operand" "")
18052 (and (match_dup 1) (match_dup 2)))]
18053 "! TARGET_PARTIAL_REG_STALL && reload_completed
18054 /* Ensure that the operand will remain sign-extended immediate. */
18055 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18056 && ! optimize_size
18057 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18058 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18059 [(parallel [(set (reg:CCNO 17)
18060 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18061 (const_int 0)))
18062 (set (match_dup 0)
18063 (and:SI (match_dup 1) (match_dup 2)))])]
18064 "operands[2]
18065 = gen_int_mode (INTVAL (operands[2])
18066 & GET_MODE_MASK (GET_MODE (operands[0])),
18067 SImode);
18068 operands[0] = gen_lowpart (SImode, operands[0]);
18069 operands[1] = gen_lowpart (SImode, operands[1]);")
18070
18071 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18072 ; the TEST instruction with 32-bit sign-extended immediate and thus
18073 ; the instruction size would at least double, which is not what we
18074 ; want even with ! optimize_size.
18075 (define_split
18076 [(set (reg 17)
18077 (compare (and (match_operand:HI 0 "aligned_operand" "")
18078 (match_operand:HI 1 "const_int_operand" ""))
18079 (const_int 0)))]
18080 "! TARGET_PARTIAL_REG_STALL && reload_completed
18081 /* Ensure that the operand will remain sign-extended immediate. */
18082 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18083 && ! TARGET_FAST_PREFIX
18084 && ! optimize_size"
18085 [(set (reg:CCNO 17)
18086 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18087 (const_int 0)))]
18088 "operands[1]
18089 = gen_int_mode (INTVAL (operands[1])
18090 & GET_MODE_MASK (GET_MODE (operands[0])),
18091 SImode);
18092 operands[0] = gen_lowpart (SImode, operands[0]);")
18093
18094 (define_split
18095 [(set (match_operand 0 "register_operand" "")
18096 (neg (match_operand 1 "register_operand" "")))
18097 (clobber (reg:CC 17))]
18098 "! TARGET_PARTIAL_REG_STALL && reload_completed
18099 && (GET_MODE (operands[0]) == HImode
18100 || (GET_MODE (operands[0]) == QImode
18101 && (TARGET_PROMOTE_QImode || optimize_size)))"
18102 [(parallel [(set (match_dup 0)
18103 (neg:SI (match_dup 1)))
18104 (clobber (reg:CC 17))])]
18105 "operands[0] = gen_lowpart (SImode, operands[0]);
18106 operands[1] = gen_lowpart (SImode, operands[1]);")
18107
18108 (define_split
18109 [(set (match_operand 0 "register_operand" "")
18110 (not (match_operand 1 "register_operand" "")))]
18111 "! TARGET_PARTIAL_REG_STALL && reload_completed
18112 && (GET_MODE (operands[0]) == HImode
18113 || (GET_MODE (operands[0]) == QImode
18114 && (TARGET_PROMOTE_QImode || optimize_size)))"
18115 [(set (match_dup 0)
18116 (not:SI (match_dup 1)))]
18117 "operands[0] = gen_lowpart (SImode, operands[0]);
18118 operands[1] = gen_lowpart (SImode, operands[1]);")
18119
18120 (define_split
18121 [(set (match_operand 0 "register_operand" "")
18122 (if_then_else (match_operator 1 "comparison_operator"
18123 [(reg 17) (const_int 0)])
18124 (match_operand 2 "register_operand" "")
18125 (match_operand 3 "register_operand" "")))]
18126 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18127 && (GET_MODE (operands[0]) == HImode
18128 || (GET_MODE (operands[0]) == QImode
18129 && (TARGET_PROMOTE_QImode || optimize_size)))"
18130 [(set (match_dup 0)
18131 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18132 "operands[0] = gen_lowpart (SImode, operands[0]);
18133 operands[2] = gen_lowpart (SImode, operands[2]);
18134 operands[3] = gen_lowpart (SImode, operands[3]);")
18135
18136 \f
18137 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18138 ;; transform a complex memory operation into two memory to register operations.
18139
18140 ;; Don't push memory operands
18141 (define_peephole2
18142 [(set (match_operand:SI 0 "push_operand" "")
18143 (match_operand:SI 1 "memory_operand" ""))
18144 (match_scratch:SI 2 "r")]
18145 "! optimize_size && ! TARGET_PUSH_MEMORY"
18146 [(set (match_dup 2) (match_dup 1))
18147 (set (match_dup 0) (match_dup 2))]
18148 "")
18149
18150 (define_peephole2
18151 [(set (match_operand:DI 0 "push_operand" "")
18152 (match_operand:DI 1 "memory_operand" ""))
18153 (match_scratch:DI 2 "r")]
18154 "! optimize_size && ! TARGET_PUSH_MEMORY"
18155 [(set (match_dup 2) (match_dup 1))
18156 (set (match_dup 0) (match_dup 2))]
18157 "")
18158
18159 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18160 ;; SImode pushes.
18161 (define_peephole2
18162 [(set (match_operand:SF 0 "push_operand" "")
18163 (match_operand:SF 1 "memory_operand" ""))
18164 (match_scratch:SF 2 "r")]
18165 "! optimize_size && ! TARGET_PUSH_MEMORY"
18166 [(set (match_dup 2) (match_dup 1))
18167 (set (match_dup 0) (match_dup 2))]
18168 "")
18169
18170 (define_peephole2
18171 [(set (match_operand:HI 0 "push_operand" "")
18172 (match_operand:HI 1 "memory_operand" ""))
18173 (match_scratch:HI 2 "r")]
18174 "! optimize_size && ! TARGET_PUSH_MEMORY"
18175 [(set (match_dup 2) (match_dup 1))
18176 (set (match_dup 0) (match_dup 2))]
18177 "")
18178
18179 (define_peephole2
18180 [(set (match_operand:QI 0 "push_operand" "")
18181 (match_operand:QI 1 "memory_operand" ""))
18182 (match_scratch:QI 2 "q")]
18183 "! optimize_size && ! TARGET_PUSH_MEMORY"
18184 [(set (match_dup 2) (match_dup 1))
18185 (set (match_dup 0) (match_dup 2))]
18186 "")
18187
18188 ;; Don't move an immediate directly to memory when the instruction
18189 ;; gets too big.
18190 (define_peephole2
18191 [(match_scratch:SI 1 "r")
18192 (set (match_operand:SI 0 "memory_operand" "")
18193 (const_int 0))]
18194 "! optimize_size
18195 && ! TARGET_USE_MOV0
18196 && TARGET_SPLIT_LONG_MOVES
18197 && get_attr_length (insn) >= ix86_cost->large_insn
18198 && peep2_regno_dead_p (0, FLAGS_REG)"
18199 [(parallel [(set (match_dup 1) (const_int 0))
18200 (clobber (reg:CC 17))])
18201 (set (match_dup 0) (match_dup 1))]
18202 "")
18203
18204 (define_peephole2
18205 [(match_scratch:HI 1 "r")
18206 (set (match_operand:HI 0 "memory_operand" "")
18207 (const_int 0))]
18208 "! optimize_size
18209 && ! TARGET_USE_MOV0
18210 && TARGET_SPLIT_LONG_MOVES
18211 && get_attr_length (insn) >= ix86_cost->large_insn
18212 && peep2_regno_dead_p (0, FLAGS_REG)"
18213 [(parallel [(set (match_dup 2) (const_int 0))
18214 (clobber (reg:CC 17))])
18215 (set (match_dup 0) (match_dup 1))]
18216 "operands[2] = gen_lowpart (SImode, operands[1]);")
18217
18218 (define_peephole2
18219 [(match_scratch:QI 1 "q")
18220 (set (match_operand:QI 0 "memory_operand" "")
18221 (const_int 0))]
18222 "! optimize_size
18223 && ! TARGET_USE_MOV0
18224 && TARGET_SPLIT_LONG_MOVES
18225 && get_attr_length (insn) >= ix86_cost->large_insn
18226 && peep2_regno_dead_p (0, FLAGS_REG)"
18227 [(parallel [(set (match_dup 2) (const_int 0))
18228 (clobber (reg:CC 17))])
18229 (set (match_dup 0) (match_dup 1))]
18230 "operands[2] = gen_lowpart (SImode, operands[1]);")
18231
18232 (define_peephole2
18233 [(match_scratch:SI 2 "r")
18234 (set (match_operand:SI 0 "memory_operand" "")
18235 (match_operand:SI 1 "immediate_operand" ""))]
18236 "! optimize_size
18237 && get_attr_length (insn) >= ix86_cost->large_insn
18238 && TARGET_SPLIT_LONG_MOVES"
18239 [(set (match_dup 2) (match_dup 1))
18240 (set (match_dup 0) (match_dup 2))]
18241 "")
18242
18243 (define_peephole2
18244 [(match_scratch:HI 2 "r")
18245 (set (match_operand:HI 0 "memory_operand" "")
18246 (match_operand:HI 1 "immediate_operand" ""))]
18247 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18248 && TARGET_SPLIT_LONG_MOVES"
18249 [(set (match_dup 2) (match_dup 1))
18250 (set (match_dup 0) (match_dup 2))]
18251 "")
18252
18253 (define_peephole2
18254 [(match_scratch:QI 2 "q")
18255 (set (match_operand:QI 0 "memory_operand" "")
18256 (match_operand:QI 1 "immediate_operand" ""))]
18257 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18258 && TARGET_SPLIT_LONG_MOVES"
18259 [(set (match_dup 2) (match_dup 1))
18260 (set (match_dup 0) (match_dup 2))]
18261 "")
18262
18263 ;; Don't compare memory with zero, load and use a test instead.
18264 (define_peephole2
18265 [(set (reg 17)
18266 (compare (match_operand:SI 0 "memory_operand" "")
18267 (const_int 0)))
18268 (match_scratch:SI 3 "r")]
18269 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18270 [(set (match_dup 3) (match_dup 0))
18271 (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18272 "")
18273
18274 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18275 ;; Don't split NOTs with a displacement operand, because resulting XOR
18276 ;; will not be pairable anyway.
18277 ;;
18278 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18279 ;; represented using a modRM byte. The XOR replacement is long decoded,
18280 ;; so this split helps here as well.
18281 ;;
18282 ;; Note: Can't do this as a regular split because we can't get proper
18283 ;; lifetime information then.
18284
18285 (define_peephole2
18286 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18287 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18288 "!optimize_size
18289 && peep2_regno_dead_p (0, FLAGS_REG)
18290 && ((TARGET_PENTIUM
18291 && (GET_CODE (operands[0]) != MEM
18292 || !memory_displacement_operand (operands[0], SImode)))
18293 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18294 [(parallel [(set (match_dup 0)
18295 (xor:SI (match_dup 1) (const_int -1)))
18296 (clobber (reg:CC 17))])]
18297 "")
18298
18299 (define_peephole2
18300 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18301 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18302 "!optimize_size
18303 && peep2_regno_dead_p (0, FLAGS_REG)
18304 && ((TARGET_PENTIUM
18305 && (GET_CODE (operands[0]) != MEM
18306 || !memory_displacement_operand (operands[0], HImode)))
18307 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18308 [(parallel [(set (match_dup 0)
18309 (xor:HI (match_dup 1) (const_int -1)))
18310 (clobber (reg:CC 17))])]
18311 "")
18312
18313 (define_peephole2
18314 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18315 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18316 "!optimize_size
18317 && peep2_regno_dead_p (0, FLAGS_REG)
18318 && ((TARGET_PENTIUM
18319 && (GET_CODE (operands[0]) != MEM
18320 || !memory_displacement_operand (operands[0], QImode)))
18321 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18322 [(parallel [(set (match_dup 0)
18323 (xor:QI (match_dup 1) (const_int -1)))
18324 (clobber (reg:CC 17))])]
18325 "")
18326
18327 ;; Non pairable "test imm, reg" instructions can be translated to
18328 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18329 ;; byte opcode instead of two, have a short form for byte operands),
18330 ;; so do it for other CPUs as well. Given that the value was dead,
18331 ;; this should not create any new dependencies. Pass on the sub-word
18332 ;; versions if we're concerned about partial register stalls.
18333
18334 (define_peephole2
18335 [(set (reg 17)
18336 (compare (and:SI (match_operand:SI 0 "register_operand" "")
18337 (match_operand:SI 1 "immediate_operand" ""))
18338 (const_int 0)))]
18339 "ix86_match_ccmode (insn, CCNOmode)
18340 && (true_regnum (operands[0]) != 0
18341 || (GET_CODE (operands[1]) == CONST_INT
18342 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18343 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18344 [(parallel
18345 [(set (reg:CCNO 17)
18346 (compare:CCNO (and:SI (match_dup 0)
18347 (match_dup 1))
18348 (const_int 0)))
18349 (set (match_dup 0)
18350 (and:SI (match_dup 0) (match_dup 1)))])]
18351 "")
18352
18353 ;; We don't need to handle HImode case, because it will be promoted to SImode
18354 ;; on ! TARGET_PARTIAL_REG_STALL
18355
18356 (define_peephole2
18357 [(set (reg 17)
18358 (compare (and:QI (match_operand:QI 0 "register_operand" "")
18359 (match_operand:QI 1 "immediate_operand" ""))
18360 (const_int 0)))]
18361 "! TARGET_PARTIAL_REG_STALL
18362 && ix86_match_ccmode (insn, CCNOmode)
18363 && true_regnum (operands[0]) != 0
18364 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18365 [(parallel
18366 [(set (reg:CCNO 17)
18367 (compare:CCNO (and:QI (match_dup 0)
18368 (match_dup 1))
18369 (const_int 0)))
18370 (set (match_dup 0)
18371 (and:QI (match_dup 0) (match_dup 1)))])]
18372 "")
18373
18374 (define_peephole2
18375 [(set (reg 17)
18376 (compare
18377 (and:SI
18378 (zero_extract:SI
18379 (match_operand 0 "ext_register_operand" "")
18380 (const_int 8)
18381 (const_int 8))
18382 (match_operand 1 "const_int_operand" ""))
18383 (const_int 0)))]
18384 "! TARGET_PARTIAL_REG_STALL
18385 && ix86_match_ccmode (insn, CCNOmode)
18386 && true_regnum (operands[0]) != 0
18387 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18388 [(parallel [(set (reg:CCNO 17)
18389 (compare:CCNO
18390 (and:SI
18391 (zero_extract:SI
18392 (match_dup 0)
18393 (const_int 8)
18394 (const_int 8))
18395 (match_dup 1))
18396 (const_int 0)))
18397 (set (zero_extract:SI (match_dup 0)
18398 (const_int 8)
18399 (const_int 8))
18400 (and:SI
18401 (zero_extract:SI
18402 (match_dup 0)
18403 (const_int 8)
18404 (const_int 8))
18405 (match_dup 1)))])]
18406 "")
18407
18408 ;; Don't do logical operations with memory inputs.
18409 (define_peephole2
18410 [(match_scratch:SI 2 "r")
18411 (parallel [(set (match_operand:SI 0 "register_operand" "")
18412 (match_operator:SI 3 "arith_or_logical_operator"
18413 [(match_dup 0)
18414 (match_operand:SI 1 "memory_operand" "")]))
18415 (clobber (reg:CC 17))])]
18416 "! optimize_size && ! TARGET_READ_MODIFY"
18417 [(set (match_dup 2) (match_dup 1))
18418 (parallel [(set (match_dup 0)
18419 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18420 (clobber (reg:CC 17))])]
18421 "")
18422
18423 (define_peephole2
18424 [(match_scratch:SI 2 "r")
18425 (parallel [(set (match_operand:SI 0 "register_operand" "")
18426 (match_operator:SI 3 "arith_or_logical_operator"
18427 [(match_operand:SI 1 "memory_operand" "")
18428 (match_dup 0)]))
18429 (clobber (reg:CC 17))])]
18430 "! optimize_size && ! TARGET_READ_MODIFY"
18431 [(set (match_dup 2) (match_dup 1))
18432 (parallel [(set (match_dup 0)
18433 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18434 (clobber (reg:CC 17))])]
18435 "")
18436
18437 ; Don't do logical operations with memory outputs
18438 ;
18439 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18440 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18441 ; the same decoder scheduling characteristics as the original.
18442
18443 (define_peephole2
18444 [(match_scratch:SI 2 "r")
18445 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18446 (match_operator:SI 3 "arith_or_logical_operator"
18447 [(match_dup 0)
18448 (match_operand:SI 1 "nonmemory_operand" "")]))
18449 (clobber (reg:CC 17))])]
18450 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18451 [(set (match_dup 2) (match_dup 0))
18452 (parallel [(set (match_dup 2)
18453 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18454 (clobber (reg:CC 17))])
18455 (set (match_dup 0) (match_dup 2))]
18456 "")
18457
18458 (define_peephole2
18459 [(match_scratch:SI 2 "r")
18460 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18461 (match_operator:SI 3 "arith_or_logical_operator"
18462 [(match_operand:SI 1 "nonmemory_operand" "")
18463 (match_dup 0)]))
18464 (clobber (reg:CC 17))])]
18465 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18466 [(set (match_dup 2) (match_dup 0))
18467 (parallel [(set (match_dup 2)
18468 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18469 (clobber (reg:CC 17))])
18470 (set (match_dup 0) (match_dup 2))]
18471 "")
18472
18473 ;; Attempt to always use XOR for zeroing registers.
18474 (define_peephole2
18475 [(set (match_operand 0 "register_operand" "")
18476 (const_int 0))]
18477 "(GET_MODE (operands[0]) == QImode
18478 || GET_MODE (operands[0]) == HImode
18479 || GET_MODE (operands[0]) == SImode
18480 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18481 && (! TARGET_USE_MOV0 || optimize_size)
18482 && peep2_regno_dead_p (0, FLAGS_REG)"
18483 [(parallel [(set (match_dup 0) (const_int 0))
18484 (clobber (reg:CC 17))])]
18485 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18486 operands[0]);")
18487
18488 (define_peephole2
18489 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18490 (const_int 0))]
18491 "(GET_MODE (operands[0]) == QImode
18492 || GET_MODE (operands[0]) == HImode)
18493 && (! TARGET_USE_MOV0 || optimize_size)
18494 && peep2_regno_dead_p (0, FLAGS_REG)"
18495 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18496 (clobber (reg:CC 17))])])
18497
18498 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18499 (define_peephole2
18500 [(set (match_operand 0 "register_operand" "")
18501 (const_int -1))]
18502 "(GET_MODE (operands[0]) == HImode
18503 || GET_MODE (operands[0]) == SImode
18504 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18505 && (optimize_size || TARGET_PENTIUM)
18506 && peep2_regno_dead_p (0, FLAGS_REG)"
18507 [(parallel [(set (match_dup 0) (const_int -1))
18508 (clobber (reg:CC 17))])]
18509 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18510 operands[0]);")
18511
18512 ;; Attempt to convert simple leas to adds. These can be created by
18513 ;; move expanders.
18514 (define_peephole2
18515 [(set (match_operand:SI 0 "register_operand" "")
18516 (plus:SI (match_dup 0)
18517 (match_operand:SI 1 "nonmemory_operand" "")))]
18518 "peep2_regno_dead_p (0, FLAGS_REG)"
18519 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18520 (clobber (reg:CC 17))])]
18521 "")
18522
18523 (define_peephole2
18524 [(set (match_operand:SI 0 "register_operand" "")
18525 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18526 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18527 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18528 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18529 (clobber (reg:CC 17))])]
18530 "operands[2] = gen_lowpart (SImode, operands[2]);")
18531
18532 (define_peephole2
18533 [(set (match_operand:DI 0 "register_operand" "")
18534 (plus:DI (match_dup 0)
18535 (match_operand:DI 1 "x86_64_general_operand" "")))]
18536 "peep2_regno_dead_p (0, FLAGS_REG)"
18537 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18538 (clobber (reg:CC 17))])]
18539 "")
18540
18541 (define_peephole2
18542 [(set (match_operand:SI 0 "register_operand" "")
18543 (mult:SI (match_dup 0)
18544 (match_operand:SI 1 "const_int_operand" "")))]
18545 "exact_log2 (INTVAL (operands[1])) >= 0
18546 && peep2_regno_dead_p (0, FLAGS_REG)"
18547 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18548 (clobber (reg:CC 17))])]
18549 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18550
18551 (define_peephole2
18552 [(set (match_operand:DI 0 "register_operand" "")
18553 (mult:DI (match_dup 0)
18554 (match_operand:DI 1 "const_int_operand" "")))]
18555 "exact_log2 (INTVAL (operands[1])) >= 0
18556 && peep2_regno_dead_p (0, FLAGS_REG)"
18557 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18558 (clobber (reg:CC 17))])]
18559 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18560
18561 (define_peephole2
18562 [(set (match_operand:SI 0 "register_operand" "")
18563 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18564 (match_operand:DI 2 "const_int_operand" "")) 0))]
18565 "exact_log2 (INTVAL (operands[2])) >= 0
18566 && REGNO (operands[0]) == REGNO (operands[1])
18567 && peep2_regno_dead_p (0, FLAGS_REG)"
18568 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18569 (clobber (reg:CC 17))])]
18570 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18571
18572 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18573 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
18574 ;; many CPUs it is also faster, since special hardware to avoid esp
18575 ;; dependencies is present.
18576
18577 ;; While some of these conversions may be done using splitters, we use peepholes
18578 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18579
18580 ;; Convert prologue esp subtractions to push.
18581 ;; We need register to push. In order to keep verify_flow_info happy we have
18582 ;; two choices
18583 ;; - use scratch and clobber it in order to avoid dependencies
18584 ;; - use already live register
18585 ;; We can't use the second way right now, since there is no reliable way how to
18586 ;; verify that given register is live. First choice will also most likely in
18587 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18588 ;; call clobbered registers are dead. We may want to use base pointer as an
18589 ;; alternative when no register is available later.
18590
18591 (define_peephole2
18592 [(match_scratch:SI 0 "r")
18593 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18594 (clobber (reg:CC 17))
18595 (clobber (mem:BLK (scratch)))])]
18596 "optimize_size || !TARGET_SUB_ESP_4"
18597 [(clobber (match_dup 0))
18598 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18599 (clobber (mem:BLK (scratch)))])])
18600
18601 (define_peephole2
18602 [(match_scratch:SI 0 "r")
18603 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18604 (clobber (reg:CC 17))
18605 (clobber (mem:BLK (scratch)))])]
18606 "optimize_size || !TARGET_SUB_ESP_8"
18607 [(clobber (match_dup 0))
18608 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18609 (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18610 (clobber (mem:BLK (scratch)))])])
18611
18612 ;; Convert esp subtractions to push.
18613 (define_peephole2
18614 [(match_scratch:SI 0 "r")
18615 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18616 (clobber (reg:CC 17))])]
18617 "optimize_size || !TARGET_SUB_ESP_4"
18618 [(clobber (match_dup 0))
18619 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18620
18621 (define_peephole2
18622 [(match_scratch:SI 0 "r")
18623 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18624 (clobber (reg:CC 17))])]
18625 "optimize_size || !TARGET_SUB_ESP_8"
18626 [(clobber (match_dup 0))
18627 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18628 (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18629
18630 ;; Convert epilogue deallocator to pop.
18631 (define_peephole2
18632 [(match_scratch:SI 0 "r")
18633 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18634 (clobber (reg:CC 17))
18635 (clobber (mem:BLK (scratch)))])]
18636 "optimize_size || !TARGET_ADD_ESP_4"
18637 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18638 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18639 (clobber (mem:BLK (scratch)))])]
18640 "")
18641
18642 ;; Two pops case is tricky, since pop causes dependency on destination register.
18643 ;; We use two registers if available.
18644 (define_peephole2
18645 [(match_scratch:SI 0 "r")
18646 (match_scratch:SI 1 "r")
18647 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18648 (clobber (reg:CC 17))
18649 (clobber (mem:BLK (scratch)))])]
18650 "optimize_size || !TARGET_ADD_ESP_8"
18651 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18652 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18653 (clobber (mem:BLK (scratch)))])
18654 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18655 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18656 "")
18657
18658 (define_peephole2
18659 [(match_scratch:SI 0 "r")
18660 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18661 (clobber (reg:CC 17))
18662 (clobber (mem:BLK (scratch)))])]
18663 "optimize_size"
18664 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18665 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18666 (clobber (mem:BLK (scratch)))])
18667 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18668 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18669 "")
18670
18671 ;; Convert esp additions to pop.
18672 (define_peephole2
18673 [(match_scratch:SI 0 "r")
18674 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18675 (clobber (reg:CC 17))])]
18676 ""
18677 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18678 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18679 "")
18680
18681 ;; Two pops case is tricky, since pop causes dependency on destination register.
18682 ;; We use two registers if available.
18683 (define_peephole2
18684 [(match_scratch:SI 0 "r")
18685 (match_scratch:SI 1 "r")
18686 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18687 (clobber (reg:CC 17))])]
18688 ""
18689 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18690 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18691 (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18692 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18693 "")
18694
18695 (define_peephole2
18696 [(match_scratch:SI 0 "r")
18697 (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18698 (clobber (reg:CC 17))])]
18699 "optimize_size"
18700 [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18701 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18702 (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18703 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18704 "")
18705 \f
18706 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18707 ;; required and register dies.
18708 (define_peephole2
18709 [(set (reg 17)
18710 (compare (match_operand:SI 0 "register_operand" "")
18711 (match_operand:SI 1 "incdec_operand" "")))]
18712 "ix86_match_ccmode (insn, CCGCmode)
18713 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18714 [(parallel [(set (reg:CCGC 17)
18715 (compare:CCGC (match_dup 0)
18716 (match_dup 1)))
18717 (clobber (match_dup 0))])]
18718 "")
18719
18720 (define_peephole2
18721 [(set (reg 17)
18722 (compare (match_operand:HI 0 "register_operand" "")
18723 (match_operand:HI 1 "incdec_operand" "")))]
18724 "ix86_match_ccmode (insn, CCGCmode)
18725 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18726 [(parallel [(set (reg:CCGC 17)
18727 (compare:CCGC (match_dup 0)
18728 (match_dup 1)))
18729 (clobber (match_dup 0))])]
18730 "")
18731
18732 (define_peephole2
18733 [(set (reg 17)
18734 (compare (match_operand:QI 0 "register_operand" "")
18735 (match_operand:QI 1 "incdec_operand" "")))]
18736 "ix86_match_ccmode (insn, CCGCmode)
18737 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18738 [(parallel [(set (reg:CCGC 17)
18739 (compare:CCGC (match_dup 0)
18740 (match_dup 1)))
18741 (clobber (match_dup 0))])]
18742 "")
18743
18744 ;; Convert compares with 128 to shorter add -128
18745 (define_peephole2
18746 [(set (reg 17)
18747 (compare (match_operand:SI 0 "register_operand" "")
18748 (const_int 128)))]
18749 "ix86_match_ccmode (insn, CCGCmode)
18750 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18751 [(parallel [(set (reg:CCGC 17)
18752 (compare:CCGC (match_dup 0)
18753 (const_int 128)))
18754 (clobber (match_dup 0))])]
18755 "")
18756
18757 (define_peephole2
18758 [(set (reg 17)
18759 (compare (match_operand:HI 0 "register_operand" "")
18760 (const_int 128)))]
18761 "ix86_match_ccmode (insn, CCGCmode)
18762 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18763 [(parallel [(set (reg:CCGC 17)
18764 (compare:CCGC (match_dup 0)
18765 (const_int 128)))
18766 (clobber (match_dup 0))])]
18767 "")
18768 \f
18769 (define_peephole2
18770 [(match_scratch:DI 0 "r")
18771 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18772 (clobber (reg:CC 17))
18773 (clobber (mem:BLK (scratch)))])]
18774 "optimize_size || !TARGET_SUB_ESP_4"
18775 [(clobber (match_dup 0))
18776 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18777 (clobber (mem:BLK (scratch)))])])
18778
18779 (define_peephole2
18780 [(match_scratch:DI 0 "r")
18781 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18782 (clobber (reg:CC 17))
18783 (clobber (mem:BLK (scratch)))])]
18784 "optimize_size || !TARGET_SUB_ESP_8"
18785 [(clobber (match_dup 0))
18786 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18787 (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18788 (clobber (mem:BLK (scratch)))])])
18789
18790 ;; Convert esp subtractions to push.
18791 (define_peephole2
18792 [(match_scratch:DI 0 "r")
18793 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18794 (clobber (reg:CC 17))])]
18795 "optimize_size || !TARGET_SUB_ESP_4"
18796 [(clobber (match_dup 0))
18797 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18798
18799 (define_peephole2
18800 [(match_scratch:DI 0 "r")
18801 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18802 (clobber (reg:CC 17))])]
18803 "optimize_size || !TARGET_SUB_ESP_8"
18804 [(clobber (match_dup 0))
18805 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18806 (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18807
18808 ;; Convert epilogue deallocator to pop.
18809 (define_peephole2
18810 [(match_scratch:DI 0 "r")
18811 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18812 (clobber (reg:CC 17))
18813 (clobber (mem:BLK (scratch)))])]
18814 "optimize_size || !TARGET_ADD_ESP_4"
18815 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18816 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18817 (clobber (mem:BLK (scratch)))])]
18818 "")
18819
18820 ;; Two pops case is tricky, since pop causes dependency on destination register.
18821 ;; We use two registers if available.
18822 (define_peephole2
18823 [(match_scratch:DI 0 "r")
18824 (match_scratch:DI 1 "r")
18825 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18826 (clobber (reg:CC 17))
18827 (clobber (mem:BLK (scratch)))])]
18828 "optimize_size || !TARGET_ADD_ESP_8"
18829 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18830 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18831 (clobber (mem:BLK (scratch)))])
18832 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18833 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18834 "")
18835
18836 (define_peephole2
18837 [(match_scratch:DI 0 "r")
18838 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18839 (clobber (reg:CC 17))
18840 (clobber (mem:BLK (scratch)))])]
18841 "optimize_size"
18842 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18843 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18844 (clobber (mem:BLK (scratch)))])
18845 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18846 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18847 "")
18848
18849 ;; Convert esp additions to pop.
18850 (define_peephole2
18851 [(match_scratch:DI 0 "r")
18852 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18853 (clobber (reg:CC 17))])]
18854 ""
18855 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18856 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18857 "")
18858
18859 ;; Two pops case is tricky, since pop causes dependency on destination register.
18860 ;; We use two registers if available.
18861 (define_peephole2
18862 [(match_scratch:DI 0 "r")
18863 (match_scratch:DI 1 "r")
18864 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18865 (clobber (reg:CC 17))])]
18866 ""
18867 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18868 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18869 (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18870 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18871 "")
18872
18873 (define_peephole2
18874 [(match_scratch:DI 0 "r")
18875 (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18876 (clobber (reg:CC 17))])]
18877 "optimize_size"
18878 [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18879 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18880 (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18881 (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18882 "")
18883 \f
18884 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18885 ;; imul $32bit_imm, reg, reg is direct decoded.
18886 (define_peephole2
18887 [(match_scratch:DI 3 "r")
18888 (parallel [(set (match_operand:DI 0 "register_operand" "")
18889 (mult:DI (match_operand:DI 1 "memory_operand" "")
18890 (match_operand:DI 2 "immediate_operand" "")))
18891 (clobber (reg:CC 17))])]
18892 "TARGET_K8 && !optimize_size
18893 && (GET_CODE (operands[2]) != CONST_INT
18894 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18895 [(set (match_dup 3) (match_dup 1))
18896 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18897 (clobber (reg:CC 17))])]
18898 "")
18899
18900 (define_peephole2
18901 [(match_scratch:SI 3 "r")
18902 (parallel [(set (match_operand:SI 0 "register_operand" "")
18903 (mult:SI (match_operand:SI 1 "memory_operand" "")
18904 (match_operand:SI 2 "immediate_operand" "")))
18905 (clobber (reg:CC 17))])]
18906 "TARGET_K8 && !optimize_size
18907 && (GET_CODE (operands[2]) != CONST_INT
18908 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18909 [(set (match_dup 3) (match_dup 1))
18910 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18911 (clobber (reg:CC 17))])]
18912 "")
18913
18914 (define_peephole2
18915 [(match_scratch:SI 3 "r")
18916 (parallel [(set (match_operand:DI 0 "register_operand" "")
18917 (zero_extend:DI
18918 (mult:SI (match_operand:SI 1 "memory_operand" "")
18919 (match_operand:SI 2 "immediate_operand" ""))))
18920 (clobber (reg:CC 17))])]
18921 "TARGET_K8 && !optimize_size
18922 && (GET_CODE (operands[2]) != CONST_INT
18923 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18924 [(set (match_dup 3) (match_dup 1))
18925 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18926 (clobber (reg:CC 17))])]
18927 "")
18928
18929 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18930 ;; Convert it into imul reg, reg
18931 ;; It would be better to force assembler to encode instruction using long
18932 ;; immediate, but there is apparently no way to do so.
18933 (define_peephole2
18934 [(parallel [(set (match_operand:DI 0 "register_operand" "")
18935 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18936 (match_operand:DI 2 "const_int_operand" "")))
18937 (clobber (reg:CC 17))])
18938 (match_scratch:DI 3 "r")]
18939 "TARGET_K8 && !optimize_size
18940 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18941 [(set (match_dup 3) (match_dup 2))
18942 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18943 (clobber (reg:CC 17))])]
18944 {
18945 if (!rtx_equal_p (operands[0], operands[1]))
18946 emit_move_insn (operands[0], operands[1]);
18947 })
18948
18949 (define_peephole2
18950 [(parallel [(set (match_operand:SI 0 "register_operand" "")
18951 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18952 (match_operand:SI 2 "const_int_operand" "")))
18953 (clobber (reg:CC 17))])
18954 (match_scratch:SI 3 "r")]
18955 "TARGET_K8 && !optimize_size
18956 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18957 [(set (match_dup 3) (match_dup 2))
18958 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18959 (clobber (reg:CC 17))])]
18960 {
18961 if (!rtx_equal_p (operands[0], operands[1]))
18962 emit_move_insn (operands[0], operands[1]);
18963 })
18964
18965 (define_peephole2
18966 [(parallel [(set (match_operand:HI 0 "register_operand" "")
18967 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18968 (match_operand:HI 2 "immediate_operand" "")))
18969 (clobber (reg:CC 17))])
18970 (match_scratch:HI 3 "r")]
18971 "TARGET_K8 && !optimize_size"
18972 [(set (match_dup 3) (match_dup 2))
18973 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18974 (clobber (reg:CC 17))])]
18975 {
18976 if (!rtx_equal_p (operands[0], operands[1]))
18977 emit_move_insn (operands[0], operands[1]);
18978 })
18979 \f
18980 ;; Call-value patterns last so that the wildcard operand does not
18981 ;; disrupt insn-recog's switch tables.
18982
18983 (define_insn "*call_value_pop_0"
18984 [(set (match_operand 0 "" "")
18985 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18986 (match_operand:SI 2 "" "")))
18987 (set (reg:SI 7) (plus:SI (reg:SI 7)
18988 (match_operand:SI 3 "immediate_operand" "")))]
18989 "!TARGET_64BIT"
18990 {
18991 if (SIBLING_CALL_P (insn))
18992 return "jmp\t%P1";
18993 else
18994 return "call\t%P1";
18995 }
18996 [(set_attr "type" "callv")])
18997
18998 (define_insn "*call_value_pop_1"
18999 [(set (match_operand 0 "" "")
19000 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19001 (match_operand:SI 2 "" "")))
19002 (set (reg:SI 7) (plus:SI (reg:SI 7)
19003 (match_operand:SI 3 "immediate_operand" "i")))]
19004 "!TARGET_64BIT"
19005 {
19006 if (constant_call_address_operand (operands[1], QImode))
19007 {
19008 if (SIBLING_CALL_P (insn))
19009 return "jmp\t%P1";
19010 else
19011 return "call\t%P1";
19012 }
19013 if (SIBLING_CALL_P (insn))
19014 return "jmp\t%A1";
19015 else
19016 return "call\t%A1";
19017 }
19018 [(set_attr "type" "callv")])
19019
19020 (define_insn "*call_value_0"
19021 [(set (match_operand 0 "" "")
19022 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19023 (match_operand:SI 2 "" "")))]
19024 "!TARGET_64BIT"
19025 {
19026 if (SIBLING_CALL_P (insn))
19027 return "jmp\t%P1";
19028 else
19029 return "call\t%P1";
19030 }
19031 [(set_attr "type" "callv")])
19032
19033 (define_insn "*call_value_0_rex64"
19034 [(set (match_operand 0 "" "")
19035 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19036 (match_operand:DI 2 "const_int_operand" "")))]
19037 "TARGET_64BIT"
19038 {
19039 if (SIBLING_CALL_P (insn))
19040 return "jmp\t%P1";
19041 else
19042 return "call\t%P1";
19043 }
19044 [(set_attr "type" "callv")])
19045
19046 (define_insn "*call_value_1"
19047 [(set (match_operand 0 "" "")
19048 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19049 (match_operand:SI 2 "" "")))]
19050 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19051 {
19052 if (constant_call_address_operand (operands[1], QImode))
19053 return "call\t%P1";
19054 return "call\t%*%1";
19055 }
19056 [(set_attr "type" "callv")])
19057
19058 (define_insn "*sibcall_value_1"
19059 [(set (match_operand 0 "" "")
19060 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19061 (match_operand:SI 2 "" "")))]
19062 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19063 {
19064 if (constant_call_address_operand (operands[1], QImode))
19065 return "jmp\t%P1";
19066 return "jmp\t%*%1";
19067 }
19068 [(set_attr "type" "callv")])
19069
19070 (define_insn "*call_value_1_rex64"
19071 [(set (match_operand 0 "" "")
19072 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19073 (match_operand:DI 2 "" "")))]
19074 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19075 {
19076 if (constant_call_address_operand (operands[1], QImode))
19077 return "call\t%P1";
19078 return "call\t%A1";
19079 }
19080 [(set_attr "type" "callv")])
19081
19082 (define_insn "*sibcall_value_1_rex64"
19083 [(set (match_operand 0 "" "")
19084 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19085 (match_operand:DI 2 "" "")))]
19086 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19087 "jmp\t%P1"
19088 [(set_attr "type" "callv")])
19089
19090 (define_insn "*sibcall_value_1_rex64_v"
19091 [(set (match_operand 0 "" "")
19092 (call (mem:QI (reg:DI 40))
19093 (match_operand:DI 1 "" "")))]
19094 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19095 "jmp\t*%%r11"
19096 [(set_attr "type" "callv")])
19097 \f
19098 (define_insn "trap"
19099 [(trap_if (const_int 1) (const_int 5))]
19100 ""
19101 "int\t$5")
19102
19103 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19104 ;;; for the sake of bounds checking. By emitting bounds checks as
19105 ;;; conditional traps rather than as conditional jumps around
19106 ;;; unconditional traps we avoid introducing spurious basic-block
19107 ;;; boundaries and facilitate elimination of redundant checks. In
19108 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19109 ;;; interrupt 5.
19110 ;;;
19111 ;;; FIXME: Static branch prediction rules for ix86 are such that
19112 ;;; forward conditional branches predict as untaken. As implemented
19113 ;;; below, pseudo conditional traps violate that rule. We should use
19114 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19115 ;;; section loaded at the end of the text segment and branch forward
19116 ;;; there on bounds-failure, and then jump back immediately (in case
19117 ;;; the system chooses to ignore bounds violations, or to report
19118 ;;; violations and continue execution).
19119
19120 (define_expand "conditional_trap"
19121 [(trap_if (match_operator 0 "comparison_operator"
19122 [(match_dup 2) (const_int 0)])
19123 (match_operand 1 "const_int_operand" ""))]
19124 ""
19125 {
19126 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19127 ix86_expand_compare (GET_CODE (operands[0]),
19128 NULL, NULL),
19129 operands[1]));
19130 DONE;
19131 })
19132
19133 (define_insn "*conditional_trap_1"
19134 [(trap_if (match_operator 0 "comparison_operator"
19135 [(reg 17) (const_int 0)])
19136 (match_operand 1 "const_int_operand" ""))]
19137 ""
19138 {
19139 operands[2] = gen_label_rtx ();
19140 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19141 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19142 CODE_LABEL_NUMBER (operands[2]));
19143 RET;
19144 })
19145
19146 ;; Pentium III SIMD instructions.
19147
19148 ;; Moves for SSE/MMX regs.
19149
19150 (define_insn "movv4sf_internal"
19151 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
19152 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
19153 "TARGET_SSE"
19154 "@
19155 xorps\t%0, %0
19156 movaps\t{%1, %0|%0, %1}
19157 movaps\t{%1, %0|%0, %1}"
19158 [(set_attr "type" "ssemov")
19159 (set_attr "mode" "V4SF")])
19160
19161 (define_split
19162 [(set (match_operand:V4SF 0 "register_operand" "")
19163 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
19164 "TARGET_SSE"
19165 [(set (match_dup 0)
19166 (vec_merge:V4SF
19167 (vec_duplicate:V4SF (match_dup 1))
19168 (match_dup 2)
19169 (const_int 1)))]
19170 {
19171 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
19172 operands[2] = CONST0_RTX (V4SFmode);
19173 })
19174
19175 (define_insn "movv4si_internal"
19176 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
19177 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
19178 "TARGET_SSE"
19179 {
19180 switch (which_alternative)
19181 {
19182 case 0:
19183 if (get_attr_mode (insn) == MODE_V4SF)
19184 return "xorps\t%0, %0";
19185 else
19186 return "pxor\t%0, %0";
19187 case 1:
19188 case 2:
19189 if (get_attr_mode (insn) == MODE_V4SF)
19190 return "movaps\t{%1, %0|%0, %1}";
19191 else
19192 return "movdqa\t{%1, %0|%0, %1}";
19193 default:
19194 abort ();
19195 }
19196 }
19197 [(set_attr "type" "ssemov")
19198 (set (attr "mode")
19199 (cond [(eq_attr "alternative" "0,1")
19200 (if_then_else
19201 (ne (symbol_ref "optimize_size")
19202 (const_int 0))
19203 (const_string "V4SF")
19204 (const_string "TI"))
19205 (eq_attr "alternative" "2")
19206 (if_then_else
19207 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19208 (const_int 0))
19209 (ne (symbol_ref "optimize_size")
19210 (const_int 0)))
19211 (const_string "V4SF")
19212 (const_string "TI"))]
19213 (const_string "TI")))])
19214
19215 (define_insn "movv2di_internal"
19216 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19217 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19218 "TARGET_SSE2"
19219 {
19220 switch (which_alternative)
19221 {
19222 case 0:
19223 if (get_attr_mode (insn) == MODE_V4SF)
19224 return "xorps\t%0, %0";
19225 else
19226 return "pxor\t%0, %0";
19227 case 1:
19228 case 2:
19229 if (get_attr_mode (insn) == MODE_V4SF)
19230 return "movaps\t{%1, %0|%0, %1}";
19231 else
19232 return "movdqa\t{%1, %0|%0, %1}";
19233 default:
19234 abort ();
19235 }
19236 }
19237 [(set_attr "type" "ssemov")
19238 (set (attr "mode")
19239 (cond [(eq_attr "alternative" "0,1")
19240 (if_then_else
19241 (ne (symbol_ref "optimize_size")
19242 (const_int 0))
19243 (const_string "V4SF")
19244 (const_string "TI"))
19245 (eq_attr "alternative" "2")
19246 (if_then_else
19247 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19248 (const_int 0))
19249 (ne (symbol_ref "optimize_size")
19250 (const_int 0)))
19251 (const_string "V4SF")
19252 (const_string "TI"))]
19253 (const_string "TI")))])
19254
19255 (define_split
19256 [(set (match_operand:V2DF 0 "register_operand" "")
19257 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19258 "TARGET_SSE2"
19259 [(set (match_dup 0)
19260 (vec_merge:V2DF
19261 (vec_duplicate:V2DF (match_dup 1))
19262 (match_dup 2)
19263 (const_int 1)))]
19264 {
19265 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19266 operands[2] = CONST0_RTX (V2DFmode);
19267 })
19268
19269 (define_insn "movv8qi_internal"
19270 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19271 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19272 "TARGET_MMX
19273 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19274 "@
19275 pxor\t%0, %0
19276 movq\t{%1, %0|%0, %1}
19277 movq\t{%1, %0|%0, %1}"
19278 [(set_attr "type" "mmxmov")
19279 (set_attr "mode" "DI")])
19280
19281 (define_insn "movv4hi_internal"
19282 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19283 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19284 "TARGET_MMX
19285 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19286 "@
19287 pxor\t%0, %0
19288 movq\t{%1, %0|%0, %1}
19289 movq\t{%1, %0|%0, %1}"
19290 [(set_attr "type" "mmxmov")
19291 (set_attr "mode" "DI")])
19292
19293 (define_insn "movv2si_internal"
19294 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19295 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19296 "TARGET_MMX
19297 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19298 "@
19299 pxor\t%0, %0
19300 movq\t{%1, %0|%0, %1}
19301 movq\t{%1, %0|%0, %1}"
19302 [(set_attr "type" "mmxcvt")
19303 (set_attr "mode" "DI")])
19304
19305 (define_insn "movv2sf_internal"
19306 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19307 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19308 "TARGET_3DNOW
19309 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19310 "@
19311 pxor\t%0, %0
19312 movq\t{%1, %0|%0, %1}
19313 movq\t{%1, %0|%0, %1}"
19314 [(set_attr "type" "mmxcvt")
19315 (set_attr "mode" "DI")])
19316
19317 (define_expand "movti"
19318 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19319 (match_operand:TI 1 "nonimmediate_operand" ""))]
19320 "TARGET_SSE || TARGET_64BIT"
19321 {
19322 if (TARGET_64BIT)
19323 ix86_expand_move (TImode, operands);
19324 else
19325 ix86_expand_vector_move (TImode, operands);
19326 DONE;
19327 })
19328
19329 (define_insn "movv2df_internal"
19330 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19331 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19332 "TARGET_SSE2
19333 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19334 {
19335 switch (which_alternative)
19336 {
19337 case 0:
19338 if (get_attr_mode (insn) == MODE_V4SF)
19339 return "xorps\t%0, %0";
19340 else
19341 return "xorpd\t%0, %0";
19342 case 1:
19343 case 2:
19344 if (get_attr_mode (insn) == MODE_V4SF)
19345 return "movaps\t{%1, %0|%0, %1}";
19346 else
19347 return "movapd\t{%1, %0|%0, %1}";
19348 default:
19349 abort ();
19350 }
19351 }
19352 [(set_attr "type" "ssemov")
19353 (set (attr "mode")
19354 (cond [(eq_attr "alternative" "0,1")
19355 (if_then_else
19356 (ne (symbol_ref "optimize_size")
19357 (const_int 0))
19358 (const_string "V4SF")
19359 (const_string "V2DF"))
19360 (eq_attr "alternative" "2")
19361 (if_then_else
19362 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19363 (const_int 0))
19364 (ne (symbol_ref "optimize_size")
19365 (const_int 0)))
19366 (const_string "V4SF")
19367 (const_string "V2DF"))]
19368 (const_string "V2DF")))])
19369
19370 (define_insn "movv8hi_internal"
19371 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19372 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19373 "TARGET_SSE2
19374 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19375 {
19376 switch (which_alternative)
19377 {
19378 case 0:
19379 if (get_attr_mode (insn) == MODE_V4SF)
19380 return "xorps\t%0, %0";
19381 else
19382 return "pxor\t%0, %0";
19383 case 1:
19384 case 2:
19385 if (get_attr_mode (insn) == MODE_V4SF)
19386 return "movaps\t{%1, %0|%0, %1}";
19387 else
19388 return "movdqa\t{%1, %0|%0, %1}";
19389 default:
19390 abort ();
19391 }
19392 }
19393 [(set_attr "type" "ssemov")
19394 (set (attr "mode")
19395 (cond [(eq_attr "alternative" "0,1")
19396 (if_then_else
19397 (ne (symbol_ref "optimize_size")
19398 (const_int 0))
19399 (const_string "V4SF")
19400 (const_string "TI"))
19401 (eq_attr "alternative" "2")
19402 (if_then_else
19403 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19404 (const_int 0))
19405 (ne (symbol_ref "optimize_size")
19406 (const_int 0)))
19407 (const_string "V4SF")
19408 (const_string "TI"))]
19409 (const_string "TI")))])
19410
19411 (define_insn "movv16qi_internal"
19412 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19413 (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19414 "TARGET_SSE2
19415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19416 {
19417 switch (which_alternative)
19418 {
19419 case 0:
19420 if (get_attr_mode (insn) == MODE_V4SF)
19421 return "xorps\t%0, %0";
19422 else
19423 return "pxor\t%0, %0";
19424 case 1:
19425 case 2:
19426 if (get_attr_mode (insn) == MODE_V4SF)
19427 return "movaps\t{%1, %0|%0, %1}";
19428 else
19429 return "movdqa\t{%1, %0|%0, %1}";
19430 default:
19431 abort ();
19432 }
19433 }
19434 [(set_attr "type" "ssemov")
19435 (set (attr "mode")
19436 (cond [(eq_attr "alternative" "0,1")
19437 (if_then_else
19438 (ne (symbol_ref "optimize_size")
19439 (const_int 0))
19440 (const_string "V4SF")
19441 (const_string "TI"))
19442 (eq_attr "alternative" "2")
19443 (if_then_else
19444 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19445 (const_int 0))
19446 (ne (symbol_ref "optimize_size")
19447 (const_int 0)))
19448 (const_string "V4SF")
19449 (const_string "TI"))]
19450 (const_string "TI")))])
19451
19452 (define_expand "movv2df"
19453 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19454 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19455 "TARGET_SSE2"
19456 {
19457 ix86_expand_vector_move (V2DFmode, operands);
19458 DONE;
19459 })
19460
19461 (define_expand "movv8hi"
19462 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19463 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19464 "TARGET_SSE2"
19465 {
19466 ix86_expand_vector_move (V8HImode, operands);
19467 DONE;
19468 })
19469
19470 (define_expand "movv16qi"
19471 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19472 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19473 "TARGET_SSE2"
19474 {
19475 ix86_expand_vector_move (V16QImode, operands);
19476 DONE;
19477 })
19478
19479 (define_expand "movv4sf"
19480 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19481 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19482 "TARGET_SSE"
19483 {
19484 ix86_expand_vector_move (V4SFmode, operands);
19485 DONE;
19486 })
19487
19488 (define_expand "movv4si"
19489 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19490 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19491 "TARGET_SSE"
19492 {
19493 ix86_expand_vector_move (V4SImode, operands);
19494 DONE;
19495 })
19496
19497 (define_expand "movv2di"
19498 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19499 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19500 "TARGET_SSE"
19501 {
19502 ix86_expand_vector_move (V2DImode, operands);
19503 DONE;
19504 })
19505
19506 (define_expand "movv2si"
19507 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19508 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19509 "TARGET_MMX"
19510 {
19511 ix86_expand_vector_move (V2SImode, operands);
19512 DONE;
19513 })
19514
19515 (define_expand "movv4hi"
19516 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19517 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19518 "TARGET_MMX"
19519 {
19520 ix86_expand_vector_move (V4HImode, operands);
19521 DONE;
19522 })
19523
19524 (define_expand "movv8qi"
19525 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19526 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19527 "TARGET_MMX"
19528 {
19529 ix86_expand_vector_move (V8QImode, operands);
19530 DONE;
19531 })
19532
19533 (define_expand "movv2sf"
19534 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19535 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19536 "TARGET_3DNOW"
19537 {
19538 ix86_expand_vector_move (V2SFmode, operands);
19539 DONE;
19540 })
19541
19542 (define_insn "*pushti"
19543 [(set (match_operand:TI 0 "push_operand" "=<")
19544 (match_operand:TI 1 "register_operand" "x"))]
19545 "TARGET_SSE"
19546 "#")
19547
19548 (define_insn "*pushv2df"
19549 [(set (match_operand:V2DF 0 "push_operand" "=<")
19550 (match_operand:V2DF 1 "register_operand" "x"))]
19551 "TARGET_SSE"
19552 "#")
19553
19554 (define_insn "*pushv2di"
19555 [(set (match_operand:V2DI 0 "push_operand" "=<")
19556 (match_operand:V2DI 1 "register_operand" "x"))]
19557 "TARGET_SSE2"
19558 "#")
19559
19560 (define_insn "*pushv8hi"
19561 [(set (match_operand:V8HI 0 "push_operand" "=<")
19562 (match_operand:V8HI 1 "register_operand" "x"))]
19563 "TARGET_SSE2"
19564 "#")
19565
19566 (define_insn "*pushv16qi"
19567 [(set (match_operand:V16QI 0 "push_operand" "=<")
19568 (match_operand:V16QI 1 "register_operand" "x"))]
19569 "TARGET_SSE2"
19570 "#")
19571
19572 (define_insn "*pushv4sf"
19573 [(set (match_operand:V4SF 0 "push_operand" "=<")
19574 (match_operand:V4SF 1 "register_operand" "x"))]
19575 "TARGET_SSE"
19576 "#")
19577
19578 (define_insn "*pushv4si"
19579 [(set (match_operand:V4SI 0 "push_operand" "=<")
19580 (match_operand:V4SI 1 "register_operand" "x"))]
19581 "TARGET_SSE2"
19582 "#")
19583
19584 (define_insn "*pushv2si"
19585 [(set (match_operand:V2SI 0 "push_operand" "=<")
19586 (match_operand:V2SI 1 "register_operand" "y"))]
19587 "TARGET_MMX"
19588 "#")
19589
19590 (define_insn "*pushv4hi"
19591 [(set (match_operand:V4HI 0 "push_operand" "=<")
19592 (match_operand:V4HI 1 "register_operand" "y"))]
19593 "TARGET_MMX"
19594 "#")
19595
19596 (define_insn "*pushv8qi"
19597 [(set (match_operand:V8QI 0 "push_operand" "=<")
19598 (match_operand:V8QI 1 "register_operand" "y"))]
19599 "TARGET_MMX"
19600 "#")
19601
19602 (define_insn "*pushv2sf"
19603 [(set (match_operand:V2SF 0 "push_operand" "=<")
19604 (match_operand:V2SF 1 "register_operand" "y"))]
19605 "TARGET_3DNOW"
19606 "#")
19607
19608 (define_split
19609 [(set (match_operand 0 "push_operand" "")
19610 (match_operand 1 "register_operand" ""))]
19611 "!TARGET_64BIT && reload_completed
19612 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19613 [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19614 (set (match_dup 2) (match_dup 1))]
19615 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19616 stack_pointer_rtx);
19617 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19618
19619 (define_split
19620 [(set (match_operand 0 "push_operand" "")
19621 (match_operand 1 "register_operand" ""))]
19622 "TARGET_64BIT && reload_completed
19623 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19624 [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19625 (set (match_dup 2) (match_dup 1))]
19626 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19627 stack_pointer_rtx);
19628 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19629
19630
19631 (define_insn "movti_internal"
19632 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19633 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19634 "TARGET_SSE && !TARGET_64BIT
19635 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19636 {
19637 switch (which_alternative)
19638 {
19639 case 0:
19640 if (get_attr_mode (insn) == MODE_V4SF)
19641 return "xorps\t%0, %0";
19642 else
19643 return "pxor\t%0, %0";
19644 case 1:
19645 case 2:
19646 if (get_attr_mode (insn) == MODE_V4SF)
19647 return "movaps\t{%1, %0|%0, %1}";
19648 else
19649 return "movdqa\t{%1, %0|%0, %1}";
19650 default:
19651 abort ();
19652 }
19653 }
19654 [(set_attr "type" "ssemov,ssemov,ssemov")
19655 (set (attr "mode")
19656 (cond [(eq_attr "alternative" "0,1")
19657 (if_then_else
19658 (ne (symbol_ref "optimize_size")
19659 (const_int 0))
19660 (const_string "V4SF")
19661 (const_string "TI"))
19662 (eq_attr "alternative" "2")
19663 (if_then_else
19664 (ne (symbol_ref "optimize_size")
19665 (const_int 0))
19666 (const_string "V4SF")
19667 (const_string "TI"))]
19668 (const_string "TI")))])
19669
19670 (define_insn "*movti_rex64"
19671 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19672 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19673 "TARGET_64BIT
19674 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19675 {
19676 switch (which_alternative)
19677 {
19678 case 0:
19679 case 1:
19680 return "#";
19681 case 2:
19682 if (get_attr_mode (insn) == MODE_V4SF)
19683 return "xorps\t%0, %0";
19684 else
19685 return "pxor\t%0, %0";
19686 case 3:
19687 case 4:
19688 if (get_attr_mode (insn) == MODE_V4SF)
19689 return "movaps\t{%1, %0|%0, %1}";
19690 else
19691 return "movdqa\t{%1, %0|%0, %1}";
19692 default:
19693 abort ();
19694 }
19695 }
19696 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19697 (set (attr "mode")
19698 (cond [(eq_attr "alternative" "2,3")
19699 (if_then_else
19700 (ne (symbol_ref "optimize_size")
19701 (const_int 0))
19702 (const_string "V4SF")
19703 (const_string "TI"))
19704 (eq_attr "alternative" "4")
19705 (if_then_else
19706 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19707 (const_int 0))
19708 (ne (symbol_ref "optimize_size")
19709 (const_int 0)))
19710 (const_string "V4SF")
19711 (const_string "TI"))]
19712 (const_string "DI")))])
19713
19714 (define_split
19715 [(set (match_operand:TI 0 "nonimmediate_operand" "")
19716 (match_operand:TI 1 "general_operand" ""))]
19717 "reload_completed && !SSE_REG_P (operands[0])
19718 && !SSE_REG_P (operands[1])"
19719 [(const_int 0)]
19720 "ix86_split_long_move (operands); DONE;")
19721
19722 ;; These two patterns are useful for specifying exactly whether to use
19723 ;; movaps or movups
19724 (define_expand "sse_movaps"
19725 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19726 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19727 UNSPEC_MOVA))]
19728 "TARGET_SSE"
19729 {
19730 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19731 {
19732 rtx tmp = gen_reg_rtx (V4SFmode);
19733 emit_insn (gen_sse_movaps (tmp, operands[1]));
19734 emit_move_insn (operands[0], tmp);
19735 DONE;
19736 }
19737 })
19738
19739 (define_insn "*sse_movaps_1"
19740 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19741 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19742 UNSPEC_MOVA))]
19743 "TARGET_SSE
19744 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19745 "movaps\t{%1, %0|%0, %1}"
19746 [(set_attr "type" "ssemov,ssemov")
19747 (set_attr "mode" "V4SF")])
19748
19749 (define_expand "sse_movups"
19750 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19751 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19752 UNSPEC_MOVU))]
19753 "TARGET_SSE"
19754 {
19755 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19756 {
19757 rtx tmp = gen_reg_rtx (V4SFmode);
19758 emit_insn (gen_sse_movups (tmp, operands[1]));
19759 emit_move_insn (operands[0], tmp);
19760 DONE;
19761 }
19762 })
19763
19764 (define_insn "*sse_movups_1"
19765 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19766 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19767 UNSPEC_MOVU))]
19768 "TARGET_SSE
19769 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19770 "movups\t{%1, %0|%0, %1}"
19771 [(set_attr "type" "ssecvt,ssecvt")
19772 (set_attr "mode" "V4SF")])
19773
19774 ;; SSE Strange Moves.
19775
19776 (define_insn "sse_movmskps"
19777 [(set (match_operand:SI 0 "register_operand" "=r")
19778 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19779 UNSPEC_MOVMSK))]
19780 "TARGET_SSE"
19781 "movmskps\t{%1, %0|%0, %1}"
19782 [(set_attr "type" "ssecvt")
19783 (set_attr "mode" "V4SF")])
19784
19785 (define_insn "mmx_pmovmskb"
19786 [(set (match_operand:SI 0 "register_operand" "=r")
19787 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19788 UNSPEC_MOVMSK))]
19789 "TARGET_SSE || TARGET_3DNOW_A"
19790 "pmovmskb\t{%1, %0|%0, %1}"
19791 [(set_attr "type" "ssecvt")
19792 (set_attr "mode" "V4SF")])
19793
19794
19795 (define_insn "mmx_maskmovq"
19796 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19797 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19798 (match_operand:V8QI 2 "register_operand" "y")]
19799 UNSPEC_MASKMOV))]
19800 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19801 ;; @@@ check ordering of operands in intel/nonintel syntax
19802 "maskmovq\t{%2, %1|%1, %2}"
19803 [(set_attr "type" "mmxcvt")
19804 (set_attr "mode" "DI")])
19805
19806 (define_insn "mmx_maskmovq_rex"
19807 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19808 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19809 (match_operand:V8QI 2 "register_operand" "y")]
19810 UNSPEC_MASKMOV))]
19811 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19812 ;; @@@ check ordering of operands in intel/nonintel syntax
19813 "maskmovq\t{%2, %1|%1, %2}"
19814 [(set_attr "type" "mmxcvt")
19815 (set_attr "mode" "DI")])
19816
19817 (define_insn "sse_movntv4sf"
19818 [(set (match_operand:V4SF 0 "memory_operand" "=m")
19819 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19820 UNSPEC_MOVNT))]
19821 "TARGET_SSE"
19822 "movntps\t{%1, %0|%0, %1}"
19823 [(set_attr "type" "ssemov")
19824 (set_attr "mode" "V4SF")])
19825
19826 (define_insn "sse_movntdi"
19827 [(set (match_operand:DI 0 "memory_operand" "=m")
19828 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19829 UNSPEC_MOVNT))]
19830 "TARGET_SSE || TARGET_3DNOW_A"
19831 "movntq\t{%1, %0|%0, %1}"
19832 [(set_attr "type" "mmxmov")
19833 (set_attr "mode" "DI")])
19834
19835 (define_insn "sse_movhlps"
19836 [(set (match_operand:V4SF 0 "register_operand" "=x")
19837 (vec_merge:V4SF
19838 (match_operand:V4SF 1 "register_operand" "0")
19839 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19840 (parallel [(const_int 2)
19841 (const_int 3)
19842 (const_int 0)
19843 (const_int 1)]))
19844 (const_int 3)))]
19845 "TARGET_SSE"
19846 "movhlps\t{%2, %0|%0, %2}"
19847 [(set_attr "type" "ssecvt")
19848 (set_attr "mode" "V4SF")])
19849
19850 (define_insn "sse_movlhps"
19851 [(set (match_operand:V4SF 0 "register_operand" "=x")
19852 (vec_merge:V4SF
19853 (match_operand:V4SF 1 "register_operand" "0")
19854 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19855 (parallel [(const_int 2)
19856 (const_int 3)
19857 (const_int 0)
19858 (const_int 1)]))
19859 (const_int 12)))]
19860 "TARGET_SSE"
19861 "movlhps\t{%2, %0|%0, %2}"
19862 [(set_attr "type" "ssecvt")
19863 (set_attr "mode" "V4SF")])
19864
19865 (define_insn "sse_movhps"
19866 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19867 (vec_merge:V4SF
19868 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19869 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19870 (const_int 12)))]
19871 "TARGET_SSE
19872 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19873 "movhps\t{%2, %0|%0, %2}"
19874 [(set_attr "type" "ssecvt")
19875 (set_attr "mode" "V4SF")])
19876
19877 (define_insn "sse_movlps"
19878 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19879 (vec_merge:V4SF
19880 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19881 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19882 (const_int 3)))]
19883 "TARGET_SSE
19884 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19885 "movlps\t{%2, %0|%0, %2}"
19886 [(set_attr "type" "ssecvt")
19887 (set_attr "mode" "V4SF")])
19888
19889 (define_expand "sse_loadss"
19890 [(match_operand:V4SF 0 "register_operand" "")
19891 (match_operand:SF 1 "memory_operand" "")]
19892 "TARGET_SSE"
19893 {
19894 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19895 CONST0_RTX (V4SFmode)));
19896 DONE;
19897 })
19898
19899 (define_insn "sse_loadss_1"
19900 [(set (match_operand:V4SF 0 "register_operand" "=x")
19901 (vec_merge:V4SF
19902 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19903 (match_operand:V4SF 2 "const0_operand" "X")
19904 (const_int 1)))]
19905 "TARGET_SSE"
19906 "movss\t{%1, %0|%0, %1}"
19907 [(set_attr "type" "ssemov")
19908 (set_attr "mode" "SF")])
19909
19910 (define_insn "sse_movss"
19911 [(set (match_operand:V4SF 0 "register_operand" "=x")
19912 (vec_merge:V4SF
19913 (match_operand:V4SF 1 "register_operand" "0")
19914 (match_operand:V4SF 2 "register_operand" "x")
19915 (const_int 1)))]
19916 "TARGET_SSE"
19917 "movss\t{%2, %0|%0, %2}"
19918 [(set_attr "type" "ssemov")
19919 (set_attr "mode" "SF")])
19920
19921 (define_insn "sse_storess"
19922 [(set (match_operand:SF 0 "memory_operand" "=m")
19923 (vec_select:SF
19924 (match_operand:V4SF 1 "register_operand" "x")
19925 (parallel [(const_int 0)])))]
19926 "TARGET_SSE"
19927 "movss\t{%1, %0|%0, %1}"
19928 [(set_attr "type" "ssemov")
19929 (set_attr "mode" "SF")])
19930
19931 (define_insn "sse_shufps"
19932 [(set (match_operand:V4SF 0 "register_operand" "=x")
19933 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19934 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19935 (match_operand:SI 3 "immediate_operand" "i")]
19936 UNSPEC_SHUFFLE))]
19937 "TARGET_SSE"
19938 ;; @@@ check operand order for intel/nonintel syntax
19939 "shufps\t{%3, %2, %0|%0, %2, %3}"
19940 [(set_attr "type" "ssecvt")
19941 (set_attr "mode" "V4SF")])
19942
19943
19944 ;; SSE arithmetic
19945
19946 (define_insn "addv4sf3"
19947 [(set (match_operand:V4SF 0 "register_operand" "=x")
19948 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19949 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19950 "TARGET_SSE"
19951 "addps\t{%2, %0|%0, %2}"
19952 [(set_attr "type" "sseadd")
19953 (set_attr "mode" "V4SF")])
19954
19955 (define_insn "vmaddv4sf3"
19956 [(set (match_operand:V4SF 0 "register_operand" "=x")
19957 (vec_merge:V4SF
19958 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19959 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19960 (match_dup 1)
19961 (const_int 1)))]
19962 "TARGET_SSE"
19963 "addss\t{%2, %0|%0, %2}"
19964 [(set_attr "type" "sseadd")
19965 (set_attr "mode" "SF")])
19966
19967 (define_insn "subv4sf3"
19968 [(set (match_operand:V4SF 0 "register_operand" "=x")
19969 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19970 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19971 "TARGET_SSE"
19972 "subps\t{%2, %0|%0, %2}"
19973 [(set_attr "type" "sseadd")
19974 (set_attr "mode" "V4SF")])
19975
19976 (define_insn "vmsubv4sf3"
19977 [(set (match_operand:V4SF 0 "register_operand" "=x")
19978 (vec_merge:V4SF
19979 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19980 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19981 (match_dup 1)
19982 (const_int 1)))]
19983 "TARGET_SSE"
19984 "subss\t{%2, %0|%0, %2}"
19985 [(set_attr "type" "sseadd")
19986 (set_attr "mode" "SF")])
19987
19988 (define_insn "mulv4sf3"
19989 [(set (match_operand:V4SF 0 "register_operand" "=x")
19990 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19991 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19992 "TARGET_SSE"
19993 "mulps\t{%2, %0|%0, %2}"
19994 [(set_attr "type" "ssemul")
19995 (set_attr "mode" "V4SF")])
19996
19997 (define_insn "vmmulv4sf3"
19998 [(set (match_operand:V4SF 0 "register_operand" "=x")
19999 (vec_merge:V4SF
20000 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20001 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20002 (match_dup 1)
20003 (const_int 1)))]
20004 "TARGET_SSE"
20005 "mulss\t{%2, %0|%0, %2}"
20006 [(set_attr "type" "ssemul")
20007 (set_attr "mode" "SF")])
20008
20009 (define_insn "divv4sf3"
20010 [(set (match_operand:V4SF 0 "register_operand" "=x")
20011 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20012 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20013 "TARGET_SSE"
20014 "divps\t{%2, %0|%0, %2}"
20015 [(set_attr "type" "ssediv")
20016 (set_attr "mode" "V4SF")])
20017
20018 (define_insn "vmdivv4sf3"
20019 [(set (match_operand:V4SF 0 "register_operand" "=x")
20020 (vec_merge:V4SF
20021 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20022 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20023 (match_dup 1)
20024 (const_int 1)))]
20025 "TARGET_SSE"
20026 "divss\t{%2, %0|%0, %2}"
20027 [(set_attr "type" "ssediv")
20028 (set_attr "mode" "SF")])
20029
20030
20031 ;; SSE square root/reciprocal
20032
20033 (define_insn "rcpv4sf2"
20034 [(set (match_operand:V4SF 0 "register_operand" "=x")
20035 (unspec:V4SF
20036 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20037 "TARGET_SSE"
20038 "rcpps\t{%1, %0|%0, %1}"
20039 [(set_attr "type" "sse")
20040 (set_attr "mode" "V4SF")])
20041
20042 (define_insn "vmrcpv4sf2"
20043 [(set (match_operand:V4SF 0 "register_operand" "=x")
20044 (vec_merge:V4SF
20045 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20046 UNSPEC_RCP)
20047 (match_operand:V4SF 2 "register_operand" "0")
20048 (const_int 1)))]
20049 "TARGET_SSE"
20050 "rcpss\t{%1, %0|%0, %1}"
20051 [(set_attr "type" "sse")
20052 (set_attr "mode" "SF")])
20053
20054 (define_insn "rsqrtv4sf2"
20055 [(set (match_operand:V4SF 0 "register_operand" "=x")
20056 (unspec:V4SF
20057 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
20058 "TARGET_SSE"
20059 "rsqrtps\t{%1, %0|%0, %1}"
20060 [(set_attr "type" "sse")
20061 (set_attr "mode" "V4SF")])
20062
20063 (define_insn "vmrsqrtv4sf2"
20064 [(set (match_operand:V4SF 0 "register_operand" "=x")
20065 (vec_merge:V4SF
20066 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20067 UNSPEC_RSQRT)
20068 (match_operand:V4SF 2 "register_operand" "0")
20069 (const_int 1)))]
20070 "TARGET_SSE"
20071 "rsqrtss\t{%1, %0|%0, %1}"
20072 [(set_attr "type" "sse")
20073 (set_attr "mode" "SF")])
20074
20075 (define_insn "sqrtv4sf2"
20076 [(set (match_operand:V4SF 0 "register_operand" "=x")
20077 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
20078 "TARGET_SSE"
20079 "sqrtps\t{%1, %0|%0, %1}"
20080 [(set_attr "type" "sse")
20081 (set_attr "mode" "V4SF")])
20082
20083 (define_insn "vmsqrtv4sf2"
20084 [(set (match_operand:V4SF 0 "register_operand" "=x")
20085 (vec_merge:V4SF
20086 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20087 (match_operand:V4SF 2 "register_operand" "0")
20088 (const_int 1)))]
20089 "TARGET_SSE"
20090 "sqrtss\t{%1, %0|%0, %1}"
20091 [(set_attr "type" "sse")
20092 (set_attr "mode" "SF")])
20093
20094 ;; SSE logical operations.
20095
20096 ;; SSE defines logical operations on floating point values. This brings
20097 ;; interesting challenge to RTL representation where logicals are only valid
20098 ;; on integral types. We deal with this by representing the floating point
20099 ;; logical as logical on arguments casted to TImode as this is what hardware
20100 ;; really does. Unfortunately hardware requires the type information to be
20101 ;; present and thus we must avoid subregs from being simplified and eliminated
20102 ;; in later compilation phases.
20103 ;;
20104 ;; We have following variants from each instruction:
20105 ;; sse_andsf3 - the operation taking V4SF vector operands
20106 ;; and doing TImode cast on them
20107 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
20108 ;; TImode, since backend insist on eliminating casts
20109 ;; on memory operands
20110 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
20111 ;; We can not accept memory operand here as instruction reads
20112 ;; whole scalar. This is generated only post reload by GCC
20113 ;; scalar float operations that expands to logicals (fabs)
20114 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
20115 ;; memory operand. Eventually combine can be able
20116 ;; to synthesize these using splitter.
20117 ;; sse2_anddf3, *sse2_anddf3_memory
20118 ;;
20119 ;;
20120 ;; These are not called andti3 etc. because we really really don't want
20121 ;; the compiler to widen DImode ands to TImode ands and then try to move
20122 ;; into DImode subregs of SSE registers, and them together, and move out
20123 ;; of DImode subregs again!
20124 ;; SSE1 single precision floating point logical operation
20125 (define_expand "sse_andv4sf3"
20126 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20127 (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20128 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20129 "TARGET_SSE"
20130 "")
20131
20132 (define_insn "*sse_andv4sf3"
20133 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20134 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20135 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20136 "TARGET_SSE
20137 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20138 "andps\t{%2, %0|%0, %2}"
20139 [(set_attr "type" "sselog")
20140 (set_attr "mode" "V4SF")])
20141
20142 (define_insn "*sse_andsf3"
20143 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20144 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20145 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20146 "TARGET_SSE
20147 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20148 "andps\t{%2, %0|%0, %2}"
20149 [(set_attr "type" "sselog")
20150 (set_attr "mode" "V4SF")])
20151
20152 (define_expand "sse_nandv4sf3"
20153 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20154 (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
20155 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20156 "TARGET_SSE"
20157 "")
20158
20159 (define_insn "*sse_nandv4sf3"
20160 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20161 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20162 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20163 "TARGET_SSE"
20164 "andnps\t{%2, %0|%0, %2}"
20165 [(set_attr "type" "sselog")
20166 (set_attr "mode" "V4SF")])
20167
20168 (define_insn "*sse_nandsf3"
20169 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20170 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20171 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20172 "TARGET_SSE"
20173 "andnps\t{%2, %0|%0, %2}"
20174 [(set_attr "type" "sselog")
20175 (set_attr "mode" "V4SF")])
20176
20177 (define_expand "sse_iorv4sf3"
20178 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20179 (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20180 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20181 "TARGET_SSE"
20182 "")
20183
20184 (define_insn "*sse_iorv4sf3"
20185 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20186 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20187 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20188 "TARGET_SSE
20189 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20190 "orps\t{%2, %0|%0, %2}"
20191 [(set_attr "type" "sselog")
20192 (set_attr "mode" "V4SF")])
20193
20194 (define_insn "*sse_iorsf3"
20195 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20196 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20197 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20198 "TARGET_SSE
20199 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20200 "orps\t{%2, %0|%0, %2}"
20201 [(set_attr "type" "sselog")
20202 (set_attr "mode" "V4SF")])
20203
20204 (define_expand "sse_xorv4sf3"
20205 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20206 (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20207 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20208 "TARGET_SSE
20209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20210 "")
20211
20212 (define_insn "*sse_xorv4sf3"
20213 [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20214 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20215 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20216 "TARGET_SSE
20217 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20218 "xorps\t{%2, %0|%0, %2}"
20219 [(set_attr "type" "sselog")
20220 (set_attr "mode" "V4SF")])
20221
20222 (define_insn "*sse_xorsf3"
20223 [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20224 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20225 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20226 "TARGET_SSE
20227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20228 "xorps\t{%2, %0|%0, %2}"
20229 [(set_attr "type" "sselog")
20230 (set_attr "mode" "V4SF")])
20231
20232 ;; SSE2 double precision floating point logical operation
20233
20234 (define_expand "sse2_andv2df3"
20235 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20236 (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20237 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20238 "TARGET_SSE2"
20239 "")
20240
20241 (define_insn "*sse2_andv2df3"
20242 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20243 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20244 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20245 "TARGET_SSE2
20246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20247 "andpd\t{%2, %0|%0, %2}"
20248 [(set_attr "type" "sselog")
20249 (set_attr "mode" "V2DF")])
20250
20251 (define_insn "*sse2_andv2df3"
20252 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20253 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20254 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20255 "TARGET_SSE2
20256 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20257 "andpd\t{%2, %0|%0, %2}"
20258 [(set_attr "type" "sselog")
20259 (set_attr "mode" "V2DF")])
20260
20261 (define_expand "sse2_nandv2df3"
20262 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20263 (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20264 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20265 "TARGET_SSE2"
20266 "")
20267
20268 (define_insn "*sse2_nandv2df3"
20269 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20270 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20271 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20272 "TARGET_SSE2"
20273 "andnpd\t{%2, %0|%0, %2}"
20274 [(set_attr "type" "sselog")
20275 (set_attr "mode" "V2DF")])
20276
20277 (define_insn "*sse_nandti3_df"
20278 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20279 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20280 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20281 "TARGET_SSE2"
20282 "andnpd\t{%2, %0|%0, %2}"
20283 [(set_attr "type" "sselog")
20284 (set_attr "mode" "V2DF")])
20285
20286 (define_expand "sse2_iorv2df3"
20287 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20288 (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20289 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20290 "TARGET_SSE2"
20291 "")
20292
20293 (define_insn "*sse2_iorv2df3"
20294 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20295 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20296 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20297 "TARGET_SSE2
20298 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20299 "orpd\t{%2, %0|%0, %2}"
20300 [(set_attr "type" "sselog")
20301 (set_attr "mode" "V2DF")])
20302
20303 (define_insn "*sse2_iordf3"
20304 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20305 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20306 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20307 "TARGET_SSE2
20308 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20309 "orpd\t{%2, %0|%0, %2}"
20310 [(set_attr "type" "sselog")
20311 (set_attr "mode" "V2DF")])
20312
20313 (define_expand "sse2_xorv2df3"
20314 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20315 (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20316 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20317 "TARGET_SSE2"
20318 "")
20319
20320 (define_insn "*sse2_xorv2df3"
20321 [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20322 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20323 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20324 "TARGET_SSE2
20325 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20326 "xorpd\t{%2, %0|%0, %2}"
20327 [(set_attr "type" "sselog")
20328 (set_attr "mode" "V2DF")])
20329
20330 (define_insn "*sse2_xordf3"
20331 [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20332 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20333 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20334 "TARGET_SSE2
20335 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20336 "xorpd\t{%2, %0|%0, %2}"
20337 [(set_attr "type" "sselog")
20338 (set_attr "mode" "V2DF")])
20339
20340 ;; SSE2 integral logicals. These patterns must always come after floating
20341 ;; point ones since we don't want compiler to use integer opcodes on floating
20342 ;; point SSE values to avoid matching of subregs in the match_operand.
20343 (define_insn "*sse2_andti3"
20344 [(set (match_operand:TI 0 "register_operand" "=x")
20345 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20346 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20347 "TARGET_SSE2
20348 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20349 "pand\t{%2, %0|%0, %2}"
20350 [(set_attr "type" "sselog")
20351 (set_attr "mode" "TI")])
20352
20353 (define_insn "sse2_andv2di3"
20354 [(set (match_operand:V2DI 0 "register_operand" "=x")
20355 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20356 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20357 "TARGET_SSE2
20358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20359 "pand\t{%2, %0|%0, %2}"
20360 [(set_attr "type" "sselog")
20361 (set_attr "mode" "TI")])
20362
20363 (define_insn "*sse2_nandti3"
20364 [(set (match_operand:TI 0 "register_operand" "=x")
20365 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20366 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20367 "TARGET_SSE2"
20368 "pandn\t{%2, %0|%0, %2}"
20369 [(set_attr "type" "sselog")
20370 (set_attr "mode" "TI")])
20371
20372 (define_insn "sse2_nandv2di3"
20373 [(set (match_operand:V2DI 0 "register_operand" "=x")
20374 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20375 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20376 "TARGET_SSE2
20377 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20378 "pandn\t{%2, %0|%0, %2}"
20379 [(set_attr "type" "sselog")
20380 (set_attr "mode" "TI")])
20381
20382 (define_insn "*sse2_iorti3"
20383 [(set (match_operand:TI 0 "register_operand" "=x")
20384 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20385 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20386 "TARGET_SSE2
20387 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20388 "por\t{%2, %0|%0, %2}"
20389 [(set_attr "type" "sselog")
20390 (set_attr "mode" "TI")])
20391
20392 (define_insn "sse2_iorv2di3"
20393 [(set (match_operand:V2DI 0 "register_operand" "=x")
20394 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20395 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20396 "TARGET_SSE2
20397 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20398 "por\t{%2, %0|%0, %2}"
20399 [(set_attr "type" "sselog")
20400 (set_attr "mode" "TI")])
20401
20402 (define_insn "*sse2_xorti3"
20403 [(set (match_operand:TI 0 "register_operand" "=x")
20404 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20405 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20406 "TARGET_SSE2
20407 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20408 "pxor\t{%2, %0|%0, %2}"
20409 [(set_attr "type" "sselog")
20410 (set_attr "mode" "TI")])
20411
20412 (define_insn "sse2_xorv2di3"
20413 [(set (match_operand:V2DI 0 "register_operand" "=x")
20414 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20415 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20416 "TARGET_SSE2
20417 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20418 "pxor\t{%2, %0|%0, %2}"
20419 [(set_attr "type" "sselog")
20420 (set_attr "mode" "TI")])
20421
20422 ;; Use xor, but don't show input operands so they aren't live before
20423 ;; this insn.
20424 (define_insn "sse_clrv4sf"
20425 [(set (match_operand:V4SF 0 "register_operand" "=x")
20426 (match_operand:V4SF 1 "const0_operand" "X"))]
20427 "TARGET_SSE"
20428 {
20429 if (get_attr_mode (insn) == MODE_TI)
20430 return "pxor\t{%0, %0|%0, %0}";
20431 else
20432 return "xorps\t{%0, %0|%0, %0}";
20433 }
20434 [(set_attr "type" "sselog")
20435 (set_attr "memory" "none")
20436 (set (attr "mode")
20437 (if_then_else
20438 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20439 (const_int 0))
20440 (ne (symbol_ref "TARGET_SSE2")
20441 (const_int 0)))
20442 (eq (symbol_ref "optimize_size")
20443 (const_int 0)))
20444 (const_string "TI")
20445 (const_string "V4SF")))])
20446
20447 ;; Use xor, but don't show input operands so they aren't live before
20448 ;; this insn.
20449 (define_insn "sse_clrv2df"
20450 [(set (match_operand:V2DF 0 "register_operand" "=x")
20451 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20452 "TARGET_SSE2"
20453 "xorpd\t{%0, %0|%0, %0}"
20454 [(set_attr "type" "sselog")
20455 (set_attr "memory" "none")
20456 (set_attr "mode" "V4SF")])
20457
20458 ;; SSE mask-generating compares
20459
20460 (define_insn "maskcmpv4sf3"
20461 [(set (match_operand:V4SI 0 "register_operand" "=x")
20462 (match_operator:V4SI 3 "sse_comparison_operator"
20463 [(match_operand:V4SF 1 "register_operand" "0")
20464 (match_operand:V4SF 2 "register_operand" "x")]))]
20465 "TARGET_SSE"
20466 "cmp%D3ps\t{%2, %0|%0, %2}"
20467 [(set_attr "type" "ssecmp")
20468 (set_attr "mode" "V4SF")])
20469
20470 (define_insn "maskncmpv4sf3"
20471 [(set (match_operand:V4SI 0 "register_operand" "=x")
20472 (not:V4SI
20473 (match_operator:V4SI 3 "sse_comparison_operator"
20474 [(match_operand:V4SF 1 "register_operand" "0")
20475 (match_operand:V4SF 2 "register_operand" "x")])))]
20476 "TARGET_SSE"
20477 {
20478 if (GET_CODE (operands[3]) == UNORDERED)
20479 return "cmpordps\t{%2, %0|%0, %2}";
20480 else
20481 return "cmpn%D3ps\t{%2, %0|%0, %2}";
20482 }
20483 [(set_attr "type" "ssecmp")
20484 (set_attr "mode" "V4SF")])
20485
20486 (define_insn "vmmaskcmpv4sf3"
20487 [(set (match_operand:V4SI 0 "register_operand" "=x")
20488 (vec_merge:V4SI
20489 (match_operator:V4SI 3 "sse_comparison_operator"
20490 [(match_operand:V4SF 1 "register_operand" "0")
20491 (match_operand:V4SF 2 "register_operand" "x")])
20492 (subreg:V4SI (match_dup 1) 0)
20493 (const_int 1)))]
20494 "TARGET_SSE"
20495 "cmp%D3ss\t{%2, %0|%0, %2}"
20496 [(set_attr "type" "ssecmp")
20497 (set_attr "mode" "SF")])
20498
20499 (define_insn "vmmaskncmpv4sf3"
20500 [(set (match_operand:V4SI 0 "register_operand" "=x")
20501 (vec_merge:V4SI
20502 (not:V4SI
20503 (match_operator:V4SI 3 "sse_comparison_operator"
20504 [(match_operand:V4SF 1 "register_operand" "0")
20505 (match_operand:V4SF 2 "register_operand" "x")]))
20506 (subreg:V4SI (match_dup 1) 0)
20507 (const_int 1)))]
20508 "TARGET_SSE"
20509 {
20510 if (GET_CODE (operands[3]) == UNORDERED)
20511 return "cmpordss\t{%2, %0|%0, %2}";
20512 else
20513 return "cmpn%D3ss\t{%2, %0|%0, %2}";
20514 }
20515 [(set_attr "type" "ssecmp")
20516 (set_attr "mode" "SF")])
20517
20518 (define_insn "sse_comi"
20519 [(set (reg:CCFP 17)
20520 (compare:CCFP (vec_select:SF
20521 (match_operand:V4SF 0 "register_operand" "x")
20522 (parallel [(const_int 0)]))
20523 (vec_select:SF
20524 (match_operand:V4SF 1 "register_operand" "x")
20525 (parallel [(const_int 0)]))))]
20526 "TARGET_SSE"
20527 "comiss\t{%1, %0|%0, %1}"
20528 [(set_attr "type" "ssecomi")
20529 (set_attr "mode" "SF")])
20530
20531 (define_insn "sse_ucomi"
20532 [(set (reg:CCFPU 17)
20533 (compare:CCFPU (vec_select:SF
20534 (match_operand:V4SF 0 "register_operand" "x")
20535 (parallel [(const_int 0)]))
20536 (vec_select:SF
20537 (match_operand:V4SF 1 "register_operand" "x")
20538 (parallel [(const_int 0)]))))]
20539 "TARGET_SSE"
20540 "ucomiss\t{%1, %0|%0, %1}"
20541 [(set_attr "type" "ssecomi")
20542 (set_attr "mode" "SF")])
20543
20544
20545 ;; SSE unpack
20546
20547 (define_insn "sse_unpckhps"
20548 [(set (match_operand:V4SF 0 "register_operand" "=x")
20549 (vec_merge:V4SF
20550 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20551 (parallel [(const_int 2)
20552 (const_int 0)
20553 (const_int 3)
20554 (const_int 1)]))
20555 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20556 (parallel [(const_int 0)
20557 (const_int 2)
20558 (const_int 1)
20559 (const_int 3)]))
20560 (const_int 5)))]
20561 "TARGET_SSE"
20562 "unpckhps\t{%2, %0|%0, %2}"
20563 [(set_attr "type" "ssecvt")
20564 (set_attr "mode" "V4SF")])
20565
20566 (define_insn "sse_unpcklps"
20567 [(set (match_operand:V4SF 0 "register_operand" "=x")
20568 (vec_merge:V4SF
20569 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20570 (parallel [(const_int 0)
20571 (const_int 2)
20572 (const_int 1)
20573 (const_int 3)]))
20574 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20575 (parallel [(const_int 2)
20576 (const_int 0)
20577 (const_int 3)
20578 (const_int 1)]))
20579 (const_int 5)))]
20580 "TARGET_SSE"
20581 "unpcklps\t{%2, %0|%0, %2}"
20582 [(set_attr "type" "ssecvt")
20583 (set_attr "mode" "V4SF")])
20584
20585
20586 ;; SSE min/max
20587
20588 (define_insn "smaxv4sf3"
20589 [(set (match_operand:V4SF 0 "register_operand" "=x")
20590 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20591 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20592 "TARGET_SSE"
20593 "maxps\t{%2, %0|%0, %2}"
20594 [(set_attr "type" "sse")
20595 (set_attr "mode" "V4SF")])
20596
20597 (define_insn "vmsmaxv4sf3"
20598 [(set (match_operand:V4SF 0 "register_operand" "=x")
20599 (vec_merge:V4SF
20600 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20601 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20602 (match_dup 1)
20603 (const_int 1)))]
20604 "TARGET_SSE"
20605 "maxss\t{%2, %0|%0, %2}"
20606 [(set_attr "type" "sse")
20607 (set_attr "mode" "SF")])
20608
20609 (define_insn "sminv4sf3"
20610 [(set (match_operand:V4SF 0 "register_operand" "=x")
20611 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20612 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20613 "TARGET_SSE"
20614 "minps\t{%2, %0|%0, %2}"
20615 [(set_attr "type" "sse")
20616 (set_attr "mode" "V4SF")])
20617
20618 (define_insn "vmsminv4sf3"
20619 [(set (match_operand:V4SF 0 "register_operand" "=x")
20620 (vec_merge:V4SF
20621 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20622 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20623 (match_dup 1)
20624 (const_int 1)))]
20625 "TARGET_SSE"
20626 "minss\t{%2, %0|%0, %2}"
20627 [(set_attr "type" "sse")
20628 (set_attr "mode" "SF")])
20629
20630 ;; SSE <-> integer/MMX conversions
20631
20632 (define_insn "cvtpi2ps"
20633 [(set (match_operand:V4SF 0 "register_operand" "=x")
20634 (vec_merge:V4SF
20635 (match_operand:V4SF 1 "register_operand" "0")
20636 (vec_duplicate:V4SF
20637 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20638 (const_int 12)))]
20639 "TARGET_SSE"
20640 "cvtpi2ps\t{%2, %0|%0, %2}"
20641 [(set_attr "type" "ssecvt")
20642 (set_attr "mode" "V4SF")])
20643
20644 (define_insn "cvtps2pi"
20645 [(set (match_operand:V2SI 0 "register_operand" "=y")
20646 (vec_select:V2SI
20647 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20648 (parallel [(const_int 0) (const_int 1)])))]
20649 "TARGET_SSE"
20650 "cvtps2pi\t{%1, %0|%0, %1}"
20651 [(set_attr "type" "ssecvt")
20652 (set_attr "mode" "V4SF")])
20653
20654 (define_insn "cvttps2pi"
20655 [(set (match_operand:V2SI 0 "register_operand" "=y")
20656 (vec_select:V2SI
20657 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20658 UNSPEC_FIX)
20659 (parallel [(const_int 0) (const_int 1)])))]
20660 "TARGET_SSE"
20661 "cvttps2pi\t{%1, %0|%0, %1}"
20662 [(set_attr "type" "ssecvt")
20663 (set_attr "mode" "SF")])
20664
20665 (define_insn "cvtsi2ss"
20666 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20667 (vec_merge:V4SF
20668 (match_operand:V4SF 1 "register_operand" "0,0")
20669 (vec_duplicate:V4SF
20670 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20671 (const_int 14)))]
20672 "TARGET_SSE"
20673 "cvtsi2ss\t{%2, %0|%0, %2}"
20674 [(set_attr "type" "sseicvt")
20675 (set_attr "athlon_decode" "vector,double")
20676 (set_attr "mode" "SF")])
20677
20678 (define_insn "cvtsi2ssq"
20679 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20680 (vec_merge:V4SF
20681 (match_operand:V4SF 1 "register_operand" "0,0")
20682 (vec_duplicate:V4SF
20683 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20684 (const_int 14)))]
20685 "TARGET_SSE && TARGET_64BIT"
20686 "cvtsi2ssq\t{%2, %0|%0, %2}"
20687 [(set_attr "type" "sseicvt")
20688 (set_attr "athlon_decode" "vector,double")
20689 (set_attr "mode" "SF")])
20690
20691 (define_insn "cvtss2si"
20692 [(set (match_operand:SI 0 "register_operand" "=r,r")
20693 (vec_select:SI
20694 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20695 (parallel [(const_int 0)])))]
20696 "TARGET_SSE"
20697 "cvtss2si\t{%1, %0|%0, %1}"
20698 [(set_attr "type" "sseicvt")
20699 (set_attr "athlon_decode" "double,vector")
20700 (set_attr "mode" "SI")])
20701
20702 (define_insn "cvtss2siq"
20703 [(set (match_operand:DI 0 "register_operand" "=r,r")
20704 (vec_select:DI
20705 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20706 (parallel [(const_int 0)])))]
20707 "TARGET_SSE"
20708 "cvtss2siq\t{%1, %0|%0, %1}"
20709 [(set_attr "type" "sseicvt")
20710 (set_attr "athlon_decode" "double,vector")
20711 (set_attr "mode" "DI")])
20712
20713 (define_insn "cvttss2si"
20714 [(set (match_operand:SI 0 "register_operand" "=r,r")
20715 (vec_select:SI
20716 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20717 UNSPEC_FIX)
20718 (parallel [(const_int 0)])))]
20719 "TARGET_SSE"
20720 "cvttss2si\t{%1, %0|%0, %1}"
20721 [(set_attr "type" "sseicvt")
20722 (set_attr "mode" "SF")
20723 (set_attr "athlon_decode" "double,vector")])
20724
20725 (define_insn "cvttss2siq"
20726 [(set (match_operand:DI 0 "register_operand" "=r,r")
20727 (vec_select:DI
20728 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20729 UNSPEC_FIX)
20730 (parallel [(const_int 0)])))]
20731 "TARGET_SSE && TARGET_64BIT"
20732 "cvttss2siq\t{%1, %0|%0, %1}"
20733 [(set_attr "type" "sseicvt")
20734 (set_attr "mode" "SF")
20735 (set_attr "athlon_decode" "double,vector")])
20736
20737
20738 ;; MMX insns
20739
20740 ;; MMX arithmetic
20741
20742 (define_insn "addv8qi3"
20743 [(set (match_operand:V8QI 0 "register_operand" "=y")
20744 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20745 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20746 "TARGET_MMX"
20747 "paddb\t{%2, %0|%0, %2}"
20748 [(set_attr "type" "mmxadd")
20749 (set_attr "mode" "DI")])
20750
20751 (define_insn "addv4hi3"
20752 [(set (match_operand:V4HI 0 "register_operand" "=y")
20753 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20754 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20755 "TARGET_MMX"
20756 "paddw\t{%2, %0|%0, %2}"
20757 [(set_attr "type" "mmxadd")
20758 (set_attr "mode" "DI")])
20759
20760 (define_insn "addv2si3"
20761 [(set (match_operand:V2SI 0 "register_operand" "=y")
20762 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20763 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20764 "TARGET_MMX"
20765 "paddd\t{%2, %0|%0, %2}"
20766 [(set_attr "type" "mmxadd")
20767 (set_attr "mode" "DI")])
20768
20769 (define_insn "mmx_adddi3"
20770 [(set (match_operand:DI 0 "register_operand" "=y")
20771 (unspec:DI
20772 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20773 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20774 UNSPEC_NOP))]
20775 "TARGET_MMX"
20776 "paddq\t{%2, %0|%0, %2}"
20777 [(set_attr "type" "mmxadd")
20778 (set_attr "mode" "DI")])
20779
20780 (define_insn "ssaddv8qi3"
20781 [(set (match_operand:V8QI 0 "register_operand" "=y")
20782 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20783 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20784 "TARGET_MMX"
20785 "paddsb\t{%2, %0|%0, %2}"
20786 [(set_attr "type" "mmxadd")
20787 (set_attr "mode" "DI")])
20788
20789 (define_insn "ssaddv4hi3"
20790 [(set (match_operand:V4HI 0 "register_operand" "=y")
20791 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20792 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20793 "TARGET_MMX"
20794 "paddsw\t{%2, %0|%0, %2}"
20795 [(set_attr "type" "mmxadd")
20796 (set_attr "mode" "DI")])
20797
20798 (define_insn "usaddv8qi3"
20799 [(set (match_operand:V8QI 0 "register_operand" "=y")
20800 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20801 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20802 "TARGET_MMX"
20803 "paddusb\t{%2, %0|%0, %2}"
20804 [(set_attr "type" "mmxadd")
20805 (set_attr "mode" "DI")])
20806
20807 (define_insn "usaddv4hi3"
20808 [(set (match_operand:V4HI 0 "register_operand" "=y")
20809 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20810 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20811 "TARGET_MMX"
20812 "paddusw\t{%2, %0|%0, %2}"
20813 [(set_attr "type" "mmxadd")
20814 (set_attr "mode" "DI")])
20815
20816 (define_insn "subv8qi3"
20817 [(set (match_operand:V8QI 0 "register_operand" "=y")
20818 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20819 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20820 "TARGET_MMX"
20821 "psubb\t{%2, %0|%0, %2}"
20822 [(set_attr "type" "mmxadd")
20823 (set_attr "mode" "DI")])
20824
20825 (define_insn "subv4hi3"
20826 [(set (match_operand:V4HI 0 "register_operand" "=y")
20827 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20828 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20829 "TARGET_MMX"
20830 "psubw\t{%2, %0|%0, %2}"
20831 [(set_attr "type" "mmxadd")
20832 (set_attr "mode" "DI")])
20833
20834 (define_insn "subv2si3"
20835 [(set (match_operand:V2SI 0 "register_operand" "=y")
20836 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20837 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20838 "TARGET_MMX"
20839 "psubd\t{%2, %0|%0, %2}"
20840 [(set_attr "type" "mmxadd")
20841 (set_attr "mode" "DI")])
20842
20843 (define_insn "mmx_subdi3"
20844 [(set (match_operand:DI 0 "register_operand" "=y")
20845 (unspec:DI
20846 [(minus:DI (match_operand:DI 1 "register_operand" "0")
20847 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20848 UNSPEC_NOP))]
20849 "TARGET_MMX"
20850 "psubq\t{%2, %0|%0, %2}"
20851 [(set_attr "type" "mmxadd")
20852 (set_attr "mode" "DI")])
20853
20854 (define_insn "sssubv8qi3"
20855 [(set (match_operand:V8QI 0 "register_operand" "=y")
20856 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20857 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20858 "TARGET_MMX"
20859 "psubsb\t{%2, %0|%0, %2}"
20860 [(set_attr "type" "mmxadd")
20861 (set_attr "mode" "DI")])
20862
20863 (define_insn "sssubv4hi3"
20864 [(set (match_operand:V4HI 0 "register_operand" "=y")
20865 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20866 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20867 "TARGET_MMX"
20868 "psubsw\t{%2, %0|%0, %2}"
20869 [(set_attr "type" "mmxadd")
20870 (set_attr "mode" "DI")])
20871
20872 (define_insn "ussubv8qi3"
20873 [(set (match_operand:V8QI 0 "register_operand" "=y")
20874 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20875 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20876 "TARGET_MMX"
20877 "psubusb\t{%2, %0|%0, %2}"
20878 [(set_attr "type" "mmxadd")
20879 (set_attr "mode" "DI")])
20880
20881 (define_insn "ussubv4hi3"
20882 [(set (match_operand:V4HI 0 "register_operand" "=y")
20883 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20884 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20885 "TARGET_MMX"
20886 "psubusw\t{%2, %0|%0, %2}"
20887 [(set_attr "type" "mmxadd")
20888 (set_attr "mode" "DI")])
20889
20890 (define_insn "mulv4hi3"
20891 [(set (match_operand:V4HI 0 "register_operand" "=y")
20892 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20893 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20894 "TARGET_MMX"
20895 "pmullw\t{%2, %0|%0, %2}"
20896 [(set_attr "type" "mmxmul")
20897 (set_attr "mode" "DI")])
20898
20899 (define_insn "smulv4hi3_highpart"
20900 [(set (match_operand:V4HI 0 "register_operand" "=y")
20901 (truncate:V4HI
20902 (lshiftrt:V4SI
20903 (mult:V4SI (sign_extend:V4SI
20904 (match_operand:V4HI 1 "register_operand" "0"))
20905 (sign_extend:V4SI
20906 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20907 (const_int 16))))]
20908 "TARGET_MMX"
20909 "pmulhw\t{%2, %0|%0, %2}"
20910 [(set_attr "type" "mmxmul")
20911 (set_attr "mode" "DI")])
20912
20913 (define_insn "umulv4hi3_highpart"
20914 [(set (match_operand:V4HI 0 "register_operand" "=y")
20915 (truncate:V4HI
20916 (lshiftrt:V4SI
20917 (mult:V4SI (zero_extend:V4SI
20918 (match_operand:V4HI 1 "register_operand" "0"))
20919 (zero_extend:V4SI
20920 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20921 (const_int 16))))]
20922 "TARGET_SSE || TARGET_3DNOW_A"
20923 "pmulhuw\t{%2, %0|%0, %2}"
20924 [(set_attr "type" "mmxmul")
20925 (set_attr "mode" "DI")])
20926
20927 (define_insn "mmx_pmaddwd"
20928 [(set (match_operand:V2SI 0 "register_operand" "=y")
20929 (plus:V2SI
20930 (mult:V2SI
20931 (sign_extend:V2SI
20932 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20933 (parallel [(const_int 0) (const_int 2)])))
20934 (sign_extend:V2SI
20935 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20936 (parallel [(const_int 0) (const_int 2)]))))
20937 (mult:V2SI
20938 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20939 (parallel [(const_int 1)
20940 (const_int 3)])))
20941 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20942 (parallel [(const_int 1)
20943 (const_int 3)]))))))]
20944 "TARGET_MMX"
20945 "pmaddwd\t{%2, %0|%0, %2}"
20946 [(set_attr "type" "mmxmul")
20947 (set_attr "mode" "DI")])
20948
20949
20950 ;; MMX logical operations
20951 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20952 ;; normal code that also wants to use the FPU from getting broken.
20953 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20954 (define_insn "mmx_iordi3"
20955 [(set (match_operand:DI 0 "register_operand" "=y")
20956 (unspec:DI
20957 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20958 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20959 UNSPEC_NOP))]
20960 "TARGET_MMX"
20961 "por\t{%2, %0|%0, %2}"
20962 [(set_attr "type" "mmxadd")
20963 (set_attr "mode" "DI")])
20964
20965 (define_insn "mmx_xordi3"
20966 [(set (match_operand:DI 0 "register_operand" "=y")
20967 (unspec:DI
20968 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20969 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20970 UNSPEC_NOP))]
20971 "TARGET_MMX"
20972 "pxor\t{%2, %0|%0, %2}"
20973 [(set_attr "type" "mmxadd")
20974 (set_attr "mode" "DI")
20975 (set_attr "memory" "none")])
20976
20977 ;; Same as pxor, but don't show input operands so that we don't think
20978 ;; they are live.
20979 (define_insn "mmx_clrdi"
20980 [(set (match_operand:DI 0 "register_operand" "=y")
20981 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20982 "TARGET_MMX"
20983 "pxor\t{%0, %0|%0, %0}"
20984 [(set_attr "type" "mmxadd")
20985 (set_attr "mode" "DI")
20986 (set_attr "memory" "none")])
20987
20988 (define_insn "mmx_anddi3"
20989 [(set (match_operand:DI 0 "register_operand" "=y")
20990 (unspec:DI
20991 [(and:DI (match_operand:DI 1 "register_operand" "%0")
20992 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20993 UNSPEC_NOP))]
20994 "TARGET_MMX"
20995 "pand\t{%2, %0|%0, %2}"
20996 [(set_attr "type" "mmxadd")
20997 (set_attr "mode" "DI")])
20998
20999 (define_insn "mmx_nanddi3"
21000 [(set (match_operand:DI 0 "register_operand" "=y")
21001 (unspec:DI
21002 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21003 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21004 UNSPEC_NOP))]
21005 "TARGET_MMX"
21006 "pandn\t{%2, %0|%0, %2}"
21007 [(set_attr "type" "mmxadd")
21008 (set_attr "mode" "DI")])
21009
21010
21011 ;; MMX unsigned averages/sum of absolute differences
21012
21013 (define_insn "mmx_uavgv8qi3"
21014 [(set (match_operand:V8QI 0 "register_operand" "=y")
21015 (ashiftrt:V8QI
21016 (plus:V8QI (plus:V8QI
21017 (match_operand:V8QI 1 "register_operand" "0")
21018 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21019 (const_vector:V8QI [(const_int 1)
21020 (const_int 1)
21021 (const_int 1)
21022 (const_int 1)
21023 (const_int 1)
21024 (const_int 1)
21025 (const_int 1)
21026 (const_int 1)]))
21027 (const_int 1)))]
21028 "TARGET_SSE || TARGET_3DNOW_A"
21029 "pavgb\t{%2, %0|%0, %2}"
21030 [(set_attr "type" "mmxshft")
21031 (set_attr "mode" "DI")])
21032
21033 (define_insn "mmx_uavgv4hi3"
21034 [(set (match_operand:V4HI 0 "register_operand" "=y")
21035 (ashiftrt:V4HI
21036 (plus:V4HI (plus:V4HI
21037 (match_operand:V4HI 1 "register_operand" "0")
21038 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21039 (const_vector:V4HI [(const_int 1)
21040 (const_int 1)
21041 (const_int 1)
21042 (const_int 1)]))
21043 (const_int 1)))]
21044 "TARGET_SSE || TARGET_3DNOW_A"
21045 "pavgw\t{%2, %0|%0, %2}"
21046 [(set_attr "type" "mmxshft")
21047 (set_attr "mode" "DI")])
21048
21049 (define_insn "mmx_psadbw"
21050 [(set (match_operand:DI 0 "register_operand" "=y")
21051 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21052 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21053 UNSPEC_PSADBW))]
21054 "TARGET_SSE || TARGET_3DNOW_A"
21055 "psadbw\t{%2, %0|%0, %2}"
21056 [(set_attr "type" "mmxshft")
21057 (set_attr "mode" "DI")])
21058
21059
21060 ;; MMX insert/extract/shuffle
21061
21062 (define_insn "mmx_pinsrw"
21063 [(set (match_operand:V4HI 0 "register_operand" "=y")
21064 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21065 (vec_duplicate:V4HI
21066 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21067 (match_operand:SI 3 "immediate_operand" "i")))]
21068 "TARGET_SSE || TARGET_3DNOW_A"
21069 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21070 [(set_attr "type" "mmxcvt")
21071 (set_attr "mode" "DI")])
21072
21073 (define_insn "mmx_pextrw"
21074 [(set (match_operand:SI 0 "register_operand" "=r")
21075 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21076 (parallel
21077 [(match_operand:SI 2 "immediate_operand" "i")]))))]
21078 "TARGET_SSE || TARGET_3DNOW_A"
21079 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21080 [(set_attr "type" "mmxcvt")
21081 (set_attr "mode" "DI")])
21082
21083 (define_insn "mmx_pshufw"
21084 [(set (match_operand:V4HI 0 "register_operand" "=y")
21085 (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
21086 (match_operand:SI 2 "immediate_operand" "i")]
21087 UNSPEC_SHUFFLE))]
21088 "TARGET_SSE || TARGET_3DNOW_A"
21089 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21090 [(set_attr "type" "mmxcvt")
21091 (set_attr "mode" "DI")])
21092
21093
21094 ;; MMX mask-generating comparisons
21095
21096 (define_insn "eqv8qi3"
21097 [(set (match_operand:V8QI 0 "register_operand" "=y")
21098 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21099 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21100 "TARGET_MMX"
21101 "pcmpeqb\t{%2, %0|%0, %2}"
21102 [(set_attr "type" "mmxcmp")
21103 (set_attr "mode" "DI")])
21104
21105 (define_insn "eqv4hi3"
21106 [(set (match_operand:V4HI 0 "register_operand" "=y")
21107 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21108 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21109 "TARGET_MMX"
21110 "pcmpeqw\t{%2, %0|%0, %2}"
21111 [(set_attr "type" "mmxcmp")
21112 (set_attr "mode" "DI")])
21113
21114 (define_insn "eqv2si3"
21115 [(set (match_operand:V2SI 0 "register_operand" "=y")
21116 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21117 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21118 "TARGET_MMX"
21119 "pcmpeqd\t{%2, %0|%0, %2}"
21120 [(set_attr "type" "mmxcmp")
21121 (set_attr "mode" "DI")])
21122
21123 (define_insn "gtv8qi3"
21124 [(set (match_operand:V8QI 0 "register_operand" "=y")
21125 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21126 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21127 "TARGET_MMX"
21128 "pcmpgtb\t{%2, %0|%0, %2}"
21129 [(set_attr "type" "mmxcmp")
21130 (set_attr "mode" "DI")])
21131
21132 (define_insn "gtv4hi3"
21133 [(set (match_operand:V4HI 0 "register_operand" "=y")
21134 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21135 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21136 "TARGET_MMX"
21137 "pcmpgtw\t{%2, %0|%0, %2}"
21138 [(set_attr "type" "mmxcmp")
21139 (set_attr "mode" "DI")])
21140
21141 (define_insn "gtv2si3"
21142 [(set (match_operand:V2SI 0 "register_operand" "=y")
21143 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21144 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21145 "TARGET_MMX"
21146 "pcmpgtd\t{%2, %0|%0, %2}"
21147 [(set_attr "type" "mmxcmp")
21148 (set_attr "mode" "DI")])
21149
21150
21151 ;; MMX max/min insns
21152
21153 (define_insn "umaxv8qi3"
21154 [(set (match_operand:V8QI 0 "register_operand" "=y")
21155 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
21156 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21157 "TARGET_SSE || TARGET_3DNOW_A"
21158 "pmaxub\t{%2, %0|%0, %2}"
21159 [(set_attr "type" "mmxadd")
21160 (set_attr "mode" "DI")])
21161
21162 (define_insn "smaxv4hi3"
21163 [(set (match_operand:V4HI 0 "register_operand" "=y")
21164 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
21165 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21166 "TARGET_SSE || TARGET_3DNOW_A"
21167 "pmaxsw\t{%2, %0|%0, %2}"
21168 [(set_attr "type" "mmxadd")
21169 (set_attr "mode" "DI")])
21170
21171 (define_insn "uminv8qi3"
21172 [(set (match_operand:V8QI 0 "register_operand" "=y")
21173 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
21174 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21175 "TARGET_SSE || TARGET_3DNOW_A"
21176 "pminub\t{%2, %0|%0, %2}"
21177 [(set_attr "type" "mmxadd")
21178 (set_attr "mode" "DI")])
21179
21180 (define_insn "sminv4hi3"
21181 [(set (match_operand:V4HI 0 "register_operand" "=y")
21182 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
21183 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21184 "TARGET_SSE || TARGET_3DNOW_A"
21185 "pminsw\t{%2, %0|%0, %2}"
21186 [(set_attr "type" "mmxadd")
21187 (set_attr "mode" "DI")])
21188
21189
21190 ;; MMX shifts
21191
21192 (define_insn "ashrv4hi3"
21193 [(set (match_operand:V4HI 0 "register_operand" "=y")
21194 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21195 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21196 "TARGET_MMX"
21197 "psraw\t{%2, %0|%0, %2}"
21198 [(set_attr "type" "mmxshft")
21199 (set_attr "mode" "DI")])
21200
21201 (define_insn "ashrv2si3"
21202 [(set (match_operand:V2SI 0 "register_operand" "=y")
21203 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21204 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21205 "TARGET_MMX"
21206 "psrad\t{%2, %0|%0, %2}"
21207 [(set_attr "type" "mmxshft")
21208 (set_attr "mode" "DI")])
21209
21210 (define_insn "lshrv4hi3"
21211 [(set (match_operand:V4HI 0 "register_operand" "=y")
21212 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21213 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21214 "TARGET_MMX"
21215 "psrlw\t{%2, %0|%0, %2}"
21216 [(set_attr "type" "mmxshft")
21217 (set_attr "mode" "DI")])
21218
21219 (define_insn "lshrv2si3"
21220 [(set (match_operand:V2SI 0 "register_operand" "=y")
21221 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21222 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21223 "TARGET_MMX"
21224 "psrld\t{%2, %0|%0, %2}"
21225 [(set_attr "type" "mmxshft")
21226 (set_attr "mode" "DI")])
21227
21228 ;; See logical MMX insns.
21229 (define_insn "mmx_lshrdi3"
21230 [(set (match_operand:DI 0 "register_operand" "=y")
21231 (unspec:DI
21232 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21233 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21234 UNSPEC_NOP))]
21235 "TARGET_MMX"
21236 "psrlq\t{%2, %0|%0, %2}"
21237 [(set_attr "type" "mmxshft")
21238 (set_attr "mode" "DI")])
21239
21240 (define_insn "ashlv4hi3"
21241 [(set (match_operand:V4HI 0 "register_operand" "=y")
21242 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21243 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21244 "TARGET_MMX"
21245 "psllw\t{%2, %0|%0, %2}"
21246 [(set_attr "type" "mmxshft")
21247 (set_attr "mode" "DI")])
21248
21249 (define_insn "ashlv2si3"
21250 [(set (match_operand:V2SI 0 "register_operand" "=y")
21251 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21252 (match_operand:DI 2 "nonmemory_operand" "yi")))]
21253 "TARGET_MMX"
21254 "pslld\t{%2, %0|%0, %2}"
21255 [(set_attr "type" "mmxshft")
21256 (set_attr "mode" "DI")])
21257
21258 ;; See logical MMX insns.
21259 (define_insn "mmx_ashldi3"
21260 [(set (match_operand:DI 0 "register_operand" "=y")
21261 (unspec:DI
21262 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21263 (match_operand:DI 2 "nonmemory_operand" "yi"))]
21264 UNSPEC_NOP))]
21265 "TARGET_MMX"
21266 "psllq\t{%2, %0|%0, %2}"
21267 [(set_attr "type" "mmxshft")
21268 (set_attr "mode" "DI")])
21269
21270
21271 ;; MMX pack/unpack insns.
21272
21273 (define_insn "mmx_packsswb"
21274 [(set (match_operand:V8QI 0 "register_operand" "=y")
21275 (vec_concat:V8QI
21276 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21277 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21278 "TARGET_MMX"
21279 "packsswb\t{%2, %0|%0, %2}"
21280 [(set_attr "type" "mmxshft")
21281 (set_attr "mode" "DI")])
21282
21283 (define_insn "mmx_packssdw"
21284 [(set (match_operand:V4HI 0 "register_operand" "=y")
21285 (vec_concat:V4HI
21286 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21287 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21288 "TARGET_MMX"
21289 "packssdw\t{%2, %0|%0, %2}"
21290 [(set_attr "type" "mmxshft")
21291 (set_attr "mode" "DI")])
21292
21293 (define_insn "mmx_packuswb"
21294 [(set (match_operand:V8QI 0 "register_operand" "=y")
21295 (vec_concat:V8QI
21296 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21297 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21298 "TARGET_MMX"
21299 "packuswb\t{%2, %0|%0, %2}"
21300 [(set_attr "type" "mmxshft")
21301 (set_attr "mode" "DI")])
21302
21303 (define_insn "mmx_punpckhbw"
21304 [(set (match_operand:V8QI 0 "register_operand" "=y")
21305 (vec_merge:V8QI
21306 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21307 (parallel [(const_int 4)
21308 (const_int 0)
21309 (const_int 5)
21310 (const_int 1)
21311 (const_int 6)
21312 (const_int 2)
21313 (const_int 7)
21314 (const_int 3)]))
21315 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21316 (parallel [(const_int 0)
21317 (const_int 4)
21318 (const_int 1)
21319 (const_int 5)
21320 (const_int 2)
21321 (const_int 6)
21322 (const_int 3)
21323 (const_int 7)]))
21324 (const_int 85)))]
21325 "TARGET_MMX"
21326 "punpckhbw\t{%2, %0|%0, %2}"
21327 [(set_attr "type" "mmxcvt")
21328 (set_attr "mode" "DI")])
21329
21330 (define_insn "mmx_punpckhwd"
21331 [(set (match_operand:V4HI 0 "register_operand" "=y")
21332 (vec_merge:V4HI
21333 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21334 (parallel [(const_int 0)
21335 (const_int 2)
21336 (const_int 1)
21337 (const_int 3)]))
21338 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21339 (parallel [(const_int 2)
21340 (const_int 0)
21341 (const_int 3)
21342 (const_int 1)]))
21343 (const_int 5)))]
21344 "TARGET_MMX"
21345 "punpckhwd\t{%2, %0|%0, %2}"
21346 [(set_attr "type" "mmxcvt")
21347 (set_attr "mode" "DI")])
21348
21349 (define_insn "mmx_punpckhdq"
21350 [(set (match_operand:V2SI 0 "register_operand" "=y")
21351 (vec_merge:V2SI
21352 (match_operand:V2SI 1 "register_operand" "0")
21353 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21354 (parallel [(const_int 1)
21355 (const_int 0)]))
21356 (const_int 1)))]
21357 "TARGET_MMX"
21358 "punpckhdq\t{%2, %0|%0, %2}"
21359 [(set_attr "type" "mmxcvt")
21360 (set_attr "mode" "DI")])
21361
21362 (define_insn "mmx_punpcklbw"
21363 [(set (match_operand:V8QI 0 "register_operand" "=y")
21364 (vec_merge:V8QI
21365 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21366 (parallel [(const_int 0)
21367 (const_int 4)
21368 (const_int 1)
21369 (const_int 5)
21370 (const_int 2)
21371 (const_int 6)
21372 (const_int 3)
21373 (const_int 7)]))
21374 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21375 (parallel [(const_int 4)
21376 (const_int 0)
21377 (const_int 5)
21378 (const_int 1)
21379 (const_int 6)
21380 (const_int 2)
21381 (const_int 7)
21382 (const_int 3)]))
21383 (const_int 85)))]
21384 "TARGET_MMX"
21385 "punpcklbw\t{%2, %0|%0, %2}"
21386 [(set_attr "type" "mmxcvt")
21387 (set_attr "mode" "DI")])
21388
21389 (define_insn "mmx_punpcklwd"
21390 [(set (match_operand:V4HI 0 "register_operand" "=y")
21391 (vec_merge:V4HI
21392 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21393 (parallel [(const_int 2)
21394 (const_int 0)
21395 (const_int 3)
21396 (const_int 1)]))
21397 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21398 (parallel [(const_int 0)
21399 (const_int 2)
21400 (const_int 1)
21401 (const_int 3)]))
21402 (const_int 5)))]
21403 "TARGET_MMX"
21404 "punpcklwd\t{%2, %0|%0, %2}"
21405 [(set_attr "type" "mmxcvt")
21406 (set_attr "mode" "DI")])
21407
21408 (define_insn "mmx_punpckldq"
21409 [(set (match_operand:V2SI 0 "register_operand" "=y")
21410 (vec_merge:V2SI
21411 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21412 (parallel [(const_int 1)
21413 (const_int 0)]))
21414 (match_operand:V2SI 2 "register_operand" "y")
21415 (const_int 1)))]
21416 "TARGET_MMX"
21417 "punpckldq\t{%2, %0|%0, %2}"
21418 [(set_attr "type" "mmxcvt")
21419 (set_attr "mode" "DI")])
21420
21421
21422 ;; Miscellaneous stuff
21423
21424 (define_insn "emms"
21425 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21426 (clobber (reg:XF 8))
21427 (clobber (reg:XF 9))
21428 (clobber (reg:XF 10))
21429 (clobber (reg:XF 11))
21430 (clobber (reg:XF 12))
21431 (clobber (reg:XF 13))
21432 (clobber (reg:XF 14))
21433 (clobber (reg:XF 15))
21434 (clobber (reg:DI 29))
21435 (clobber (reg:DI 30))
21436 (clobber (reg:DI 31))
21437 (clobber (reg:DI 32))
21438 (clobber (reg:DI 33))
21439 (clobber (reg:DI 34))
21440 (clobber (reg:DI 35))
21441 (clobber (reg:DI 36))]
21442 "TARGET_MMX"
21443 "emms"
21444 [(set_attr "type" "mmx")
21445 (set_attr "memory" "unknown")])
21446
21447 (define_insn "ldmxcsr"
21448 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21449 UNSPECV_LDMXCSR)]
21450 "TARGET_SSE"
21451 "ldmxcsr\t%0"
21452 [(set_attr "type" "sse")
21453 (set_attr "memory" "load")])
21454
21455 (define_insn "stmxcsr"
21456 [(set (match_operand:SI 0 "memory_operand" "=m")
21457 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21458 "TARGET_SSE"
21459 "stmxcsr\t%0"
21460 [(set_attr "type" "sse")
21461 (set_attr "memory" "store")])
21462
21463 (define_expand "sfence"
21464 [(set (match_dup 0)
21465 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21466 "TARGET_SSE || TARGET_3DNOW_A"
21467 {
21468 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21469 MEM_VOLATILE_P (operands[0]) = 1;
21470 })
21471
21472 (define_insn "*sfence_insn"
21473 [(set (match_operand:BLK 0 "" "")
21474 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21475 "TARGET_SSE || TARGET_3DNOW_A"
21476 "sfence"
21477 [(set_attr "type" "sse")
21478 (set_attr "memory" "unknown")])
21479
21480 (define_expand "sse_prologue_save"
21481 [(parallel [(set (match_operand:BLK 0 "" "")
21482 (unspec:BLK [(reg:DI 21)
21483 (reg:DI 22)
21484 (reg:DI 23)
21485 (reg:DI 24)
21486 (reg:DI 25)
21487 (reg:DI 26)
21488 (reg:DI 27)
21489 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21490 (use (match_operand:DI 1 "register_operand" ""))
21491 (use (match_operand:DI 2 "immediate_operand" ""))
21492 (use (label_ref:DI (match_operand 3 "" "")))])]
21493 "TARGET_64BIT"
21494 "")
21495
21496 (define_insn "*sse_prologue_save_insn"
21497 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21498 (match_operand:DI 4 "const_int_operand" "n")))
21499 (unspec:BLK [(reg:DI 21)
21500 (reg:DI 22)
21501 (reg:DI 23)
21502 (reg:DI 24)
21503 (reg:DI 25)
21504 (reg:DI 26)
21505 (reg:DI 27)
21506 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21507 (use (match_operand:DI 1 "register_operand" "r"))
21508 (use (match_operand:DI 2 "const_int_operand" "i"))
21509 (use (label_ref:DI (match_operand 3 "" "X")))]
21510 "TARGET_64BIT
21511 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21512 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21513 "*
21514 {
21515 int i;
21516 operands[0] = gen_rtx_MEM (Pmode,
21517 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21518 output_asm_insn (\"jmp\\t%A1\", operands);
21519 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21520 {
21521 operands[4] = adjust_address (operands[0], DImode, i*16);
21522 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21523 PUT_MODE (operands[4], TImode);
21524 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21525 output_asm_insn (\"rex\", operands);
21526 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21527 }
21528 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21529 CODE_LABEL_NUMBER (operands[3]));
21530 RET;
21531 }
21532 "
21533 [(set_attr "type" "other")
21534 (set_attr "length_immediate" "0")
21535 (set_attr "length_address" "0")
21536 (set_attr "length" "135")
21537 (set_attr "memory" "store")
21538 (set_attr "modrm" "0")
21539 (set_attr "mode" "DI")])
21540
21541 ;; 3Dnow! instructions
21542
21543 (define_insn "addv2sf3"
21544 [(set (match_operand:V2SF 0 "register_operand" "=y")
21545 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21546 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21547 "TARGET_3DNOW"
21548 "pfadd\\t{%2, %0|%0, %2}"
21549 [(set_attr "type" "mmxadd")
21550 (set_attr "mode" "V2SF")])
21551
21552 (define_insn "subv2sf3"
21553 [(set (match_operand:V2SF 0 "register_operand" "=y")
21554 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21555 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21556 "TARGET_3DNOW"
21557 "pfsub\\t{%2, %0|%0, %2}"
21558 [(set_attr "type" "mmxadd")
21559 (set_attr "mode" "V2SF")])
21560
21561 (define_insn "subrv2sf3"
21562 [(set (match_operand:V2SF 0 "register_operand" "=y")
21563 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21564 (match_operand:V2SF 1 "register_operand" "0")))]
21565 "TARGET_3DNOW"
21566 "pfsubr\\t{%2, %0|%0, %2}"
21567 [(set_attr "type" "mmxadd")
21568 (set_attr "mode" "V2SF")])
21569
21570 (define_insn "gtv2sf3"
21571 [(set (match_operand:V2SI 0 "register_operand" "=y")
21572 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21573 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21574 "TARGET_3DNOW"
21575 "pfcmpgt\\t{%2, %0|%0, %2}"
21576 [(set_attr "type" "mmxcmp")
21577 (set_attr "mode" "V2SF")])
21578
21579 (define_insn "gev2sf3"
21580 [(set (match_operand:V2SI 0 "register_operand" "=y")
21581 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21582 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21583 "TARGET_3DNOW"
21584 "pfcmpge\\t{%2, %0|%0, %2}"
21585 [(set_attr "type" "mmxcmp")
21586 (set_attr "mode" "V2SF")])
21587
21588 (define_insn "eqv2sf3"
21589 [(set (match_operand:V2SI 0 "register_operand" "=y")
21590 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21591 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21592 "TARGET_3DNOW"
21593 "pfcmpeq\\t{%2, %0|%0, %2}"
21594 [(set_attr "type" "mmxcmp")
21595 (set_attr "mode" "V2SF")])
21596
21597 (define_insn "pfmaxv2sf3"
21598 [(set (match_operand:V2SF 0 "register_operand" "=y")
21599 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21600 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21601 "TARGET_3DNOW"
21602 "pfmax\\t{%2, %0|%0, %2}"
21603 [(set_attr "type" "mmxadd")
21604 (set_attr "mode" "V2SF")])
21605
21606 (define_insn "pfminv2sf3"
21607 [(set (match_operand:V2SF 0 "register_operand" "=y")
21608 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21609 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21610 "TARGET_3DNOW"
21611 "pfmin\\t{%2, %0|%0, %2}"
21612 [(set_attr "type" "mmxadd")
21613 (set_attr "mode" "V2SF")])
21614
21615 (define_insn "mulv2sf3"
21616 [(set (match_operand:V2SF 0 "register_operand" "=y")
21617 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21618 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21619 "TARGET_3DNOW"
21620 "pfmul\\t{%2, %0|%0, %2}"
21621 [(set_attr "type" "mmxmul")
21622 (set_attr "mode" "V2SF")])
21623
21624 (define_insn "femms"
21625 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21626 (clobber (reg:XF 8))
21627 (clobber (reg:XF 9))
21628 (clobber (reg:XF 10))
21629 (clobber (reg:XF 11))
21630 (clobber (reg:XF 12))
21631 (clobber (reg:XF 13))
21632 (clobber (reg:XF 14))
21633 (clobber (reg:XF 15))
21634 (clobber (reg:DI 29))
21635 (clobber (reg:DI 30))
21636 (clobber (reg:DI 31))
21637 (clobber (reg:DI 32))
21638 (clobber (reg:DI 33))
21639 (clobber (reg:DI 34))
21640 (clobber (reg:DI 35))
21641 (clobber (reg:DI 36))]
21642 "TARGET_3DNOW"
21643 "femms"
21644 [(set_attr "type" "mmx")
21645 (set_attr "memory" "none")])
21646
21647 (define_insn "pf2id"
21648 [(set (match_operand:V2SI 0 "register_operand" "=y")
21649 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21650 "TARGET_3DNOW"
21651 "pf2id\\t{%1, %0|%0, %1}"
21652 [(set_attr "type" "mmxcvt")
21653 (set_attr "mode" "V2SF")])
21654
21655 (define_insn "pf2iw"
21656 [(set (match_operand:V2SI 0 "register_operand" "=y")
21657 (sign_extend:V2SI
21658 (ss_truncate:V2HI
21659 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21660 "TARGET_3DNOW_A"
21661 "pf2iw\\t{%1, %0|%0, %1}"
21662 [(set_attr "type" "mmxcvt")
21663 (set_attr "mode" "V2SF")])
21664
21665 (define_insn "pfacc"
21666 [(set (match_operand:V2SF 0 "register_operand" "=y")
21667 (vec_concat:V2SF
21668 (plus:SF
21669 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21670 (parallel [(const_int 0)]))
21671 (vec_select:SF (match_dup 1)
21672 (parallel [(const_int 1)])))
21673 (plus:SF
21674 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21675 (parallel [(const_int 0)]))
21676 (vec_select:SF (match_dup 2)
21677 (parallel [(const_int 1)])))))]
21678 "TARGET_3DNOW"
21679 "pfacc\\t{%2, %0|%0, %2}"
21680 [(set_attr "type" "mmxadd")
21681 (set_attr "mode" "V2SF")])
21682
21683 (define_insn "pfnacc"
21684 [(set (match_operand:V2SF 0 "register_operand" "=y")
21685 (vec_concat:V2SF
21686 (minus:SF
21687 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21688 (parallel [(const_int 0)]))
21689 (vec_select:SF (match_dup 1)
21690 (parallel [(const_int 1)])))
21691 (minus:SF
21692 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21693 (parallel [(const_int 0)]))
21694 (vec_select:SF (match_dup 2)
21695 (parallel [(const_int 1)])))))]
21696 "TARGET_3DNOW_A"
21697 "pfnacc\\t{%2, %0|%0, %2}"
21698 [(set_attr "type" "mmxadd")
21699 (set_attr "mode" "V2SF")])
21700
21701 (define_insn "pfpnacc"
21702 [(set (match_operand:V2SF 0 "register_operand" "=y")
21703 (vec_concat:V2SF
21704 (minus:SF
21705 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21706 (parallel [(const_int 0)]))
21707 (vec_select:SF (match_dup 1)
21708 (parallel [(const_int 1)])))
21709 (plus:SF
21710 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21711 (parallel [(const_int 0)]))
21712 (vec_select:SF (match_dup 2)
21713 (parallel [(const_int 1)])))))]
21714 "TARGET_3DNOW_A"
21715 "pfpnacc\\t{%2, %0|%0, %2}"
21716 [(set_attr "type" "mmxadd")
21717 (set_attr "mode" "V2SF")])
21718
21719 (define_insn "pi2fw"
21720 [(set (match_operand:V2SF 0 "register_operand" "=y")
21721 (float:V2SF
21722 (vec_concat:V2SI
21723 (sign_extend:SI
21724 (truncate:HI
21725 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21726 (parallel [(const_int 0)]))))
21727 (sign_extend:SI
21728 (truncate:HI
21729 (vec_select:SI (match_dup 1)
21730 (parallel [(const_int 1)])))))))]
21731 "TARGET_3DNOW_A"
21732 "pi2fw\\t{%1, %0|%0, %1}"
21733 [(set_attr "type" "mmxcvt")
21734 (set_attr "mode" "V2SF")])
21735
21736 (define_insn "floatv2si2"
21737 [(set (match_operand:V2SF 0 "register_operand" "=y")
21738 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21739 "TARGET_3DNOW"
21740 "pi2fd\\t{%1, %0|%0, %1}"
21741 [(set_attr "type" "mmxcvt")
21742 (set_attr "mode" "V2SF")])
21743
21744 ;; This insn is identical to pavgb in operation, but the opcode is
21745 ;; different. To avoid accidentally matching pavgb, use an unspec.
21746
21747 (define_insn "pavgusb"
21748 [(set (match_operand:V8QI 0 "register_operand" "=y")
21749 (unspec:V8QI
21750 [(match_operand:V8QI 1 "register_operand" "0")
21751 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21752 UNSPEC_PAVGUSB))]
21753 "TARGET_3DNOW"
21754 "pavgusb\\t{%2, %0|%0, %2}"
21755 [(set_attr "type" "mmxshft")
21756 (set_attr "mode" "TI")])
21757
21758 ;; 3DNow reciprocal and sqrt
21759
21760 (define_insn "pfrcpv2sf2"
21761 [(set (match_operand:V2SF 0 "register_operand" "=y")
21762 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21763 UNSPEC_PFRCP))]
21764 "TARGET_3DNOW"
21765 "pfrcp\\t{%1, %0|%0, %1}"
21766 [(set_attr "type" "mmx")
21767 (set_attr "mode" "TI")])
21768
21769 (define_insn "pfrcpit1v2sf3"
21770 [(set (match_operand:V2SF 0 "register_operand" "=y")
21771 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21772 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21773 UNSPEC_PFRCPIT1))]
21774 "TARGET_3DNOW"
21775 "pfrcpit1\\t{%2, %0|%0, %2}"
21776 [(set_attr "type" "mmx")
21777 (set_attr "mode" "TI")])
21778
21779 (define_insn "pfrcpit2v2sf3"
21780 [(set (match_operand:V2SF 0 "register_operand" "=y")
21781 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21782 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21783 UNSPEC_PFRCPIT2))]
21784 "TARGET_3DNOW"
21785 "pfrcpit2\\t{%2, %0|%0, %2}"
21786 [(set_attr "type" "mmx")
21787 (set_attr "mode" "TI")])
21788
21789 (define_insn "pfrsqrtv2sf2"
21790 [(set (match_operand:V2SF 0 "register_operand" "=y")
21791 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21792 UNSPEC_PFRSQRT))]
21793 "TARGET_3DNOW"
21794 "pfrsqrt\\t{%1, %0|%0, %1}"
21795 [(set_attr "type" "mmx")
21796 (set_attr "mode" "TI")])
21797
21798 (define_insn "pfrsqit1v2sf3"
21799 [(set (match_operand:V2SF 0 "register_operand" "=y")
21800 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21801 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21802 UNSPEC_PFRSQIT1))]
21803 "TARGET_3DNOW"
21804 "pfrsqit1\\t{%2, %0|%0, %2}"
21805 [(set_attr "type" "mmx")
21806 (set_attr "mode" "TI")])
21807
21808 (define_insn "pmulhrwv4hi3"
21809 [(set (match_operand:V4HI 0 "register_operand" "=y")
21810 (truncate:V4HI
21811 (lshiftrt:V4SI
21812 (plus:V4SI
21813 (mult:V4SI
21814 (sign_extend:V4SI
21815 (match_operand:V4HI 1 "register_operand" "0"))
21816 (sign_extend:V4SI
21817 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21818 (const_vector:V4SI [(const_int 32768)
21819 (const_int 32768)
21820 (const_int 32768)
21821 (const_int 32768)]))
21822 (const_int 16))))]
21823 "TARGET_3DNOW"
21824 "pmulhrw\\t{%2, %0|%0, %2}"
21825 [(set_attr "type" "mmxmul")
21826 (set_attr "mode" "TI")])
21827
21828 (define_insn "pswapdv2si2"
21829 [(set (match_operand:V2SI 0 "register_operand" "=y")
21830 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21831 (parallel [(const_int 1) (const_int 0)])))]
21832 "TARGET_3DNOW_A"
21833 "pswapd\\t{%1, %0|%0, %1}"
21834 [(set_attr "type" "mmxcvt")
21835 (set_attr "mode" "TI")])
21836
21837 (define_insn "pswapdv2sf2"
21838 [(set (match_operand:V2SF 0 "register_operand" "=y")
21839 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21840 (parallel [(const_int 1) (const_int 0)])))]
21841 "TARGET_3DNOW_A"
21842 "pswapd\\t{%1, %0|%0, %1}"
21843 [(set_attr "type" "mmxcvt")
21844 (set_attr "mode" "TI")])
21845
21846 (define_expand "prefetch"
21847 [(prefetch (match_operand 0 "address_operand" "")
21848 (match_operand:SI 1 "const_int_operand" "")
21849 (match_operand:SI 2 "const_int_operand" ""))]
21850 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21851 {
21852 int rw = INTVAL (operands[1]);
21853 int locality = INTVAL (operands[2]);
21854
21855 if (rw != 0 && rw != 1)
21856 abort ();
21857 if (locality < 0 || locality > 3)
21858 abort ();
21859 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21860 abort ();
21861
21862 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21863 suported by SSE counterpart or the SSE prefetch is not available
21864 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21865 of locality. */
21866 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21867 operands[2] = GEN_INT (3);
21868 else
21869 operands[1] = const0_rtx;
21870 })
21871
21872 (define_insn "*prefetch_sse"
21873 [(prefetch (match_operand:SI 0 "address_operand" "p")
21874 (const_int 0)
21875 (match_operand:SI 1 "const_int_operand" ""))]
21876 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21877 {
21878 static const char * const patterns[4] = {
21879 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21880 };
21881
21882 int locality = INTVAL (operands[1]);
21883 if (locality < 0 || locality > 3)
21884 abort ();
21885
21886 return patterns[locality];
21887 }
21888 [(set_attr "type" "sse")
21889 (set_attr "memory" "none")])
21890
21891 (define_insn "*prefetch_sse_rex"
21892 [(prefetch (match_operand:DI 0 "address_operand" "p")
21893 (const_int 0)
21894 (match_operand:SI 1 "const_int_operand" ""))]
21895 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21896 {
21897 static const char * const patterns[4] = {
21898 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21899 };
21900
21901 int locality = INTVAL (operands[1]);
21902 if (locality < 0 || locality > 3)
21903 abort ();
21904
21905 return patterns[locality];
21906 }
21907 [(set_attr "type" "sse")
21908 (set_attr "memory" "none")])
21909
21910 (define_insn "*prefetch_3dnow"
21911 [(prefetch (match_operand:SI 0 "address_operand" "p")
21912 (match_operand:SI 1 "const_int_operand" "n")
21913 (const_int 3))]
21914 "TARGET_3DNOW && !TARGET_64BIT"
21915 {
21916 if (INTVAL (operands[1]) == 0)
21917 return "prefetch\t%a0";
21918 else
21919 return "prefetchw\t%a0";
21920 }
21921 [(set_attr "type" "mmx")
21922 (set_attr "memory" "none")])
21923
21924 (define_insn "*prefetch_3dnow_rex"
21925 [(prefetch (match_operand:DI 0 "address_operand" "p")
21926 (match_operand:SI 1 "const_int_operand" "n")
21927 (const_int 3))]
21928 "TARGET_3DNOW && TARGET_64BIT"
21929 {
21930 if (INTVAL (operands[1]) == 0)
21931 return "prefetch\t%a0";
21932 else
21933 return "prefetchw\t%a0";
21934 }
21935 [(set_attr "type" "mmx")
21936 (set_attr "memory" "none")])
21937
21938 ;; SSE2 support
21939
21940 (define_insn "addv2df3"
21941 [(set (match_operand:V2DF 0 "register_operand" "=x")
21942 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21943 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21944 "TARGET_SSE2"
21945 "addpd\t{%2, %0|%0, %2}"
21946 [(set_attr "type" "sseadd")
21947 (set_attr "mode" "V2DF")])
21948
21949 (define_insn "vmaddv2df3"
21950 [(set (match_operand:V2DF 0 "register_operand" "=x")
21951 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21952 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21953 (match_dup 1)
21954 (const_int 1)))]
21955 "TARGET_SSE2"
21956 "addsd\t{%2, %0|%0, %2}"
21957 [(set_attr "type" "sseadd")
21958 (set_attr "mode" "DF")])
21959
21960 (define_insn "subv2df3"
21961 [(set (match_operand:V2DF 0 "register_operand" "=x")
21962 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21963 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21964 "TARGET_SSE2"
21965 "subpd\t{%2, %0|%0, %2}"
21966 [(set_attr "type" "sseadd")
21967 (set_attr "mode" "V2DF")])
21968
21969 (define_insn "vmsubv2df3"
21970 [(set (match_operand:V2DF 0 "register_operand" "=x")
21971 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21972 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21973 (match_dup 1)
21974 (const_int 1)))]
21975 "TARGET_SSE2"
21976 "subsd\t{%2, %0|%0, %2}"
21977 [(set_attr "type" "sseadd")
21978 (set_attr "mode" "DF")])
21979
21980 (define_insn "mulv2df3"
21981 [(set (match_operand:V2DF 0 "register_operand" "=x")
21982 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21983 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21984 "TARGET_SSE2"
21985 "mulpd\t{%2, %0|%0, %2}"
21986 [(set_attr "type" "ssemul")
21987 (set_attr "mode" "V2DF")])
21988
21989 (define_insn "vmmulv2df3"
21990 [(set (match_operand:V2DF 0 "register_operand" "=x")
21991 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21992 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21993 (match_dup 1)
21994 (const_int 1)))]
21995 "TARGET_SSE2"
21996 "mulsd\t{%2, %0|%0, %2}"
21997 [(set_attr "type" "ssemul")
21998 (set_attr "mode" "DF")])
21999
22000 (define_insn "divv2df3"
22001 [(set (match_operand:V2DF 0 "register_operand" "=x")
22002 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22003 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22004 "TARGET_SSE2"
22005 "divpd\t{%2, %0|%0, %2}"
22006 [(set_attr "type" "ssediv")
22007 (set_attr "mode" "V2DF")])
22008
22009 (define_insn "vmdivv2df3"
22010 [(set (match_operand:V2DF 0 "register_operand" "=x")
22011 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22012 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22013 (match_dup 1)
22014 (const_int 1)))]
22015 "TARGET_SSE2"
22016 "divsd\t{%2, %0|%0, %2}"
22017 [(set_attr "type" "ssediv")
22018 (set_attr "mode" "DF")])
22019
22020 ;; SSE min/max
22021
22022 (define_insn "smaxv2df3"
22023 [(set (match_operand:V2DF 0 "register_operand" "=x")
22024 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22025 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22026 "TARGET_SSE2"
22027 "maxpd\t{%2, %0|%0, %2}"
22028 [(set_attr "type" "sseadd")
22029 (set_attr "mode" "V2DF")])
22030
22031 (define_insn "vmsmaxv2df3"
22032 [(set (match_operand:V2DF 0 "register_operand" "=x")
22033 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22034 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22035 (match_dup 1)
22036 (const_int 1)))]
22037 "TARGET_SSE2"
22038 "maxsd\t{%2, %0|%0, %2}"
22039 [(set_attr "type" "sseadd")
22040 (set_attr "mode" "DF")])
22041
22042 (define_insn "sminv2df3"
22043 [(set (match_operand:V2DF 0 "register_operand" "=x")
22044 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22045 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22046 "TARGET_SSE2"
22047 "minpd\t{%2, %0|%0, %2}"
22048 [(set_attr "type" "sseadd")
22049 (set_attr "mode" "V2DF")])
22050
22051 (define_insn "vmsminv2df3"
22052 [(set (match_operand:V2DF 0 "register_operand" "=x")
22053 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22054 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22055 (match_dup 1)
22056 (const_int 1)))]
22057 "TARGET_SSE2"
22058 "minsd\t{%2, %0|%0, %2}"
22059 [(set_attr "type" "sseadd")
22060 (set_attr "mode" "DF")])
22061 ;; SSE2 square root. There doesn't appear to be an extension for the
22062 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22063
22064 (define_insn "sqrtv2df2"
22065 [(set (match_operand:V2DF 0 "register_operand" "=x")
22066 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22067 "TARGET_SSE2"
22068 "sqrtpd\t{%1, %0|%0, %1}"
22069 [(set_attr "type" "sse")
22070 (set_attr "mode" "V2DF")])
22071
22072 (define_insn "vmsqrtv2df2"
22073 [(set (match_operand:V2DF 0 "register_operand" "=x")
22074 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22075 (match_operand:V2DF 2 "register_operand" "0")
22076 (const_int 1)))]
22077 "TARGET_SSE2"
22078 "sqrtsd\t{%1, %0|%0, %1}"
22079 [(set_attr "type" "sse")
22080 (set_attr "mode" "SF")])
22081
22082 ;; SSE mask-generating compares
22083
22084 (define_insn "maskcmpv2df3"
22085 [(set (match_operand:V2DI 0 "register_operand" "=x")
22086 (match_operator:V2DI 3 "sse_comparison_operator"
22087 [(match_operand:V2DF 1 "register_operand" "0")
22088 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22089 "TARGET_SSE2"
22090 "cmp%D3pd\t{%2, %0|%0, %2}"
22091 [(set_attr "type" "ssecmp")
22092 (set_attr "mode" "V2DF")])
22093
22094 (define_insn "maskncmpv2df3"
22095 [(set (match_operand:V2DI 0 "register_operand" "=x")
22096 (not:V2DI
22097 (match_operator:V2DI 3 "sse_comparison_operator"
22098 [(match_operand:V2DF 1 "register_operand" "0")
22099 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22100 "TARGET_SSE2"
22101 {
22102 if (GET_CODE (operands[3]) == UNORDERED)
22103 return "cmpordps\t{%2, %0|%0, %2}";
22104 else
22105 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22106 }
22107 [(set_attr "type" "ssecmp")
22108 (set_attr "mode" "V2DF")])
22109
22110 (define_insn "vmmaskcmpv2df3"
22111 [(set (match_operand:V2DI 0 "register_operand" "=x")
22112 (vec_merge:V2DI
22113 (match_operator:V2DI 3 "sse_comparison_operator"
22114 [(match_operand:V2DF 1 "register_operand" "0")
22115 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22116 (subreg:V2DI (match_dup 1) 0)
22117 (const_int 1)))]
22118 "TARGET_SSE2"
22119 "cmp%D3sd\t{%2, %0|%0, %2}"
22120 [(set_attr "type" "ssecmp")
22121 (set_attr "mode" "DF")])
22122
22123 (define_insn "vmmaskncmpv2df3"
22124 [(set (match_operand:V2DI 0 "register_operand" "=x")
22125 (vec_merge:V2DI
22126 (not:V2DI
22127 (match_operator:V2DI 3 "sse_comparison_operator"
22128 [(match_operand:V2DF 1 "register_operand" "0")
22129 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22130 (subreg:V2DI (match_dup 1) 0)
22131 (const_int 1)))]
22132 "TARGET_SSE2"
22133 {
22134 if (GET_CODE (operands[3]) == UNORDERED)
22135 return "cmpordsd\t{%2, %0|%0, %2}";
22136 else
22137 return "cmpn%D3sd\t{%2, %0|%0, %2}";
22138 }
22139 [(set_attr "type" "ssecmp")
22140 (set_attr "mode" "DF")])
22141
22142 (define_insn "sse2_comi"
22143 [(set (reg:CCFP 17)
22144 (compare:CCFP (vec_select:DF
22145 (match_operand:V2DF 0 "register_operand" "x")
22146 (parallel [(const_int 0)]))
22147 (vec_select:DF
22148 (match_operand:V2DF 1 "register_operand" "x")
22149 (parallel [(const_int 0)]))))]
22150 "TARGET_SSE2"
22151 "comisd\t{%1, %0|%0, %1}"
22152 [(set_attr "type" "ssecomi")
22153 (set_attr "mode" "DF")])
22154
22155 (define_insn "sse2_ucomi"
22156 [(set (reg:CCFPU 17)
22157 (compare:CCFPU (vec_select:DF
22158 (match_operand:V2DF 0 "register_operand" "x")
22159 (parallel [(const_int 0)]))
22160 (vec_select:DF
22161 (match_operand:V2DF 1 "register_operand" "x")
22162 (parallel [(const_int 0)]))))]
22163 "TARGET_SSE2"
22164 "ucomisd\t{%1, %0|%0, %1}"
22165 [(set_attr "type" "ssecomi")
22166 (set_attr "mode" "DF")])
22167
22168 ;; SSE Strange Moves.
22169
22170 (define_insn "sse2_movmskpd"
22171 [(set (match_operand:SI 0 "register_operand" "=r")
22172 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
22173 UNSPEC_MOVMSK))]
22174 "TARGET_SSE2"
22175 "movmskpd\t{%1, %0|%0, %1}"
22176 [(set_attr "type" "ssecvt")
22177 (set_attr "mode" "V2DF")])
22178
22179 (define_insn "sse2_pmovmskb"
22180 [(set (match_operand:SI 0 "register_operand" "=r")
22181 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
22182 UNSPEC_MOVMSK))]
22183 "TARGET_SSE2"
22184 "pmovmskb\t{%1, %0|%0, %1}"
22185 [(set_attr "type" "ssecvt")
22186 (set_attr "mode" "V2DF")])
22187
22188 (define_insn "sse2_maskmovdqu"
22189 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
22190 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22191 (match_operand:V16QI 2 "register_operand" "x")]
22192 UNSPEC_MASKMOV))]
22193 "TARGET_SSE2"
22194 ;; @@@ check ordering of operands in intel/nonintel syntax
22195 "maskmovdqu\t{%2, %1|%1, %2}"
22196 [(set_attr "type" "ssecvt")
22197 (set_attr "mode" "TI")])
22198
22199 (define_insn "sse2_maskmovdqu_rex64"
22200 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22201 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22202 (match_operand:V16QI 2 "register_operand" "x")]
22203 UNSPEC_MASKMOV))]
22204 "TARGET_SSE2"
22205 ;; @@@ check ordering of operands in intel/nonintel syntax
22206 "maskmovdqu\t{%2, %1|%1, %2}"
22207 [(set_attr "type" "ssecvt")
22208 (set_attr "mode" "TI")])
22209
22210 (define_insn "sse2_movntv2df"
22211 [(set (match_operand:V2DF 0 "memory_operand" "=m")
22212 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22213 UNSPEC_MOVNT))]
22214 "TARGET_SSE2"
22215 "movntpd\t{%1, %0|%0, %1}"
22216 [(set_attr "type" "ssecvt")
22217 (set_attr "mode" "V2DF")])
22218
22219 (define_insn "sse2_movntv2di"
22220 [(set (match_operand:V2DI 0 "memory_operand" "=m")
22221 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22222 UNSPEC_MOVNT))]
22223 "TARGET_SSE2"
22224 "movntdq\t{%1, %0|%0, %1}"
22225 [(set_attr "type" "ssecvt")
22226 (set_attr "mode" "TI")])
22227
22228 (define_insn "sse2_movntsi"
22229 [(set (match_operand:SI 0 "memory_operand" "=m")
22230 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22231 UNSPEC_MOVNT))]
22232 "TARGET_SSE2"
22233 "movnti\t{%1, %0|%0, %1}"
22234 [(set_attr "type" "ssecvt")
22235 (set_attr "mode" "V2DF")])
22236
22237 ;; SSE <-> integer/MMX conversions
22238
22239 ;; Conversions between SI and SF
22240
22241 (define_insn "cvtdq2ps"
22242 [(set (match_operand:V4SF 0 "register_operand" "=x")
22243 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22244 "TARGET_SSE2"
22245 "cvtdq2ps\t{%1, %0|%0, %1}"
22246 [(set_attr "type" "ssecvt")
22247 (set_attr "mode" "V2DF")])
22248
22249 (define_insn "cvtps2dq"
22250 [(set (match_operand:V4SI 0 "register_operand" "=x")
22251 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22252 "TARGET_SSE2"
22253 "cvtps2dq\t{%1, %0|%0, %1}"
22254 [(set_attr "type" "ssecvt")
22255 (set_attr "mode" "TI")])
22256
22257 (define_insn "cvttps2dq"
22258 [(set (match_operand:V4SI 0 "register_operand" "=x")
22259 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22260 UNSPEC_FIX))]
22261 "TARGET_SSE2"
22262 "cvttps2dq\t{%1, %0|%0, %1}"
22263 [(set_attr "type" "ssecvt")
22264 (set_attr "mode" "TI")])
22265
22266 ;; Conversions between SI and DF
22267
22268 (define_insn "cvtdq2pd"
22269 [(set (match_operand:V2DF 0 "register_operand" "=x")
22270 (float:V2DF (vec_select:V2SI
22271 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22272 (parallel
22273 [(const_int 0)
22274 (const_int 1)]))))]
22275 "TARGET_SSE2"
22276 "cvtdq2pd\t{%1, %0|%0, %1}"
22277 [(set_attr "type" "ssecvt")
22278 (set_attr "mode" "V2DF")])
22279
22280 (define_insn "cvtpd2dq"
22281 [(set (match_operand:V4SI 0 "register_operand" "=x")
22282 (vec_concat:V4SI
22283 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22284 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22285 "TARGET_SSE2"
22286 "cvtpd2dq\t{%1, %0|%0, %1}"
22287 [(set_attr "type" "ssecvt")
22288 (set_attr "mode" "TI")])
22289
22290 (define_insn "cvttpd2dq"
22291 [(set (match_operand:V4SI 0 "register_operand" "=x")
22292 (vec_concat:V4SI
22293 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22294 UNSPEC_FIX)
22295 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22296 "TARGET_SSE2"
22297 "cvttpd2dq\t{%1, %0|%0, %1}"
22298 [(set_attr "type" "ssecvt")
22299 (set_attr "mode" "TI")])
22300
22301 (define_insn "cvtpd2pi"
22302 [(set (match_operand:V2SI 0 "register_operand" "=y")
22303 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22304 "TARGET_SSE2"
22305 "cvtpd2pi\t{%1, %0|%0, %1}"
22306 [(set_attr "type" "ssecvt")
22307 (set_attr "mode" "TI")])
22308
22309 (define_insn "cvttpd2pi"
22310 [(set (match_operand:V2SI 0 "register_operand" "=y")
22311 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22312 UNSPEC_FIX))]
22313 "TARGET_SSE2"
22314 "cvttpd2pi\t{%1, %0|%0, %1}"
22315 [(set_attr "type" "ssecvt")
22316 (set_attr "mode" "TI")])
22317
22318 (define_insn "cvtpi2pd"
22319 [(set (match_operand:V2DF 0 "register_operand" "=x")
22320 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22321 "TARGET_SSE2"
22322 "cvtpi2pd\t{%1, %0|%0, %1}"
22323 [(set_attr "type" "ssecvt")
22324 (set_attr "mode" "TI")])
22325
22326 ;; Conversions between SI and DF
22327
22328 (define_insn "cvtsd2si"
22329 [(set (match_operand:SI 0 "register_operand" "=r,r")
22330 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22331 (parallel [(const_int 0)]))))]
22332 "TARGET_SSE2"
22333 "cvtsd2si\t{%1, %0|%0, %1}"
22334 [(set_attr "type" "sseicvt")
22335 (set_attr "athlon_decode" "double,vector")
22336 (set_attr "mode" "SI")])
22337
22338 (define_insn "cvtsd2siq"
22339 [(set (match_operand:DI 0 "register_operand" "=r,r")
22340 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22341 (parallel [(const_int 0)]))))]
22342 "TARGET_SSE2 && TARGET_64BIT"
22343 "cvtsd2siq\t{%1, %0|%0, %1}"
22344 [(set_attr "type" "sseicvt")
22345 (set_attr "athlon_decode" "double,vector")
22346 (set_attr "mode" "DI")])
22347
22348 (define_insn "cvttsd2si"
22349 [(set (match_operand:SI 0 "register_operand" "=r,r")
22350 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22351 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22352 "TARGET_SSE2"
22353 "cvttsd2si\t{%1, %0|%0, %1}"
22354 [(set_attr "type" "sseicvt")
22355 (set_attr "mode" "SI")
22356 (set_attr "athlon_decode" "double,vector")])
22357
22358 (define_insn "cvttsd2siq"
22359 [(set (match_operand:DI 0 "register_operand" "=r,r")
22360 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22361 (parallel [(const_int 0)]))] UNSPEC_FIX))]
22362 "TARGET_SSE2 && TARGET_64BIT"
22363 "cvttsd2siq\t{%1, %0|%0, %1}"
22364 [(set_attr "type" "sseicvt")
22365 (set_attr "mode" "DI")
22366 (set_attr "athlon_decode" "double,vector")])
22367
22368 (define_insn "cvtsi2sd"
22369 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22370 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22371 (vec_duplicate:V2DF
22372 (float:DF
22373 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22374 (const_int 2)))]
22375 "TARGET_SSE2"
22376 "cvtsi2sd\t{%2, %0|%0, %2}"
22377 [(set_attr "type" "sseicvt")
22378 (set_attr "mode" "DF")
22379 (set_attr "athlon_decode" "double,direct")])
22380
22381 (define_insn "cvtsi2sdq"
22382 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22383 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22384 (vec_duplicate:V2DF
22385 (float:DF
22386 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22387 (const_int 2)))]
22388 "TARGET_SSE2 && TARGET_64BIT"
22389 "cvtsi2sdq\t{%2, %0|%0, %2}"
22390 [(set_attr "type" "sseicvt")
22391 (set_attr "mode" "DF")
22392 (set_attr "athlon_decode" "double,direct")])
22393
22394 ;; Conversions between SF and DF
22395
22396 (define_insn "cvtsd2ss"
22397 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22398 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22399 (vec_duplicate:V4SF
22400 (float_truncate:V2SF
22401 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22402 (const_int 14)))]
22403 "TARGET_SSE2"
22404 "cvtsd2ss\t{%2, %0|%0, %2}"
22405 [(set_attr "type" "ssecvt")
22406 (set_attr "athlon_decode" "vector,double")
22407 (set_attr "mode" "SF")])
22408
22409 (define_insn "cvtss2sd"
22410 [(set (match_operand:V2DF 0 "register_operand" "=x")
22411 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22412 (float_extend:V2DF
22413 (vec_select:V2SF
22414 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22415 (parallel [(const_int 0)
22416 (const_int 1)])))
22417 (const_int 2)))]
22418 "TARGET_SSE2"
22419 "cvtss2sd\t{%2, %0|%0, %2}"
22420 [(set_attr "type" "ssecvt")
22421 (set_attr "mode" "DF")])
22422
22423 (define_insn "cvtpd2ps"
22424 [(set (match_operand:V4SF 0 "register_operand" "=x")
22425 (subreg:V4SF
22426 (vec_concat:V4SI
22427 (subreg:V2SI (float_truncate:V2SF
22428 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22429 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22430 "TARGET_SSE2"
22431 "cvtpd2ps\t{%1, %0|%0, %1}"
22432 [(set_attr "type" "ssecvt")
22433 (set_attr "mode" "V4SF")])
22434
22435 (define_insn "cvtps2pd"
22436 [(set (match_operand:V2DF 0 "register_operand" "=x")
22437 (float_extend:V2DF
22438 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22439 (parallel [(const_int 0)
22440 (const_int 1)]))))]
22441 "TARGET_SSE2"
22442 "cvtps2pd\t{%1, %0|%0, %1}"
22443 [(set_attr "type" "ssecvt")
22444 (set_attr "mode" "V2DF")])
22445
22446 ;; SSE2 variants of MMX insns
22447
22448 ;; MMX arithmetic
22449
22450 (define_insn "addv16qi3"
22451 [(set (match_operand:V16QI 0 "register_operand" "=x")
22452 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22453 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22454 "TARGET_SSE2"
22455 "paddb\t{%2, %0|%0, %2}"
22456 [(set_attr "type" "sseiadd")
22457 (set_attr "mode" "TI")])
22458
22459 (define_insn "addv8hi3"
22460 [(set (match_operand:V8HI 0 "register_operand" "=x")
22461 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22462 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22463 "TARGET_SSE2"
22464 "paddw\t{%2, %0|%0, %2}"
22465 [(set_attr "type" "sseiadd")
22466 (set_attr "mode" "TI")])
22467
22468 (define_insn "addv4si3"
22469 [(set (match_operand:V4SI 0 "register_operand" "=x")
22470 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22471 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22472 "TARGET_SSE2"
22473 "paddd\t{%2, %0|%0, %2}"
22474 [(set_attr "type" "sseiadd")
22475 (set_attr "mode" "TI")])
22476
22477 (define_insn "addv2di3"
22478 [(set (match_operand:V2DI 0 "register_operand" "=x")
22479 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22480 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22481 "TARGET_SSE2"
22482 "paddq\t{%2, %0|%0, %2}"
22483 [(set_attr "type" "sseiadd")
22484 (set_attr "mode" "TI")])
22485
22486 (define_insn "ssaddv16qi3"
22487 [(set (match_operand:V16QI 0 "register_operand" "=x")
22488 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22489 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22490 "TARGET_SSE2"
22491 "paddsb\t{%2, %0|%0, %2}"
22492 [(set_attr "type" "sseiadd")
22493 (set_attr "mode" "TI")])
22494
22495 (define_insn "ssaddv8hi3"
22496 [(set (match_operand:V8HI 0 "register_operand" "=x")
22497 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22498 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22499 "TARGET_SSE2"
22500 "paddsw\t{%2, %0|%0, %2}"
22501 [(set_attr "type" "sseiadd")
22502 (set_attr "mode" "TI")])
22503
22504 (define_insn "usaddv16qi3"
22505 [(set (match_operand:V16QI 0 "register_operand" "=x")
22506 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22507 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22508 "TARGET_SSE2"
22509 "paddusb\t{%2, %0|%0, %2}"
22510 [(set_attr "type" "sseiadd")
22511 (set_attr "mode" "TI")])
22512
22513 (define_insn "usaddv8hi3"
22514 [(set (match_operand:V8HI 0 "register_operand" "=x")
22515 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22516 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22517 "TARGET_SSE2"
22518 "paddusw\t{%2, %0|%0, %2}"
22519 [(set_attr "type" "sseiadd")
22520 (set_attr "mode" "TI")])
22521
22522 (define_insn "subv16qi3"
22523 [(set (match_operand:V16QI 0 "register_operand" "=x")
22524 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22525 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22526 "TARGET_SSE2"
22527 "psubb\t{%2, %0|%0, %2}"
22528 [(set_attr "type" "sseiadd")
22529 (set_attr "mode" "TI")])
22530
22531 (define_insn "subv8hi3"
22532 [(set (match_operand:V8HI 0 "register_operand" "=x")
22533 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22534 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22535 "TARGET_SSE2"
22536 "psubw\t{%2, %0|%0, %2}"
22537 [(set_attr "type" "sseiadd")
22538 (set_attr "mode" "TI")])
22539
22540 (define_insn "subv4si3"
22541 [(set (match_operand:V4SI 0 "register_operand" "=x")
22542 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22543 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22544 "TARGET_SSE2"
22545 "psubd\t{%2, %0|%0, %2}"
22546 [(set_attr "type" "sseiadd")
22547 (set_attr "mode" "TI")])
22548
22549 (define_insn "subv2di3"
22550 [(set (match_operand:V2DI 0 "register_operand" "=x")
22551 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22552 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22553 "TARGET_SSE2"
22554 "psubq\t{%2, %0|%0, %2}"
22555 [(set_attr "type" "sseiadd")
22556 (set_attr "mode" "TI")])
22557
22558 (define_insn "sssubv16qi3"
22559 [(set (match_operand:V16QI 0 "register_operand" "=x")
22560 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22561 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22562 "TARGET_SSE2"
22563 "psubsb\t{%2, %0|%0, %2}"
22564 [(set_attr "type" "sseiadd")
22565 (set_attr "mode" "TI")])
22566
22567 (define_insn "sssubv8hi3"
22568 [(set (match_operand:V8HI 0 "register_operand" "=x")
22569 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22570 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22571 "TARGET_SSE2"
22572 "psubsw\t{%2, %0|%0, %2}"
22573 [(set_attr "type" "sseiadd")
22574 (set_attr "mode" "TI")])
22575
22576 (define_insn "ussubv16qi3"
22577 [(set (match_operand:V16QI 0 "register_operand" "=x")
22578 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22579 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22580 "TARGET_SSE2"
22581 "psubusb\t{%2, %0|%0, %2}"
22582 [(set_attr "type" "sseiadd")
22583 (set_attr "mode" "TI")])
22584
22585 (define_insn "ussubv8hi3"
22586 [(set (match_operand:V8HI 0 "register_operand" "=x")
22587 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22588 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22589 "TARGET_SSE2"
22590 "psubusw\t{%2, %0|%0, %2}"
22591 [(set_attr "type" "sseiadd")
22592 (set_attr "mode" "TI")])
22593
22594 (define_insn "mulv8hi3"
22595 [(set (match_operand:V8HI 0 "register_operand" "=x")
22596 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22597 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22598 "TARGET_SSE2"
22599 "pmullw\t{%2, %0|%0, %2}"
22600 [(set_attr "type" "sseimul")
22601 (set_attr "mode" "TI")])
22602
22603 (define_insn "smulv8hi3_highpart"
22604 [(set (match_operand:V8HI 0 "register_operand" "=x")
22605 (truncate:V8HI
22606 (lshiftrt:V8SI
22607 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22608 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22609 (const_int 16))))]
22610 "TARGET_SSE2"
22611 "pmulhw\t{%2, %0|%0, %2}"
22612 [(set_attr "type" "sseimul")
22613 (set_attr "mode" "TI")])
22614
22615 (define_insn "umulv8hi3_highpart"
22616 [(set (match_operand:V8HI 0 "register_operand" "=x")
22617 (truncate:V8HI
22618 (lshiftrt:V8SI
22619 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22620 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22621 (const_int 16))))]
22622 "TARGET_SSE2"
22623 "pmulhuw\t{%2, %0|%0, %2}"
22624 [(set_attr "type" "sseimul")
22625 (set_attr "mode" "TI")])
22626
22627 (define_insn "sse2_umulsidi3"
22628 [(set (match_operand:DI 0 "register_operand" "=y")
22629 (mult:DI (zero_extend:DI (vec_select:SI
22630 (match_operand:V2SI 1 "register_operand" "0")
22631 (parallel [(const_int 0)])))
22632 (zero_extend:DI (vec_select:SI
22633 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22634 (parallel [(const_int 0)])))))]
22635 "TARGET_SSE2"
22636 "pmuludq\t{%2, %0|%0, %2}"
22637 [(set_attr "type" "sseimul")
22638 (set_attr "mode" "TI")])
22639
22640 (define_insn "sse2_umulv2siv2di3"
22641 [(set (match_operand:V2DI 0 "register_operand" "=x")
22642 (mult:V2DI (zero_extend:V2DI
22643 (vec_select:V2SI
22644 (match_operand:V4SI 1 "register_operand" "0")
22645 (parallel [(const_int 0) (const_int 2)])))
22646 (zero_extend:V2DI
22647 (vec_select:V2SI
22648 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22649 (parallel [(const_int 0) (const_int 2)])))))]
22650 "TARGET_SSE2"
22651 "pmuludq\t{%2, %0|%0, %2}"
22652 [(set_attr "type" "sseimul")
22653 (set_attr "mode" "TI")])
22654
22655 (define_insn "sse2_pmaddwd"
22656 [(set (match_operand:V4SI 0 "register_operand" "=x")
22657 (plus:V4SI
22658 (mult:V4SI
22659 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22660 (parallel [(const_int 0)
22661 (const_int 2)
22662 (const_int 4)
22663 (const_int 6)])))
22664 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22665 (parallel [(const_int 0)
22666 (const_int 2)
22667 (const_int 4)
22668 (const_int 6)]))))
22669 (mult:V4SI
22670 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22671 (parallel [(const_int 1)
22672 (const_int 3)
22673 (const_int 5)
22674 (const_int 7)])))
22675 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22676 (parallel [(const_int 1)
22677 (const_int 3)
22678 (const_int 5)
22679 (const_int 7)]))))))]
22680 "TARGET_SSE2"
22681 "pmaddwd\t{%2, %0|%0, %2}"
22682 [(set_attr "type" "sseiadd")
22683 (set_attr "mode" "TI")])
22684
22685 ;; Same as pxor, but don't show input operands so that we don't think
22686 ;; they are live.
22687 (define_insn "sse2_clrti"
22688 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22689 "TARGET_SSE2"
22690 {
22691 if (get_attr_mode (insn) == MODE_TI)
22692 return "pxor\t%0, %0";
22693 else
22694 return "xorps\t%0, %0";
22695 }
22696 [(set_attr "type" "ssemov")
22697 (set_attr "memory" "none")
22698 (set (attr "mode")
22699 (if_then_else
22700 (ne (symbol_ref "optimize_size")
22701 (const_int 0))
22702 (const_string "V4SF")
22703 (const_string "TI")))])
22704
22705 ;; MMX unsigned averages/sum of absolute differences
22706
22707 (define_insn "sse2_uavgv16qi3"
22708 [(set (match_operand:V16QI 0 "register_operand" "=x")
22709 (ashiftrt:V16QI
22710 (plus:V16QI (plus:V16QI
22711 (match_operand:V16QI 1 "register_operand" "0")
22712 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22713 (const_vector:V16QI [(const_int 1) (const_int 1)
22714 (const_int 1) (const_int 1)
22715 (const_int 1) (const_int 1)
22716 (const_int 1) (const_int 1)
22717 (const_int 1) (const_int 1)
22718 (const_int 1) (const_int 1)
22719 (const_int 1) (const_int 1)
22720 (const_int 1) (const_int 1)]))
22721 (const_int 1)))]
22722 "TARGET_SSE2"
22723 "pavgb\t{%2, %0|%0, %2}"
22724 [(set_attr "type" "sseiadd")
22725 (set_attr "mode" "TI")])
22726
22727 (define_insn "sse2_uavgv8hi3"
22728 [(set (match_operand:V8HI 0 "register_operand" "=x")
22729 (ashiftrt:V8HI
22730 (plus:V8HI (plus:V8HI
22731 (match_operand:V8HI 1 "register_operand" "0")
22732 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22733 (const_vector:V8HI [(const_int 1) (const_int 1)
22734 (const_int 1) (const_int 1)
22735 (const_int 1) (const_int 1)
22736 (const_int 1) (const_int 1)]))
22737 (const_int 1)))]
22738 "TARGET_SSE2"
22739 "pavgw\t{%2, %0|%0, %2}"
22740 [(set_attr "type" "sseiadd")
22741 (set_attr "mode" "TI")])
22742
22743 ;; @@@ this isn't the right representation.
22744 (define_insn "sse2_psadbw"
22745 [(set (match_operand:V2DI 0 "register_operand" "=x")
22746 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22747 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22748 UNSPEC_PSADBW))]
22749 "TARGET_SSE2"
22750 "psadbw\t{%2, %0|%0, %2}"
22751 [(set_attr "type" "sseiadd")
22752 (set_attr "mode" "TI")])
22753
22754
22755 ;; MMX insert/extract/shuffle
22756
22757 (define_insn "sse2_pinsrw"
22758 [(set (match_operand:V8HI 0 "register_operand" "=x")
22759 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22760 (vec_duplicate:V8HI
22761 (truncate:HI
22762 (match_operand:SI 2 "nonimmediate_operand" "rm")))
22763 (match_operand:SI 3 "immediate_operand" "i")))]
22764 "TARGET_SSE2"
22765 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22766 [(set_attr "type" "ssecvt")
22767 (set_attr "mode" "TI")])
22768
22769 (define_insn "sse2_pextrw"
22770 [(set (match_operand:SI 0 "register_operand" "=r")
22771 (zero_extend:SI
22772 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22773 (parallel
22774 [(match_operand:SI 2 "immediate_operand" "i")]))))]
22775 "TARGET_SSE2"
22776 "pextrw\t{%2, %1, %0|%0, %1, %2}"
22777 [(set_attr "type" "ssecvt")
22778 (set_attr "mode" "TI")])
22779
22780 (define_insn "sse2_pshufd"
22781 [(set (match_operand:V4SI 0 "register_operand" "=x")
22782 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22783 (match_operand:SI 2 "immediate_operand" "i")]
22784 UNSPEC_SHUFFLE))]
22785 "TARGET_SSE2"
22786 "pshufd\t{%2, %1, %0|%0, %1, %2}"
22787 [(set_attr "type" "ssecvt")
22788 (set_attr "mode" "TI")])
22789
22790 (define_insn "sse2_pshuflw"
22791 [(set (match_operand:V8HI 0 "register_operand" "=x")
22792 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22793 (match_operand:SI 2 "immediate_operand" "i")]
22794 UNSPEC_PSHUFLW))]
22795 "TARGET_SSE2"
22796 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22797 [(set_attr "type" "ssecvt")
22798 (set_attr "mode" "TI")])
22799
22800 (define_insn "sse2_pshufhw"
22801 [(set (match_operand:V8HI 0 "register_operand" "=x")
22802 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22803 (match_operand:SI 2 "immediate_operand" "i")]
22804 UNSPEC_PSHUFHW))]
22805 "TARGET_SSE2"
22806 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22807 [(set_attr "type" "ssecvt")
22808 (set_attr "mode" "TI")])
22809
22810 ;; MMX mask-generating comparisons
22811
22812 (define_insn "eqv16qi3"
22813 [(set (match_operand:V16QI 0 "register_operand" "=x")
22814 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22815 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22816 "TARGET_SSE2"
22817 "pcmpeqb\t{%2, %0|%0, %2}"
22818 [(set_attr "type" "ssecmp")
22819 (set_attr "mode" "TI")])
22820
22821 (define_insn "eqv8hi3"
22822 [(set (match_operand:V8HI 0 "register_operand" "=x")
22823 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22824 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22825 "TARGET_SSE2"
22826 "pcmpeqw\t{%2, %0|%0, %2}"
22827 [(set_attr "type" "ssecmp")
22828 (set_attr "mode" "TI")])
22829
22830 (define_insn "eqv4si3"
22831 [(set (match_operand:V4SI 0 "register_operand" "=x")
22832 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22833 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22834 "TARGET_SSE2"
22835 "pcmpeqd\t{%2, %0|%0, %2}"
22836 [(set_attr "type" "ssecmp")
22837 (set_attr "mode" "TI")])
22838
22839 (define_insn "gtv16qi3"
22840 [(set (match_operand:V16QI 0 "register_operand" "=x")
22841 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22842 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22843 "TARGET_SSE2"
22844 "pcmpgtb\t{%2, %0|%0, %2}"
22845 [(set_attr "type" "ssecmp")
22846 (set_attr "mode" "TI")])
22847
22848 (define_insn "gtv8hi3"
22849 [(set (match_operand:V8HI 0 "register_operand" "=x")
22850 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22851 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22852 "TARGET_SSE2"
22853 "pcmpgtw\t{%2, %0|%0, %2}"
22854 [(set_attr "type" "ssecmp")
22855 (set_attr "mode" "TI")])
22856
22857 (define_insn "gtv4si3"
22858 [(set (match_operand:V4SI 0 "register_operand" "=x")
22859 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22860 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22861 "TARGET_SSE2"
22862 "pcmpgtd\t{%2, %0|%0, %2}"
22863 [(set_attr "type" "ssecmp")
22864 (set_attr "mode" "TI")])
22865
22866
22867 ;; MMX max/min insns
22868
22869 (define_insn "umaxv16qi3"
22870 [(set (match_operand:V16QI 0 "register_operand" "=x")
22871 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22872 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22873 "TARGET_SSE2"
22874 "pmaxub\t{%2, %0|%0, %2}"
22875 [(set_attr "type" "sseiadd")
22876 (set_attr "mode" "TI")])
22877
22878 (define_insn "smaxv8hi3"
22879 [(set (match_operand:V8HI 0 "register_operand" "=x")
22880 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22881 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22882 "TARGET_SSE2"
22883 "pmaxsw\t{%2, %0|%0, %2}"
22884 [(set_attr "type" "sseiadd")
22885 (set_attr "mode" "TI")])
22886
22887 (define_insn "uminv16qi3"
22888 [(set (match_operand:V16QI 0 "register_operand" "=x")
22889 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22890 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22891 "TARGET_SSE2"
22892 "pminub\t{%2, %0|%0, %2}"
22893 [(set_attr "type" "sseiadd")
22894 (set_attr "mode" "TI")])
22895
22896 (define_insn "sminv8hi3"
22897 [(set (match_operand:V8HI 0 "register_operand" "=x")
22898 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22899 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22900 "TARGET_SSE2"
22901 "pminsw\t{%2, %0|%0, %2}"
22902 [(set_attr "type" "sseiadd")
22903 (set_attr "mode" "TI")])
22904
22905
22906 ;; MMX shifts
22907
22908 (define_insn "ashrv8hi3"
22909 [(set (match_operand:V8HI 0 "register_operand" "=x")
22910 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22911 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22912 "TARGET_SSE2"
22913 "psraw\t{%2, %0|%0, %2}"
22914 [(set_attr "type" "sseishft")
22915 (set_attr "mode" "TI")])
22916
22917 (define_insn "ashrv4si3"
22918 [(set (match_operand:V4SI 0 "register_operand" "=x")
22919 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22920 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22921 "TARGET_SSE2"
22922 "psrad\t{%2, %0|%0, %2}"
22923 [(set_attr "type" "sseishft")
22924 (set_attr "mode" "TI")])
22925
22926 (define_insn "lshrv8hi3"
22927 [(set (match_operand:V8HI 0 "register_operand" "=x")
22928 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22929 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22930 "TARGET_SSE2"
22931 "psrlw\t{%2, %0|%0, %2}"
22932 [(set_attr "type" "sseishft")
22933 (set_attr "mode" "TI")])
22934
22935 (define_insn "lshrv4si3"
22936 [(set (match_operand:V4SI 0 "register_operand" "=x")
22937 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22938 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22939 "TARGET_SSE2"
22940 "psrld\t{%2, %0|%0, %2}"
22941 [(set_attr "type" "sseishft")
22942 (set_attr "mode" "TI")])
22943
22944 (define_insn "lshrv2di3"
22945 [(set (match_operand:V2DI 0 "register_operand" "=x")
22946 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22947 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22948 "TARGET_SSE2"
22949 "psrlq\t{%2, %0|%0, %2}"
22950 [(set_attr "type" "sseishft")
22951 (set_attr "mode" "TI")])
22952
22953 (define_insn "ashlv8hi3"
22954 [(set (match_operand:V8HI 0 "register_operand" "=x")
22955 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22956 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22957 "TARGET_SSE2"
22958 "psllw\t{%2, %0|%0, %2}"
22959 [(set_attr "type" "sseishft")
22960 (set_attr "mode" "TI")])
22961
22962 (define_insn "ashlv4si3"
22963 [(set (match_operand:V4SI 0 "register_operand" "=x")
22964 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22965 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22966 "TARGET_SSE2"
22967 "pslld\t{%2, %0|%0, %2}"
22968 [(set_attr "type" "sseishft")
22969 (set_attr "mode" "TI")])
22970
22971 (define_insn "ashlv2di3"
22972 [(set (match_operand:V2DI 0 "register_operand" "=x")
22973 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22974 (match_operand:TI 2 "nonmemory_operand" "xi")))]
22975 "TARGET_SSE2"
22976 "psllq\t{%2, %0|%0, %2}"
22977 [(set_attr "type" "sseishft")
22978 (set_attr "mode" "TI")])
22979
22980 (define_insn "ashrv8hi3_ti"
22981 [(set (match_operand:V8HI 0 "register_operand" "=x")
22982 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22983 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22984 "TARGET_SSE2"
22985 "psraw\t{%2, %0|%0, %2}"
22986 [(set_attr "type" "sseishft")
22987 (set_attr "mode" "TI")])
22988
22989 (define_insn "ashrv4si3_ti"
22990 [(set (match_operand:V4SI 0 "register_operand" "=x")
22991 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22992 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22993 "TARGET_SSE2"
22994 "psrad\t{%2, %0|%0, %2}"
22995 [(set_attr "type" "sseishft")
22996 (set_attr "mode" "TI")])
22997
22998 (define_insn "lshrv8hi3_ti"
22999 [(set (match_operand:V8HI 0 "register_operand" "=x")
23000 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23001 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23002 "TARGET_SSE2"
23003 "psrlw\t{%2, %0|%0, %2}"
23004 [(set_attr "type" "sseishft")
23005 (set_attr "mode" "TI")])
23006
23007 (define_insn "lshrv4si3_ti"
23008 [(set (match_operand:V4SI 0 "register_operand" "=x")
23009 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23010 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23011 "TARGET_SSE2"
23012 "psrld\t{%2, %0|%0, %2}"
23013 [(set_attr "type" "sseishft")
23014 (set_attr "mode" "TI")])
23015
23016 (define_insn "lshrv2di3_ti"
23017 [(set (match_operand:V2DI 0 "register_operand" "=x")
23018 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23019 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23020 "TARGET_SSE2"
23021 "psrlq\t{%2, %0|%0, %2}"
23022 [(set_attr "type" "sseishft")
23023 (set_attr "mode" "TI")])
23024
23025 (define_insn "ashlv8hi3_ti"
23026 [(set (match_operand:V8HI 0 "register_operand" "=x")
23027 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23028 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23029 "TARGET_SSE2"
23030 "psllw\t{%2, %0|%0, %2}"
23031 [(set_attr "type" "sseishft")
23032 (set_attr "mode" "TI")])
23033
23034 (define_insn "ashlv4si3_ti"
23035 [(set (match_operand:V4SI 0 "register_operand" "=x")
23036 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23037 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23038 "TARGET_SSE2"
23039 "pslld\t{%2, %0|%0, %2}"
23040 [(set_attr "type" "sseishft")
23041 (set_attr "mode" "TI")])
23042
23043 (define_insn "ashlv2di3_ti"
23044 [(set (match_operand:V2DI 0 "register_operand" "=x")
23045 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23046 (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23047 "TARGET_SSE2"
23048 "psllq\t{%2, %0|%0, %2}"
23049 [(set_attr "type" "sseishft")
23050 (set_attr "mode" "TI")])
23051
23052 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23053 ;; we wouldn't need here it since we never generate TImode arithmetic.
23054
23055 ;; There has to be some kind of prize for the weirdest new instruction...
23056 (define_insn "sse2_ashlti3"
23057 [(set (match_operand:TI 0 "register_operand" "=x")
23058 (unspec:TI
23059 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23060 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23061 (const_int 8)))] UNSPEC_NOP))]
23062 "TARGET_SSE2"
23063 "pslldq\t{%2, %0|%0, %2}"
23064 [(set_attr "type" "sseishft")
23065 (set_attr "mode" "TI")])
23066
23067 (define_insn "sse2_lshrti3"
23068 [(set (match_operand:TI 0 "register_operand" "=x")
23069 (unspec:TI
23070 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23071 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23072 (const_int 8)))] UNSPEC_NOP))]
23073 "TARGET_SSE2"
23074 "psrldq\t{%2, %0|%0, %2}"
23075 [(set_attr "type" "sseishft")
23076 (set_attr "mode" "TI")])
23077
23078 ;; SSE unpack
23079
23080 (define_insn "sse2_unpckhpd"
23081 [(set (match_operand:V2DF 0 "register_operand" "=x")
23082 (vec_concat:V2DF
23083 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23084 (parallel [(const_int 1)]))
23085 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23086 (parallel [(const_int 0)]))))]
23087 "TARGET_SSE2"
23088 "unpckhpd\t{%2, %0|%0, %2}"
23089 [(set_attr "type" "ssecvt")
23090 (set_attr "mode" "TI")])
23091
23092 (define_insn "sse2_unpcklpd"
23093 [(set (match_operand:V2DF 0 "register_operand" "=x")
23094 (vec_concat:V2DF
23095 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23096 (parallel [(const_int 0)]))
23097 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23098 (parallel [(const_int 1)]))))]
23099 "TARGET_SSE2"
23100 "unpcklpd\t{%2, %0|%0, %2}"
23101 [(set_attr "type" "ssecvt")
23102 (set_attr "mode" "TI")])
23103
23104 ;; MMX pack/unpack insns.
23105
23106 (define_insn "sse2_packsswb"
23107 [(set (match_operand:V16QI 0 "register_operand" "=x")
23108 (vec_concat:V16QI
23109 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23110 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23111 "TARGET_SSE2"
23112 "packsswb\t{%2, %0|%0, %2}"
23113 [(set_attr "type" "ssecvt")
23114 (set_attr "mode" "TI")])
23115
23116 (define_insn "sse2_packssdw"
23117 [(set (match_operand:V8HI 0 "register_operand" "=x")
23118 (vec_concat:V8HI
23119 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23120 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23121 "TARGET_SSE2"
23122 "packssdw\t{%2, %0|%0, %2}"
23123 [(set_attr "type" "ssecvt")
23124 (set_attr "mode" "TI")])
23125
23126 (define_insn "sse2_packuswb"
23127 [(set (match_operand:V16QI 0 "register_operand" "=x")
23128 (vec_concat:V16QI
23129 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23130 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23131 "TARGET_SSE2"
23132 "packuswb\t{%2, %0|%0, %2}"
23133 [(set_attr "type" "ssecvt")
23134 (set_attr "mode" "TI")])
23135
23136 (define_insn "sse2_punpckhbw"
23137 [(set (match_operand:V16QI 0 "register_operand" "=x")
23138 (vec_merge:V16QI
23139 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23140 (parallel [(const_int 8) (const_int 0)
23141 (const_int 9) (const_int 1)
23142 (const_int 10) (const_int 2)
23143 (const_int 11) (const_int 3)
23144 (const_int 12) (const_int 4)
23145 (const_int 13) (const_int 5)
23146 (const_int 14) (const_int 6)
23147 (const_int 15) (const_int 7)]))
23148 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23149 (parallel [(const_int 0) (const_int 8)
23150 (const_int 1) (const_int 9)
23151 (const_int 2) (const_int 10)
23152 (const_int 3) (const_int 11)
23153 (const_int 4) (const_int 12)
23154 (const_int 5) (const_int 13)
23155 (const_int 6) (const_int 14)
23156 (const_int 7) (const_int 15)]))
23157 (const_int 21845)))]
23158 "TARGET_SSE2"
23159 "punpckhbw\t{%2, %0|%0, %2}"
23160 [(set_attr "type" "ssecvt")
23161 (set_attr "mode" "TI")])
23162
23163 (define_insn "sse2_punpckhwd"
23164 [(set (match_operand:V8HI 0 "register_operand" "=x")
23165 (vec_merge:V8HI
23166 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23167 (parallel [(const_int 4) (const_int 0)
23168 (const_int 5) (const_int 1)
23169 (const_int 6) (const_int 2)
23170 (const_int 7) (const_int 3)]))
23171 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23172 (parallel [(const_int 0) (const_int 4)
23173 (const_int 1) (const_int 5)
23174 (const_int 2) (const_int 6)
23175 (const_int 3) (const_int 7)]))
23176 (const_int 85)))]
23177 "TARGET_SSE2"
23178 "punpckhwd\t{%2, %0|%0, %2}"
23179 [(set_attr "type" "ssecvt")
23180 (set_attr "mode" "TI")])
23181
23182 (define_insn "sse2_punpckhdq"
23183 [(set (match_operand:V4SI 0 "register_operand" "=x")
23184 (vec_merge:V4SI
23185 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23186 (parallel [(const_int 2) (const_int 0)
23187 (const_int 3) (const_int 1)]))
23188 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23189 (parallel [(const_int 0) (const_int 2)
23190 (const_int 1) (const_int 3)]))
23191 (const_int 5)))]
23192 "TARGET_SSE2"
23193 "punpckhdq\t{%2, %0|%0, %2}"
23194 [(set_attr "type" "ssecvt")
23195 (set_attr "mode" "TI")])
23196
23197 (define_insn "sse2_punpcklbw"
23198 [(set (match_operand:V16QI 0 "register_operand" "=x")
23199 (vec_merge:V16QI
23200 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23201 (parallel [(const_int 0) (const_int 8)
23202 (const_int 1) (const_int 9)
23203 (const_int 2) (const_int 10)
23204 (const_int 3) (const_int 11)
23205 (const_int 4) (const_int 12)
23206 (const_int 5) (const_int 13)
23207 (const_int 6) (const_int 14)
23208 (const_int 7) (const_int 15)]))
23209 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23210 (parallel [(const_int 8) (const_int 0)
23211 (const_int 9) (const_int 1)
23212 (const_int 10) (const_int 2)
23213 (const_int 11) (const_int 3)
23214 (const_int 12) (const_int 4)
23215 (const_int 13) (const_int 5)
23216 (const_int 14) (const_int 6)
23217 (const_int 15) (const_int 7)]))
23218 (const_int 21845)))]
23219 "TARGET_SSE2"
23220 "punpcklbw\t{%2, %0|%0, %2}"
23221 [(set_attr "type" "ssecvt")
23222 (set_attr "mode" "TI")])
23223
23224 (define_insn "sse2_punpcklwd"
23225 [(set (match_operand:V8HI 0 "register_operand" "=x")
23226 (vec_merge:V8HI
23227 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23228 (parallel [(const_int 0) (const_int 4)
23229 (const_int 1) (const_int 5)
23230 (const_int 2) (const_int 6)
23231 (const_int 3) (const_int 7)]))
23232 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23233 (parallel [(const_int 4) (const_int 0)
23234 (const_int 5) (const_int 1)
23235 (const_int 6) (const_int 2)
23236 (const_int 7) (const_int 3)]))
23237 (const_int 85)))]
23238 "TARGET_SSE2"
23239 "punpcklwd\t{%2, %0|%0, %2}"
23240 [(set_attr "type" "ssecvt")
23241 (set_attr "mode" "TI")])
23242
23243 (define_insn "sse2_punpckldq"
23244 [(set (match_operand:V4SI 0 "register_operand" "=x")
23245 (vec_merge:V4SI
23246 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23247 (parallel [(const_int 0) (const_int 2)
23248 (const_int 1) (const_int 3)]))
23249 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23250 (parallel [(const_int 2) (const_int 0)
23251 (const_int 3) (const_int 1)]))
23252 (const_int 5)))]
23253 "TARGET_SSE2"
23254 "punpckldq\t{%2, %0|%0, %2}"
23255 [(set_attr "type" "ssecvt")
23256 (set_attr "mode" "TI")])
23257
23258 (define_insn "sse2_punpcklqdq"
23259 [(set (match_operand:V2DI 0 "register_operand" "=x")
23260 (vec_merge:V2DI
23261 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23262 (parallel [(const_int 1)
23263 (const_int 0)]))
23264 (match_operand:V2DI 1 "register_operand" "0")
23265 (const_int 1)))]
23266 "TARGET_SSE2"
23267 "punpcklqdq\t{%2, %0|%0, %2}"
23268 [(set_attr "type" "ssecvt")
23269 (set_attr "mode" "TI")])
23270
23271 (define_insn "sse2_punpckhqdq"
23272 [(set (match_operand:V2DI 0 "register_operand" "=x")
23273 (vec_merge:V2DI
23274 (match_operand:V2DI 1 "register_operand" "0")
23275 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23276 (parallel [(const_int 1)
23277 (const_int 0)]))
23278 (const_int 1)))]
23279 "TARGET_SSE2"
23280 "punpckhqdq\t{%2, %0|%0, %2}"
23281 [(set_attr "type" "ssecvt")
23282 (set_attr "mode" "TI")])
23283
23284 ;; SSE2 moves
23285
23286 (define_insn "sse2_movapd"
23287 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23288 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23289 UNSPEC_MOVA))]
23290 "TARGET_SSE2
23291 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23292 "movapd\t{%1, %0|%0, %1}"
23293 [(set_attr "type" "ssemov")
23294 (set_attr "mode" "V2DF")])
23295
23296 (define_insn "sse2_movupd"
23297 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23298 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23299 UNSPEC_MOVU))]
23300 "TARGET_SSE2
23301 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23302 "movupd\t{%1, %0|%0, %1}"
23303 [(set_attr "type" "ssecvt")
23304 (set_attr "mode" "V2DF")])
23305
23306 (define_insn "sse2_movdqa"
23307 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23308 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23309 UNSPEC_MOVA))]
23310 "TARGET_SSE2
23311 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23312 "movdqa\t{%1, %0|%0, %1}"
23313 [(set_attr "type" "ssemov")
23314 (set_attr "mode" "TI")])
23315
23316 (define_insn "sse2_movdqu"
23317 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23318 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23319 UNSPEC_MOVU))]
23320 "TARGET_SSE2
23321 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23322 "movdqu\t{%1, %0|%0, %1}"
23323 [(set_attr "type" "ssecvt")
23324 (set_attr "mode" "TI")])
23325
23326 (define_insn "sse2_movdq2q"
23327 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23328 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23329 (parallel [(const_int 0)])))]
23330 "TARGET_SSE2 && !TARGET_64BIT"
23331 "@
23332 movq\t{%1, %0|%0, %1}
23333 movdq2q\t{%1, %0|%0, %1}"
23334 [(set_attr "type" "ssecvt")
23335 (set_attr "mode" "TI")])
23336
23337 (define_insn "sse2_movdq2q_rex64"
23338 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23339 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23340 (parallel [(const_int 0)])))]
23341 "TARGET_SSE2 && TARGET_64BIT"
23342 "@
23343 movq\t{%1, %0|%0, %1}
23344 movdq2q\t{%1, %0|%0, %1}
23345 movd\t{%1, %0|%0, %1}"
23346 [(set_attr "type" "ssecvt")
23347 (set_attr "mode" "TI")])
23348
23349 (define_insn "sse2_movq2dq"
23350 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23351 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23352 (const_int 0)))]
23353 "TARGET_SSE2 && !TARGET_64BIT"
23354 "@
23355 movq\t{%1, %0|%0, %1}
23356 movq2dq\t{%1, %0|%0, %1}"
23357 [(set_attr "type" "ssecvt,ssemov")
23358 (set_attr "mode" "TI")])
23359
23360 (define_insn "sse2_movq2dq_rex64"
23361 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23362 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23363 (const_int 0)))]
23364 "TARGET_SSE2 && TARGET_64BIT"
23365 "@
23366 movq\t{%1, %0|%0, %1}
23367 movq2dq\t{%1, %0|%0, %1}
23368 movd\t{%1, %0|%0, %1}"
23369 [(set_attr "type" "ssecvt,ssemov,ssecvt")
23370 (set_attr "mode" "TI")])
23371
23372 (define_insn "sse2_movq"
23373 [(set (match_operand:V2DI 0 "register_operand" "=x")
23374 (vec_concat:V2DI (vec_select:DI
23375 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23376 (parallel [(const_int 0)]))
23377 (const_int 0)))]
23378 "TARGET_SSE2"
23379 "movq\t{%1, %0|%0, %1}"
23380 [(set_attr "type" "ssemov")
23381 (set_attr "mode" "TI")])
23382
23383 (define_insn "sse2_loadd"
23384 [(set (match_operand:V4SI 0 "register_operand" "=x")
23385 (vec_merge:V4SI
23386 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23387 (const_vector:V4SI [(const_int 0)
23388 (const_int 0)
23389 (const_int 0)
23390 (const_int 0)])
23391 (const_int 1)))]
23392 "TARGET_SSE2"
23393 "movd\t{%1, %0|%0, %1}"
23394 [(set_attr "type" "ssemov")
23395 (set_attr "mode" "TI")])
23396
23397 (define_insn "sse2_stored"
23398 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23399 (vec_select:SI
23400 (match_operand:V4SI 1 "register_operand" "x")
23401 (parallel [(const_int 0)])))]
23402 "TARGET_SSE2"
23403 "movd\t{%1, %0|%0, %1}"
23404 [(set_attr "type" "ssemov")
23405 (set_attr "mode" "TI")])
23406
23407 (define_insn "sse2_movhpd"
23408 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23409 (vec_merge:V2DF
23410 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23411 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23412 (const_int 2)))]
23413 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23414 "movhpd\t{%2, %0|%0, %2}"
23415 [(set_attr "type" "ssecvt")
23416 (set_attr "mode" "V2DF")])
23417
23418 (define_insn "sse2_movlpd"
23419 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23420 (vec_merge:V2DF
23421 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23422 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23423 (const_int 1)))]
23424 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23425 "movlpd\t{%2, %0|%0, %2}"
23426 [(set_attr "type" "ssecvt")
23427 (set_attr "mode" "V2DF")])
23428
23429 (define_expand "sse2_loadsd"
23430 [(match_operand:V2DF 0 "register_operand" "")
23431 (match_operand:DF 1 "memory_operand" "")]
23432 "TARGET_SSE2"
23433 {
23434 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23435 CONST0_RTX (V2DFmode)));
23436 DONE;
23437 })
23438
23439 (define_insn "sse2_loadsd_1"
23440 [(set (match_operand:V2DF 0 "register_operand" "=x")
23441 (vec_merge:V2DF
23442 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23443 (match_operand:V2DF 2 "const0_operand" "X")
23444 (const_int 1)))]
23445 "TARGET_SSE2"
23446 "movsd\t{%1, %0|%0, %1}"
23447 [(set_attr "type" "ssecvt")
23448 (set_attr "mode" "DF")])
23449
23450 (define_insn "sse2_movsd"
23451 [(set (match_operand:V2DF 0 "register_operand" "=x")
23452 (vec_merge:V2DF
23453 (match_operand:V2DF 1 "register_operand" "0")
23454 (match_operand:V2DF 2 "register_operand" "x")
23455 (const_int 1)))]
23456 "TARGET_SSE2"
23457 "movsd\t{%2, %0|%0, %2}"
23458 [(set_attr "type" "ssecvt")
23459 (set_attr "mode" "DF")])
23460
23461 (define_insn "sse2_storesd"
23462 [(set (match_operand:DF 0 "memory_operand" "=m")
23463 (vec_select:DF
23464 (match_operand:V2DF 1 "register_operand" "x")
23465 (parallel [(const_int 0)])))]
23466 "TARGET_SSE2"
23467 "movsd\t{%1, %0|%0, %1}"
23468 [(set_attr "type" "ssecvt")
23469 (set_attr "mode" "DF")])
23470
23471 (define_insn "sse2_shufpd"
23472 [(set (match_operand:V2DF 0 "register_operand" "=x")
23473 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23474 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23475 (match_operand:SI 3 "immediate_operand" "i")]
23476 UNSPEC_SHUFFLE))]
23477 "TARGET_SSE2"
23478 ;; @@@ check operand order for intel/nonintel syntax
23479 "shufpd\t{%3, %2, %0|%0, %2, %3}"
23480 [(set_attr "type" "ssecvt")
23481 (set_attr "mode" "V2DF")])
23482
23483 (define_insn "sse2_clflush"
23484 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23485 UNSPECV_CLFLUSH)]
23486 "TARGET_SSE2"
23487 "clflush %0"
23488 [(set_attr "type" "sse")
23489 (set_attr "memory" "unknown")])
23490
23491 (define_expand "sse2_mfence"
23492 [(set (match_dup 0)
23493 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23494 "TARGET_SSE2"
23495 {
23496 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23497 MEM_VOLATILE_P (operands[0]) = 1;
23498 })
23499
23500 (define_insn "*mfence_insn"
23501 [(set (match_operand:BLK 0 "" "")
23502 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23503 "TARGET_SSE2"
23504 "mfence"
23505 [(set_attr "type" "sse")
23506 (set_attr "memory" "unknown")])
23507
23508 (define_expand "sse2_lfence"
23509 [(set (match_dup 0)
23510 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23511 "TARGET_SSE2"
23512 {
23513 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23514 MEM_VOLATILE_P (operands[0]) = 1;
23515 })
23516
23517 (define_insn "*lfence_insn"
23518 [(set (match_operand:BLK 0 "" "")
23519 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23520 "TARGET_SSE2"
23521 "lfence"
23522 [(set_attr "type" "sse")
23523 (set_attr "memory" "unknown")])
23524
23525 ;; PNI
23526
23527 (define_insn "mwait"
23528 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23529 (match_operand:SI 1 "register_operand" "c")]
23530 UNSPECV_MWAIT)]
23531 "TARGET_PNI"
23532 "mwait\t%0, %1"
23533 [(set_attr "length" "3")])
23534
23535 (define_insn "monitor"
23536 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
23537 (match_operand:SI 1 "register_operand" "c")
23538 (match_operand:SI 2 "register_operand" "d")]
23539 UNSPECV_MONITOR)]
23540 "TARGET_PNI"
23541 "monitor\t%0, %1, %2"
23542 [(set_attr "length" "3")])
23543
23544 ;; PNI arithmetic
23545
23546 (define_insn "addsubv4sf3"
23547 [(set (match_operand:V4SF 0 "register_operand" "=x")
23548 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23549 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23550 UNSPEC_ADDSUB))]
23551 "TARGET_PNI"
23552 "addsubps\t{%2, %0|%0, %2}"
23553 [(set_attr "type" "sseadd")
23554 (set_attr "mode" "V4SF")])
23555
23556 (define_insn "addsubv2df3"
23557 [(set (match_operand:V2DF 0 "register_operand" "=x")
23558 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23559 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23560 UNSPEC_ADDSUB))]
23561 "TARGET_PNI"
23562 "addsubpd\t{%2, %0|%0, %2}"
23563 [(set_attr "type" "sseadd")
23564 (set_attr "mode" "V2DF")])
23565
23566 (define_insn "haddv4sf3"
23567 [(set (match_operand:V4SF 0 "register_operand" "=x")
23568 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23569 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23570 UNSPEC_HADD))]
23571 "TARGET_PNI"
23572 "haddps\t{%2, %0|%0, %2}"
23573 [(set_attr "type" "sseadd")
23574 (set_attr "mode" "V4SF")])
23575
23576 (define_insn "haddv2df3"
23577 [(set (match_operand:V2DF 0 "register_operand" "=x")
23578 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23579 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23580 UNSPEC_HADD))]
23581 "TARGET_PNI"
23582 "haddpd\t{%2, %0|%0, %2}"
23583 [(set_attr "type" "sseadd")
23584 (set_attr "mode" "V2DF")])
23585
23586 (define_insn "hsubv4sf3"
23587 [(set (match_operand:V4SF 0 "register_operand" "=x")
23588 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
23589 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
23590 UNSPEC_HSUB))]
23591 "TARGET_PNI"
23592 "hsubps\t{%2, %0|%0, %2}"
23593 [(set_attr "type" "sseadd")
23594 (set_attr "mode" "V4SF")])
23595
23596 (define_insn "hsubv2df3"
23597 [(set (match_operand:V2DF 0 "register_operand" "=x")
23598 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23599 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
23600 UNSPEC_HSUB))]
23601 "TARGET_PNI"
23602 "hsubpd\t{%2, %0|%0, %2}"
23603 [(set_attr "type" "sseadd")
23604 (set_attr "mode" "V2DF")])
23605
23606 (define_insn "movshdup"
23607 [(set (match_operand:V4SF 0 "register_operand" "=x")
23608 (unspec:V4SF
23609 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
23610 "TARGET_PNI"
23611 "movshdup\t{%1, %0|%0, %1}"
23612 [(set_attr "type" "sse")
23613 (set_attr "mode" "V4SF")])
23614
23615 (define_insn "movsldup"
23616 [(set (match_operand:V4SF 0 "register_operand" "=x")
23617 (unspec:V4SF
23618 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
23619 "TARGET_PNI"
23620 "movsldup\t{%1, %0|%0, %1}"
23621 [(set_attr "type" "sse")
23622 (set_attr "mode" "V4SF")])
23623
23624 (define_insn "lddqu"
23625 [(set (match_operand:V16QI 0 "register_operand" "=x")
23626 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
23627 UNSPEC_LDQQU))]
23628 "TARGET_PNI"
23629 "lddqu\t{%1, %0|%0, %1}"
23630 [(set_attr "type" "ssecvt")
23631 (set_attr "mode" "TI")])
23632
23633 (define_insn "loadddup"
23634 [(set (match_operand:V2DF 0 "register_operand" "=x")
23635 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
23636 "TARGET_PNI"
23637 "movddup\t{%1, %0|%0, %1}"
23638 [(set_attr "type" "ssecvt")
23639 (set_attr "mode" "DF")])
23640
23641 (define_insn "movddup"
23642 [(set (match_operand:V2DF 0 "register_operand" "=x")
23643 (vec_duplicate:V2DF
23644 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
23645 (parallel [(const_int 0)]))))]
23646 "TARGET_PNI"
23647 "movddup\t{%1, %0|%0, %1}"
23648 [(set_attr "type" "ssecvt")
23649 (set_attr "mode" "DF")])