d2afa853da2497cca7085ff07f595750383c9990
[gcc.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;; otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode 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 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62
63 ;; UNSPEC usage:
64
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
67 UNSPEC_GOT
68 UNSPEC_GOTOFF
69 UNSPEC_GOTPCREL
70 UNSPEC_GOTTPOFF
71 UNSPEC_TPOFF
72 UNSPEC_NTPOFF
73 UNSPEC_DTPOFF
74 UNSPEC_GOTNTPOFF
75 UNSPEC_INDNTPOFF
76 UNSPEC_PLTOFF
77 UNSPEC_MACHOPIC_OFFSET
78
79 ;; Prologue support
80 UNSPEC_STACK_ALLOC
81 UNSPEC_SET_GOT
82 UNSPEC_SSE_PROLOGUE_SAVE
83 UNSPEC_REG_SAVE
84 UNSPEC_DEF_CFA
85 UNSPEC_SET_RIP
86 UNSPEC_SET_GOT_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
88 UNSPEC_SSE_PROLOGUE_SAVE_LOW
89
90 ;; TLS support
91 UNSPEC_TP
92 UNSPEC_TLS_GD
93 UNSPEC_TLS_LD_BASE
94 UNSPEC_TLSDESC
95
96 ;; Other random patterns
97 UNSPEC_SCAS
98 UNSPEC_FNSTSW
99 UNSPEC_SAHF
100 UNSPEC_PARITY
101 UNSPEC_FSTCW
102 UNSPEC_ADD_CARRY
103 UNSPEC_FLDCW
104 UNSPEC_REP
105 UNSPEC_LD_MPIC ; load_macho_picbase
106 UNSPEC_TRUNC_NOOP
107
108 ;; For SSE/MMX support:
109 UNSPEC_FIX_NOTRUNC
110 UNSPEC_MASKMOV
111 UNSPEC_MOVMSK
112 UNSPEC_MOVNT
113 UNSPEC_MOVU
114 UNSPEC_RCP
115 UNSPEC_RSQRT
116 UNSPEC_SFENCE
117 UNSPEC_PFRCP
118 UNSPEC_PFRCPIT1
119 UNSPEC_PFRCPIT2
120 UNSPEC_PFRSQRT
121 UNSPEC_PFRSQIT1
122 UNSPEC_MFENCE
123 UNSPEC_LFENCE
124 UNSPEC_PSADBW
125 UNSPEC_LDDQU
126 UNSPEC_MS_TO_SYSV_CALL
127
128 ;; Generic math support
129 UNSPEC_COPYSIGN
130 UNSPEC_IEEE_MIN ; not commutative
131 UNSPEC_IEEE_MAX ; not commutative
132
133 ;; x87 Floating point
134 UNSPEC_SIN
135 UNSPEC_COS
136 UNSPEC_FPATAN
137 UNSPEC_FYL2X
138 UNSPEC_FYL2XP1
139 UNSPEC_FRNDINT
140 UNSPEC_FIST
141 UNSPEC_F2XM1
142 UNSPEC_TAN
143 UNSPEC_FXAM
144
145 ;; x87 Rounding
146 UNSPEC_FRNDINT_FLOOR
147 UNSPEC_FRNDINT_CEIL
148 UNSPEC_FRNDINT_TRUNC
149 UNSPEC_FRNDINT_MASK_PM
150 UNSPEC_FIST_FLOOR
151 UNSPEC_FIST_CEIL
152
153 ;; x87 Double output FP
154 UNSPEC_SINCOS_COS
155 UNSPEC_SINCOS_SIN
156 UNSPEC_XTRACT_FRACT
157 UNSPEC_XTRACT_EXP
158 UNSPEC_FSCALE_FRACT
159 UNSPEC_FSCALE_EXP
160 UNSPEC_FPREM_F
161 UNSPEC_FPREM_U
162 UNSPEC_FPREM1_F
163 UNSPEC_FPREM1_U
164
165 UNSPEC_C2_FLAG
166 UNSPEC_FXAM_MEM
167
168 ;; SSP patterns
169 UNSPEC_SP_SET
170 UNSPEC_SP_TEST
171 UNSPEC_SP_TLS_SET
172 UNSPEC_SP_TLS_TEST
173
174 ;; SSSE3
175 UNSPEC_PSHUFB
176 UNSPEC_PSIGN
177 UNSPEC_PALIGNR
178
179 ;; For SSE4A support
180 UNSPEC_EXTRQI
181 UNSPEC_EXTRQ
182 UNSPEC_INSERTQI
183 UNSPEC_INSERTQ
184
185 ;; For SSE4.1 support
186 UNSPEC_BLENDV
187 UNSPEC_INSERTPS
188 UNSPEC_DP
189 UNSPEC_MOVNTDQA
190 UNSPEC_MPSADBW
191 UNSPEC_PHMINPOSUW
192 UNSPEC_PTEST
193 UNSPEC_ROUND
194
195 ;; For SSE4.2 support
196 UNSPEC_CRC32
197 UNSPEC_PCMPESTR
198 UNSPEC_PCMPISTR
199
200 ;; For FMA4 support
201 UNSPEC_FMA4_INTRINSIC
202 UNSPEC_FMA4_FMADDSUB
203 UNSPEC_FMA4_FMSUBADD
204 UNSPEC_XOP_UNSIGNED_CMP
205 UNSPEC_XOP_TRUEFALSE
206 UNSPEC_XOP_PERMUTE
207 UNSPEC_FRCZ
208
209 ;; For AES support
210 UNSPEC_AESENC
211 UNSPEC_AESENCLAST
212 UNSPEC_AESDEC
213 UNSPEC_AESDECLAST
214 UNSPEC_AESIMC
215 UNSPEC_AESKEYGENASSIST
216
217 ;; For PCLMUL support
218 UNSPEC_PCLMUL
219
220 ;; For AVX support
221 UNSPEC_PCMP
222 UNSPEC_VPERMIL
223 UNSPEC_VPERMIL2
224 UNSPEC_VPERMIL2F128
225 UNSPEC_MASKLOAD
226 UNSPEC_MASKSTORE
227 UNSPEC_CAST
228 UNSPEC_VTESTP
229 ])
230
231 (define_c_enum "unspecv" [
232 UNSPECV_BLOCKAGE
233 UNSPECV_STACK_PROBE
234 UNSPECV_EMMS
235 UNSPECV_LDMXCSR
236 UNSPECV_STMXCSR
237 UNSPECV_FEMMS
238 UNSPECV_CLFLUSH
239 UNSPECV_ALIGN
240 UNSPECV_MONITOR
241 UNSPECV_MWAIT
242 UNSPECV_CMPXCHG
243 UNSPECV_XCHG
244 UNSPECV_LOCK
245 UNSPECV_PROLOGUE_USE
246 UNSPECV_CLD
247 UNSPECV_VZEROALL
248 UNSPECV_VZEROUPPER
249 UNSPECV_RDTSC
250 UNSPECV_RDTSCP
251 UNSPECV_RDPMC
252 UNSPECV_VSWAPMOV
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
257 ])
258
259 ;; Constants to represent pcomtrue/pcomfalse variants
260 (define_constants
261 [(PCOM_FALSE 0)
262 (PCOM_TRUE 1)
263 (COM_FALSE_S 2)
264 (COM_FALSE_P 3)
265 (COM_TRUE_S 4)
266 (COM_TRUE_P 5)
267 ])
268
269 ;; Constants used in the XOP pperm instruction
270 (define_constants
271 [(PPERM_SRC 0x00) /* copy source */
272 (PPERM_INVERT 0x20) /* invert source */
273 (PPERM_REVERSE 0x40) /* bit reverse source */
274 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
275 (PPERM_ZERO 0x80) /* all 0's */
276 (PPERM_ONES 0xa0) /* all 1's */
277 (PPERM_SIGN 0xc0) /* propagate sign bit */
278 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
279 (PPERM_SRC1 0x00) /* use first source byte */
280 (PPERM_SRC2 0x10) /* use second source byte */
281 ])
282
283 ;; Registers by name.
284 (define_constants
285 [(AX_REG 0)
286 (DX_REG 1)
287 (CX_REG 2)
288 (BX_REG 3)
289 (SI_REG 4)
290 (DI_REG 5)
291 (BP_REG 6)
292 (SP_REG 7)
293 (ST0_REG 8)
294 (ST1_REG 9)
295 (ST2_REG 10)
296 (ST3_REG 11)
297 (ST4_REG 12)
298 (ST5_REG 13)
299 (ST6_REG 14)
300 (ST7_REG 15)
301 (FLAGS_REG 17)
302 (FPSR_REG 18)
303 (FPCR_REG 19)
304 (XMM0_REG 21)
305 (XMM1_REG 22)
306 (XMM2_REG 23)
307 (XMM3_REG 24)
308 (XMM4_REG 25)
309 (XMM5_REG 26)
310 (XMM6_REG 27)
311 (XMM7_REG 28)
312 (MM0_REG 29)
313 (MM1_REG 30)
314 (MM2_REG 31)
315 (MM3_REG 32)
316 (MM4_REG 33)
317 (MM5_REG 34)
318 (MM6_REG 35)
319 (MM7_REG 36)
320 (R8_REG 37)
321 (R9_REG 38)
322 (R10_REG 39)
323 (R11_REG 40)
324 (R12_REG 41)
325 (R13_REG 42)
326 (XMM8_REG 45)
327 (XMM9_REG 46)
328 (XMM10_REG 47)
329 (XMM11_REG 48)
330 (XMM12_REG 49)
331 (XMM13_REG 50)
332 (XMM14_REG 51)
333 (XMM15_REG 52)
334 ])
335
336 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; from i386.c.
338
339 ;; In C guard expressions, put expressions which may be compile-time
340 ;; constants first. This allows for better optimization. For
341 ;; example, write "TARGET_64BIT && reload_completed", not
342 ;; "reload_completed && TARGET_64BIT".
343
344 \f
345 ;; Processor type.
346 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
347 generic64,amdfam10,bdver1"
348 (const (symbol_ref "ix86_schedule")))
349
350 ;; A basic instruction type. Refinements due to arguments to be
351 ;; provided in other attributes.
352 (define_attr "type"
353 "other,multi,
354 alu,alu1,negnot,imov,imovx,lea,
355 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
356 icmp,test,ibr,setcc,icmov,
357 push,pop,call,callv,leave,
358 str,bitmanip,
359 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
360 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
361 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
362 ssemuladd,sse4arg,lwp,
363 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
364 (const_string "other"))
365
366 ;; Main data type used by the insn
367 (define_attr "mode"
368 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
369 (const_string "unknown"))
370
371 ;; The CPU unit operations uses.
372 (define_attr "unit" "integer,i387,sse,mmx,unknown"
373 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
374 (const_string "i387")
375 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
376 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
377 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
378 (const_string "sse")
379 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
380 (const_string "mmx")
381 (eq_attr "type" "other")
382 (const_string "unknown")]
383 (const_string "integer")))
384
385 ;; The (bounding maximum) length of an instruction immediate.
386 (define_attr "length_immediate" ""
387 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 bitmanip")
389 (const_int 0)
390 (eq_attr "unit" "i387,sse,mmx")
391 (const_int 0)
392 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
393 imul,icmp,push,pop")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
395 (eq_attr "type" "imov,test")
396 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
397 (eq_attr "type" "call")
398 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (const_int 4)
400 (const_int 0))
401 (eq_attr "type" "callv")
402 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 (const_int 4)
404 (const_int 0))
405 ;; We don't know the size before shorten_branches. Expect
406 ;; the instruction to fit for better scheduling.
407 (eq_attr "type" "ibr")
408 (const_int 1)
409 ]
410 (symbol_ref "/* Update immediate_length and other attributes! */
411 gcc_unreachable (),1")))
412
413 ;; The (bounding maximum) length of an instruction address.
414 (define_attr "length_address" ""
415 (cond [(eq_attr "type" "str,other,multi,fxch")
416 (const_int 0)
417 (and (eq_attr "type" "call")
418 (match_operand 0 "constant_call_address_operand" ""))
419 (const_int 0)
420 (and (eq_attr "type" "callv")
421 (match_operand 1 "constant_call_address_operand" ""))
422 (const_int 0)
423 ]
424 (symbol_ref "ix86_attr_length_address_default (insn)")))
425
426 ;; Set when length prefix is used.
427 (define_attr "prefix_data16" ""
428 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429 (const_int 0)
430 (eq_attr "mode" "HI")
431 (const_int 1)
432 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
433 (const_int 1)
434 ]
435 (const_int 0)))
436
437 ;; Set when string REP prefix is used.
438 (define_attr "prefix_rep" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
440 (const_int 0)
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
442 (const_int 1)
443 ]
444 (const_int 0)))
445
446 ;; Set when 0f opcode prefix is used.
447 (define_attr "prefix_0f" ""
448 (if_then_else
449 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
450 (eq_attr "unit" "sse,mmx"))
451 (const_int 1)
452 (const_int 0)))
453
454 ;; Set when REX opcode prefix is used.
455 (define_attr "prefix_rex" ""
456 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
457 (const_int 0)
458 (and (eq_attr "mode" "DI")
459 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
460 (eq_attr "unit" "!mmx")))
461 (const_int 1)
462 (and (eq_attr "mode" "QI")
463 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (const_int 0)))
465 (const_int 1)
466 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (const_int 0))
468 (const_int 1)
469 (and (eq_attr "type" "imovx")
470 (match_operand:QI 1 "ext_QIreg_operand" ""))
471 (const_int 1)
472 ]
473 (const_int 0)))
474
475 ;; There are also additional prefixes in 3DNOW, SSSE3.
476 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
477 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
478 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
479 (define_attr "prefix_extra" ""
480 (cond [(eq_attr "type" "ssemuladd,sse4arg")
481 (const_int 2)
482 (eq_attr "type" "sseiadd1,ssecvt1")
483 (const_int 1)
484 ]
485 (const_int 0)))
486
487 ;; Prefix used: original, VEX or maybe VEX.
488 (define_attr "prefix" "orig,vex,maybe_vex"
489 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
490 (const_string "vex")
491 (const_string "orig")))
492
493 ;; VEX W bit is used.
494 (define_attr "prefix_vex_w" "" (const_int 0))
495
496 ;; The length of VEX prefix
497 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
498 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
499 ;; still prefix_0f 1, with prefix_extra 1.
500 (define_attr "length_vex" ""
501 (if_then_else (and (eq_attr "prefix_0f" "1")
502 (eq_attr "prefix_extra" "0"))
503 (if_then_else (eq_attr "prefix_vex_w" "1")
504 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
506 (if_then_else (eq_attr "prefix_vex_w" "1")
507 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
508 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509
510 ;; Set when modrm byte is used.
511 (define_attr "modrm" ""
512 (cond [(eq_attr "type" "str,leave")
513 (const_int 0)
514 (eq_attr "unit" "i387")
515 (const_int 0)
516 (and (eq_attr "type" "incdec")
517 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
518 (ior (match_operand:SI 1 "register_operand" "")
519 (match_operand:HI 1 "register_operand" ""))))
520 (const_int 0)
521 (and (eq_attr "type" "push")
522 (not (match_operand 1 "memory_operand" "")))
523 (const_int 0)
524 (and (eq_attr "type" "pop")
525 (not (match_operand 0 "memory_operand" "")))
526 (const_int 0)
527 (and (eq_attr "type" "imov")
528 (and (not (eq_attr "mode" "DI"))
529 (ior (and (match_operand 0 "register_operand" "")
530 (match_operand 1 "immediate_operand" ""))
531 (ior (and (match_operand 0 "ax_reg_operand" "")
532 (match_operand 1 "memory_displacement_only_operand" ""))
533 (and (match_operand 0 "memory_displacement_only_operand" "")
534 (match_operand 1 "ax_reg_operand" ""))))))
535 (const_int 0)
536 (and (eq_attr "type" "call")
537 (match_operand 0 "constant_call_address_operand" ""))
538 (const_int 0)
539 (and (eq_attr "type" "callv")
540 (match_operand 1 "constant_call_address_operand" ""))
541 (const_int 0)
542 (and (eq_attr "type" "alu,alu1,icmp,test")
543 (match_operand 0 "ax_reg_operand" ""))
544 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
545 ]
546 (const_int 1)))
547
548 ;; The (bounding maximum) length of an instruction in bytes.
549 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
550 ;; Later we may want to split them and compute proper length as for
551 ;; other insns.
552 (define_attr "length" ""
553 (cond [(eq_attr "type" "other,multi,fistp,frndint")
554 (const_int 16)
555 (eq_attr "type" "fcmp")
556 (const_int 4)
557 (eq_attr "unit" "i387")
558 (plus (const_int 2)
559 (plus (attr "prefix_data16")
560 (attr "length_address")))
561 (ior (eq_attr "prefix" "vex")
562 (and (eq_attr "prefix" "maybe_vex")
563 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
564 (plus (attr "length_vex")
565 (plus (attr "length_immediate")
566 (plus (attr "modrm")
567 (attr "length_address"))))]
568 (plus (plus (attr "modrm")
569 (plus (attr "prefix_0f")
570 (plus (attr "prefix_rex")
571 (plus (attr "prefix_extra")
572 (const_int 1)))))
573 (plus (attr "prefix_rep")
574 (plus (attr "prefix_data16")
575 (plus (attr "length_immediate")
576 (attr "length_address")))))))
577
578 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
579 ;; `store' if there is a simple memory reference therein, or `unknown'
580 ;; if the instruction is complex.
581
582 (define_attr "memory" "none,load,store,both,unknown"
583 (cond [(eq_attr "type" "other,multi,str,lwp")
584 (const_string "unknown")
585 (eq_attr "type" "lea,fcmov,fpspc")
586 (const_string "none")
587 (eq_attr "type" "fistp,leave")
588 (const_string "both")
589 (eq_attr "type" "frndint")
590 (const_string "load")
591 (eq_attr "type" "push")
592 (if_then_else (match_operand 1 "memory_operand" "")
593 (const_string "both")
594 (const_string "store"))
595 (eq_attr "type" "pop")
596 (if_then_else (match_operand 0 "memory_operand" "")
597 (const_string "both")
598 (const_string "load"))
599 (eq_attr "type" "setcc")
600 (if_then_else (match_operand 0 "memory_operand" "")
601 (const_string "store")
602 (const_string "none"))
603 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
604 (if_then_else (ior (match_operand 0 "memory_operand" "")
605 (match_operand 1 "memory_operand" ""))
606 (const_string "load")
607 (const_string "none"))
608 (eq_attr "type" "ibr")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "load")
611 (const_string "none"))
612 (eq_attr "type" "call")
613 (if_then_else (match_operand 0 "constant_call_address_operand" "")
614 (const_string "none")
615 (const_string "load"))
616 (eq_attr "type" "callv")
617 (if_then_else (match_operand 1 "constant_call_address_operand" "")
618 (const_string "none")
619 (const_string "load"))
620 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
621 (match_operand 1 "memory_operand" ""))
622 (const_string "both")
623 (and (match_operand 0 "memory_operand" "")
624 (match_operand 1 "memory_operand" ""))
625 (const_string "both")
626 (match_operand 0 "memory_operand" "")
627 (const_string "store")
628 (match_operand 1 "memory_operand" "")
629 (const_string "load")
630 (and (eq_attr "type"
631 "!alu1,negnot,ishift1,
632 imov,imovx,icmp,test,bitmanip,
633 fmov,fcmp,fsgn,
634 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
635 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
636 (match_operand 2 "memory_operand" ""))
637 (const_string "load")
638 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
639 (match_operand 3 "memory_operand" ""))
640 (const_string "load")
641 ]
642 (const_string "none")))
643
644 ;; Indicates if an instruction has both an immediate and a displacement.
645
646 (define_attr "imm_disp" "false,true,unknown"
647 (cond [(eq_attr "type" "other,multi")
648 (const_string "unknown")
649 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
650 (and (match_operand 0 "memory_displacement_operand" "")
651 (match_operand 1 "immediate_operand" "")))
652 (const_string "true")
653 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
654 (and (match_operand 0 "memory_displacement_operand" "")
655 (match_operand 2 "immediate_operand" "")))
656 (const_string "true")
657 ]
658 (const_string "false")))
659
660 ;; Indicates if an FP operation has an integer source.
661
662 (define_attr "fp_int_src" "false,true"
663 (const_string "false"))
664
665 ;; Defines rounding mode of an FP operation.
666
667 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
668 (const_string "any"))
669
670 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
671 (define_attr "use_carry" "0,1" (const_string "0"))
672
673 ;; Define attribute to indicate unaligned ssemov insns
674 (define_attr "movu" "0,1" (const_string "0"))
675
676 ;; Describe a user's asm statement.
677 (define_asm_attributes
678 [(set_attr "length" "128")
679 (set_attr "type" "multi")])
680
681 ;; All integer comparison codes.
682 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683
684 ;; All floating-point comparison codes.
685 (define_code_iterator fp_cond [unordered ordered
686 uneq unge ungt unle unlt ltgt])
687
688 (define_code_iterator plusminus [plus minus])
689
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699 [(plus "add") (ss_plus "adds") (us_plus "addus")
700 (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702 [(plus "adc") (minus "sbb")])
703
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706 (minus "") (ss_minus "") (us_minus "")])
707
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
710
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
713
714 ;; Mapping of signed/unsigned max and min
715 (define_code_iterator maxmin [smax smin umax umin])
716
717 ;; Base name for integer and FP insn mnemonic
718 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
719 (umax "maxu") (umin "minu")])
720 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721
722 ;; Mapping of logic operators
723 (define_code_iterator any_logic [and ior xor])
724 (define_code_iterator any_or [ior xor])
725
726 ;; Base name for insn mnemonic.
727 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728
729 ;; Mapping of shift-right operators
730 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731
732 ;; Base name for define_insn
733 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734
735 ;; Base name for insn mnemonic.
736 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737
738 ;; Mapping of rotate operators
739 (define_code_iterator any_rotate [rotate rotatert])
740
741 ;; Base name for define_insn
742 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743
744 ;; Base name for insn mnemonic.
745 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746
747 ;; Mapping of abs neg operators
748 (define_code_iterator absneg [abs neg])
749
750 ;; Base name for x87 insn mnemonic.
751 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752
753 ;; Used in signed and unsigned widening multiplications.
754 (define_code_iterator any_extend [sign_extend zero_extend])
755
756 ;; Various insn prefixes for signed and unsigned operations.
757 (define_code_attr u [(sign_extend "") (zero_extend "u")
758 (div "") (udiv "u")])
759 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760
761 ;; Used in signed and unsigned divisions.
762 (define_code_iterator any_div [div udiv])
763 (define_code_attr extract_code
764 [(div "SIGN_EXTRACT") (udiv "ZERO_EXTRACT")])
765
766 ;; Instruction prefix for signed and unsigned operations.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
768 (div "i") (udiv "")])
769
770 ;; 64bit single word integer modes.
771 (define_mode_iterator SWI1248x [QI HI SI DI])
772
773 ;; 64bit single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
775
776 ;; Single word integer modes.
777 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
778
779 ;; Single word integer modes without SImode and DImode.
780 (define_mode_iterator SWI12 [QI HI])
781
782 ;; Single word integer modes without DImode.
783 (define_mode_iterator SWI124 [QI HI SI])
784
785 ;; Single word integer modes without QImode and DImode.
786 (define_mode_iterator SWI24 [HI SI])
787
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
790
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
793
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI DI (TI "TARGET_64BIT")])
798
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
802 SI (DI "TARGET_64BIT")])
803
804 ;; Math-dependant single word integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806 (HI "TARGET_HIMODE_MATH")
807 SI])
808
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811 SI (DI "TARGET_64BIT")])
812
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815 (TI "TARGET_64BIT")])
816
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
820
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823 (DI "TARGET_64BIT")])
824
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
827
828 ;; Register class for integer modes.
829 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
830
831 ;; Immediate operand constraint for integer modes.
832 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
833
834 ;; General operand constraint for word modes.
835 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
836
837 ;; Immediate operand constraint for double integer modes.
838 (define_mode_attr di [(SI "iF") (DI "e")])
839
840 ;; Immediate operand constraint for shifts.
841 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
842
843 ;; General operand predicate for integer modes.
844 (define_mode_attr general_operand
845 [(QI "general_operand")
846 (HI "general_operand")
847 (SI "general_operand")
848 (DI "x86_64_general_operand")
849 (TI "x86_64_general_operand")])
850
851 ;; General sign/zero extend operand predicate for integer modes.
852 (define_mode_attr general_szext_operand
853 [(QI "general_operand")
854 (HI "general_operand")
855 (SI "general_operand")
856 (DI "x86_64_szext_general_operand")])
857
858 ;; Operand predicate for shifts.
859 (define_mode_attr shift_operand
860 [(QI "nonimmediate_operand")
861 (HI "nonimmediate_operand")
862 (SI "nonimmediate_operand")
863 (DI "shiftdi_operand")
864 (TI "register_operand")])
865
866 ;; Operand predicate for shift argument.
867 (define_mode_attr shift_immediate_operand
868 [(QI "const_1_to_31_operand")
869 (HI "const_1_to_31_operand")
870 (SI "const_1_to_31_operand")
871 (DI "const_1_to_63_operand")])
872
873 ;; Input operand predicate for arithmetic left shifts.
874 (define_mode_attr ashl_input_operand
875 [(QI "nonimmediate_operand")
876 (HI "nonimmediate_operand")
877 (SI "nonimmediate_operand")
878 (DI "ashldi_input_operand")
879 (TI "reg_or_pm1_operand")])
880
881 ;; SSE and x87 SFmode and DFmode floating point modes
882 (define_mode_iterator MODEF [SF DF])
883
884 ;; All x87 floating point modes
885 (define_mode_iterator X87MODEF [SF DF XF])
886
887 ;; All integer modes handled by x87 fisttp operator.
888 (define_mode_iterator X87MODEI [HI SI DI])
889
890 ;; All integer modes handled by integer x87 operators.
891 (define_mode_iterator X87MODEI12 [HI SI])
892
893 ;; All integer modes handled by SSE cvtts?2si* operators.
894 (define_mode_iterator SSEMODEI24 [SI DI])
895
896 ;; SSE asm suffix for floating point modes
897 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
898
899 ;; SSE vector mode corresponding to a scalar mode
900 (define_mode_attr ssevecmode
901 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
902
903 ;; Instruction suffix for REX 64bit operators.
904 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
905
906 ;; This mode iterator allows :P to be used for patterns that operate on
907 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
908 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
909 \f
910 ;; Scheduling descriptions
911
912 (include "pentium.md")
913 (include "ppro.md")
914 (include "k6.md")
915 (include "athlon.md")
916 (include "geode.md")
917 (include "atom.md")
918
919 \f
920 ;; Operand and operator predicates and constraints
921
922 (include "predicates.md")
923 (include "constraints.md")
924
925 \f
926 ;; Compare and branch/compare and store instructions.
927
928 (define_expand "cbranch<mode>4"
929 [(set (reg:CC FLAGS_REG)
930 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
931 (match_operand:SDWIM 2 "<general_operand>" "")))
932 (set (pc) (if_then_else
933 (match_operator 0 "comparison_operator"
934 [(reg:CC FLAGS_REG) (const_int 0)])
935 (label_ref (match_operand 3 "" ""))
936 (pc)))]
937 ""
938 {
939 if (MEM_P (operands[1]) && MEM_P (operands[2]))
940 operands[1] = force_reg (<MODE>mode, operands[1]);
941 ix86_compare_op0 = operands[1];
942 ix86_compare_op1 = operands[2];
943 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
944 DONE;
945 })
946
947 (define_expand "cstore<mode>4"
948 [(set (reg:CC FLAGS_REG)
949 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
950 (match_operand:SWIM 3 "<general_operand>" "")))
951 (set (match_operand:QI 0 "register_operand" "")
952 (match_operator 1 "comparison_operator"
953 [(reg:CC FLAGS_REG) (const_int 0)]))]
954 ""
955 {
956 if (MEM_P (operands[2]) && MEM_P (operands[3]))
957 operands[2] = force_reg (<MODE>mode, operands[2]);
958 ix86_compare_op0 = operands[2];
959 ix86_compare_op1 = operands[3];
960 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
961 DONE;
962 })
963
964 (define_expand "cmp<mode>_1"
965 [(set (reg:CC FLAGS_REG)
966 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
967 (match_operand:SWI48 1 "<general_operand>" "")))]
968 ""
969 "")
970
971 (define_insn "*cmp<mode>_ccno_1"
972 [(set (reg FLAGS_REG)
973 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
974 (match_operand:SWI 1 "const0_operand" "")))]
975 "ix86_match_ccmode (insn, CCNOmode)"
976 "@
977 test{<imodesuffix>}\t%0, %0
978 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
979 [(set_attr "type" "test,icmp")
980 (set_attr "length_immediate" "0,1")
981 (set_attr "mode" "<MODE>")])
982
983 (define_insn "*cmp<mode>_1"
984 [(set (reg FLAGS_REG)
985 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
986 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
987 "ix86_match_ccmode (insn, CCmode)"
988 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
989 [(set_attr "type" "icmp")
990 (set_attr "mode" "<MODE>")])
991
992 (define_insn "*cmp<mode>_minus_1"
993 [(set (reg FLAGS_REG)
994 (compare
995 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
996 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
997 (const_int 0)))]
998 "ix86_match_ccmode (insn, CCGOCmode)"
999 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "mode" "<MODE>")])
1002
1003 (define_insn "*cmpqi_ext_1"
1004 [(set (reg FLAGS_REG)
1005 (compare
1006 (match_operand:QI 0 "general_operand" "Qm")
1007 (subreg:QI
1008 (zero_extract:SI
1009 (match_operand 1 "ext_register_operand" "Q")
1010 (const_int 8)
1011 (const_int 8)) 0)))]
1012 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013 "cmp{b}\t{%h1, %0|%0, %h1}"
1014 [(set_attr "type" "icmp")
1015 (set_attr "mode" "QI")])
1016
1017 (define_insn "*cmpqi_ext_1_rex64"
1018 [(set (reg FLAGS_REG)
1019 (compare
1020 (match_operand:QI 0 "register_operand" "Q")
1021 (subreg:QI
1022 (zero_extract:SI
1023 (match_operand 1 "ext_register_operand" "Q")
1024 (const_int 8)
1025 (const_int 8)) 0)))]
1026 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1027 "cmp{b}\t{%h1, %0|%0, %h1}"
1028 [(set_attr "type" "icmp")
1029 (set_attr "mode" "QI")])
1030
1031 (define_insn "*cmpqi_ext_2"
1032 [(set (reg FLAGS_REG)
1033 (compare
1034 (subreg:QI
1035 (zero_extract:SI
1036 (match_operand 0 "ext_register_operand" "Q")
1037 (const_int 8)
1038 (const_int 8)) 0)
1039 (match_operand:QI 1 "const0_operand" "")))]
1040 "ix86_match_ccmode (insn, CCNOmode)"
1041 "test{b}\t%h0, %h0"
1042 [(set_attr "type" "test")
1043 (set_attr "length_immediate" "0")
1044 (set_attr "mode" "QI")])
1045
1046 (define_expand "cmpqi_ext_3"
1047 [(set (reg:CC FLAGS_REG)
1048 (compare:CC
1049 (subreg:QI
1050 (zero_extract:SI
1051 (match_operand 0 "ext_register_operand" "")
1052 (const_int 8)
1053 (const_int 8)) 0)
1054 (match_operand:QI 1 "immediate_operand" "")))]
1055 ""
1056 "")
1057
1058 (define_insn "*cmpqi_ext_3_insn"
1059 [(set (reg FLAGS_REG)
1060 (compare
1061 (subreg:QI
1062 (zero_extract:SI
1063 (match_operand 0 "ext_register_operand" "Q")
1064 (const_int 8)
1065 (const_int 8)) 0)
1066 (match_operand:QI 1 "general_operand" "Qmn")))]
1067 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1068 "cmp{b}\t{%1, %h0|%h0, %1}"
1069 [(set_attr "type" "icmp")
1070 (set_attr "modrm" "1")
1071 (set_attr "mode" "QI")])
1072
1073 (define_insn "*cmpqi_ext_3_insn_rex64"
1074 [(set (reg FLAGS_REG)
1075 (compare
1076 (subreg:QI
1077 (zero_extract:SI
1078 (match_operand 0 "ext_register_operand" "Q")
1079 (const_int 8)
1080 (const_int 8)) 0)
1081 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1082 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1083 "cmp{b}\t{%1, %h0|%h0, %1}"
1084 [(set_attr "type" "icmp")
1085 (set_attr "modrm" "1")
1086 (set_attr "mode" "QI")])
1087
1088 (define_insn "*cmpqi_ext_4"
1089 [(set (reg FLAGS_REG)
1090 (compare
1091 (subreg:QI
1092 (zero_extract:SI
1093 (match_operand 0 "ext_register_operand" "Q")
1094 (const_int 8)
1095 (const_int 8)) 0)
1096 (subreg:QI
1097 (zero_extract:SI
1098 (match_operand 1 "ext_register_operand" "Q")
1099 (const_int 8)
1100 (const_int 8)) 0)))]
1101 "ix86_match_ccmode (insn, CCmode)"
1102 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1103 [(set_attr "type" "icmp")
1104 (set_attr "mode" "QI")])
1105
1106 ;; These implement float point compares.
1107 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1108 ;; which would allow mix and match FP modes on the compares. Which is what
1109 ;; the old patterns did, but with many more of them.
1110
1111 (define_expand "cbranchxf4"
1112 [(set (reg:CC FLAGS_REG)
1113 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1114 (match_operand:XF 2 "nonmemory_operand" "")))
1115 (set (pc) (if_then_else
1116 (match_operator 0 "ix86_fp_comparison_operator"
1117 [(reg:CC FLAGS_REG)
1118 (const_int 0)])
1119 (label_ref (match_operand 3 "" ""))
1120 (pc)))]
1121 "TARGET_80387"
1122 {
1123 ix86_compare_op0 = operands[1];
1124 ix86_compare_op1 = operands[2];
1125 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1126 DONE;
1127 })
1128
1129 (define_expand "cstorexf4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1132 (match_operand:XF 3 "nonmemory_operand" "")))
1133 (set (match_operand:QI 0 "register_operand" "")
1134 (match_operator 1 "ix86_fp_comparison_operator"
1135 [(reg:CC FLAGS_REG)
1136 (const_int 0)]))]
1137 "TARGET_80387"
1138 {
1139 ix86_compare_op0 = operands[2];
1140 ix86_compare_op1 = operands[3];
1141 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1142 DONE;
1143 })
1144
1145 (define_expand "cbranch<mode>4"
1146 [(set (reg:CC FLAGS_REG)
1147 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1148 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1149 (set (pc) (if_then_else
1150 (match_operator 0 "ix86_fp_comparison_operator"
1151 [(reg:CC FLAGS_REG)
1152 (const_int 0)])
1153 (label_ref (match_operand 3 "" ""))
1154 (pc)))]
1155 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1156 {
1157 ix86_compare_op0 = operands[1];
1158 ix86_compare_op1 = operands[2];
1159 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1160 DONE;
1161 })
1162
1163 (define_expand "cstore<mode>4"
1164 [(set (reg:CC FLAGS_REG)
1165 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1166 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1167 (set (match_operand:QI 0 "register_operand" "")
1168 (match_operator 1 "ix86_fp_comparison_operator"
1169 [(reg:CC FLAGS_REG)
1170 (const_int 0)]))]
1171 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1172 {
1173 ix86_compare_op0 = operands[2];
1174 ix86_compare_op1 = operands[3];
1175 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1176 DONE;
1177 })
1178
1179 (define_expand "cbranchcc4"
1180 [(set (pc) (if_then_else
1181 (match_operator 0 "comparison_operator"
1182 [(match_operand 1 "flags_reg_operand" "")
1183 (match_operand 2 "const0_operand" "")])
1184 (label_ref (match_operand 3 "" ""))
1185 (pc)))]
1186 ""
1187 {
1188 ix86_compare_op0 = operands[1];
1189 ix86_compare_op1 = operands[2];
1190 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1191 DONE;
1192 })
1193
1194 (define_expand "cstorecc4"
1195 [(set (match_operand:QI 0 "register_operand" "")
1196 (match_operator 1 "comparison_operator"
1197 [(match_operand 2 "flags_reg_operand" "")
1198 (match_operand 3 "const0_operand" "")]))]
1199 ""
1200 {
1201 ix86_compare_op0 = operands[2];
1202 ix86_compare_op1 = operands[3];
1203 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1204 DONE;
1205 })
1206
1207
1208 ;; FP compares, step 1:
1209 ;; Set the FP condition codes.
1210 ;;
1211 ;; CCFPmode compare with exceptions
1212 ;; CCFPUmode compare with no exceptions
1213
1214 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1215 ;; used to manage the reg stack popping would not be preserved.
1216
1217 (define_insn "*cmpfp_0"
1218 [(set (match_operand:HI 0 "register_operand" "=a")
1219 (unspec:HI
1220 [(compare:CCFP
1221 (match_operand 1 "register_operand" "f")
1222 (match_operand 2 "const0_operand" ""))]
1223 UNSPEC_FNSTSW))]
1224 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1226 "* return output_fp_compare (insn, operands, 0, 0);"
1227 [(set_attr "type" "multi")
1228 (set_attr "unit" "i387")
1229 (set (attr "mode")
1230 (cond [(match_operand:SF 1 "" "")
1231 (const_string "SF")
1232 (match_operand:DF 1 "" "")
1233 (const_string "DF")
1234 ]
1235 (const_string "XF")))])
1236
1237 (define_insn_and_split "*cmpfp_0_cc"
1238 [(set (reg:CCFP FLAGS_REG)
1239 (compare:CCFP
1240 (match_operand 1 "register_operand" "f")
1241 (match_operand 2 "const0_operand" "")))
1242 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1243 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1244 && TARGET_SAHF && !TARGET_CMOVE
1245 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1246 "#"
1247 "&& reload_completed"
1248 [(set (match_dup 0)
1249 (unspec:HI
1250 [(compare:CCFP (match_dup 1)(match_dup 2))]
1251 UNSPEC_FNSTSW))
1252 (set (reg:CC FLAGS_REG)
1253 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1254 ""
1255 [(set_attr "type" "multi")
1256 (set_attr "unit" "i387")
1257 (set (attr "mode")
1258 (cond [(match_operand:SF 1 "" "")
1259 (const_string "SF")
1260 (match_operand:DF 1 "" "")
1261 (const_string "DF")
1262 ]
1263 (const_string "XF")))])
1264
1265 (define_insn "*cmpfp_xf"
1266 [(set (match_operand:HI 0 "register_operand" "=a")
1267 (unspec:HI
1268 [(compare:CCFP
1269 (match_operand:XF 1 "register_operand" "f")
1270 (match_operand:XF 2 "register_operand" "f"))]
1271 UNSPEC_FNSTSW))]
1272 "TARGET_80387"
1273 "* return output_fp_compare (insn, operands, 0, 0);"
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1276 (set_attr "mode" "XF")])
1277
1278 (define_insn_and_split "*cmpfp_xf_cc"
1279 [(set (reg:CCFP FLAGS_REG)
1280 (compare:CCFP
1281 (match_operand:XF 1 "register_operand" "f")
1282 (match_operand:XF 2 "register_operand" "f")))
1283 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1284 "TARGET_80387
1285 && TARGET_SAHF && !TARGET_CMOVE"
1286 "#"
1287 "&& reload_completed"
1288 [(set (match_dup 0)
1289 (unspec:HI
1290 [(compare:CCFP (match_dup 1)(match_dup 2))]
1291 UNSPEC_FNSTSW))
1292 (set (reg:CC FLAGS_REG)
1293 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 ""
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "XF")])
1298
1299 (define_insn "*cmpfp_<mode>"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (unspec:HI
1302 [(compare:CCFP
1303 (match_operand:MODEF 1 "register_operand" "f")
1304 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1305 UNSPEC_FNSTSW))]
1306 "TARGET_80387"
1307 "* return output_fp_compare (insn, operands, 0, 0);"
1308 [(set_attr "type" "multi")
1309 (set_attr "unit" "i387")
1310 (set_attr "mode" "<MODE>")])
1311
1312 (define_insn_and_split "*cmpfp_<mode>_cc"
1313 [(set (reg:CCFP FLAGS_REG)
1314 (compare:CCFP
1315 (match_operand:MODEF 1 "register_operand" "f")
1316 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1317 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1318 "TARGET_80387
1319 && TARGET_SAHF && !TARGET_CMOVE"
1320 "#"
1321 "&& reload_completed"
1322 [(set (match_dup 0)
1323 (unspec:HI
1324 [(compare:CCFP (match_dup 1)(match_dup 2))]
1325 UNSPEC_FNSTSW))
1326 (set (reg:CC FLAGS_REG)
1327 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1328 ""
1329 [(set_attr "type" "multi")
1330 (set_attr "unit" "i387")
1331 (set_attr "mode" "<MODE>")])
1332
1333 (define_insn "*cmpfp_u"
1334 [(set (match_operand:HI 0 "register_operand" "=a")
1335 (unspec:HI
1336 [(compare:CCFPU
1337 (match_operand 1 "register_operand" "f")
1338 (match_operand 2 "register_operand" "f"))]
1339 UNSPEC_FNSTSW))]
1340 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1342 "* return output_fp_compare (insn, operands, 0, 1);"
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set (attr "mode")
1346 (cond [(match_operand:SF 1 "" "")
1347 (const_string "SF")
1348 (match_operand:DF 1 "" "")
1349 (const_string "DF")
1350 ]
1351 (const_string "XF")))])
1352
1353 (define_insn_and_split "*cmpfp_u_cc"
1354 [(set (reg:CCFPU FLAGS_REG)
1355 (compare:CCFPU
1356 (match_operand 1 "register_operand" "f")
1357 (match_operand 2 "register_operand" "f")))
1358 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1359 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1360 && TARGET_SAHF && !TARGET_CMOVE
1361 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1362 "#"
1363 "&& reload_completed"
1364 [(set (match_dup 0)
1365 (unspec:HI
1366 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1367 UNSPEC_FNSTSW))
1368 (set (reg:CC FLAGS_REG)
1369 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1370 ""
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1373 (set (attr "mode")
1374 (cond [(match_operand:SF 1 "" "")
1375 (const_string "SF")
1376 (match_operand:DF 1 "" "")
1377 (const_string "DF")
1378 ]
1379 (const_string "XF")))])
1380
1381 (define_insn "*cmpfp_<mode>"
1382 [(set (match_operand:HI 0 "register_operand" "=a")
1383 (unspec:HI
1384 [(compare:CCFP
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1388 UNSPEC_FNSTSW))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392 "* return output_fp_compare (insn, operands, 0, 0);"
1393 [(set_attr "type" "multi")
1394 (set_attr "unit" "i387")
1395 (set_attr "fp_int_src" "true")
1396 (set_attr "mode" "<MODE>")])
1397
1398 (define_insn_and_split "*cmpfp_<mode>_cc"
1399 [(set (reg:CCFP FLAGS_REG)
1400 (compare:CCFP
1401 (match_operand 1 "register_operand" "f")
1402 (match_operator 3 "float_operator"
1403 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1404 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1405 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1406 && TARGET_SAHF && !TARGET_CMOVE
1407 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1408 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1409 "#"
1410 "&& reload_completed"
1411 [(set (match_dup 0)
1412 (unspec:HI
1413 [(compare:CCFP
1414 (match_dup 1)
1415 (match_op_dup 3 [(match_dup 2)]))]
1416 UNSPEC_FNSTSW))
1417 (set (reg:CC FLAGS_REG)
1418 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1419 ""
1420 [(set_attr "type" "multi")
1421 (set_attr "unit" "i387")
1422 (set_attr "fp_int_src" "true")
1423 (set_attr "mode" "<MODE>")])
1424
1425 ;; FP compares, step 2
1426 ;; Move the fpsw to ax.
1427
1428 (define_insn "x86_fnstsw_1"
1429 [(set (match_operand:HI 0 "register_operand" "=a")
1430 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1431 "TARGET_80387"
1432 "fnstsw\t%0"
1433 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1434 (set_attr "mode" "SI")
1435 (set_attr "unit" "i387")])
1436
1437 ;; FP compares, step 3
1438 ;; Get ax into flags, general case.
1439
1440 (define_insn "x86_sahf_1"
1441 [(set (reg:CC FLAGS_REG)
1442 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1443 UNSPEC_SAHF))]
1444 "TARGET_SAHF"
1445 {
1446 #ifndef HAVE_AS_IX86_SAHF
1447 if (TARGET_64BIT)
1448 return ASM_BYTE "0x9e";
1449 else
1450 #endif
1451 return "sahf";
1452 }
1453 [(set_attr "length" "1")
1454 (set_attr "athlon_decode" "vector")
1455 (set_attr "amdfam10_decode" "direct")
1456 (set_attr "mode" "SI")])
1457
1458 ;; Pentium Pro can do steps 1 through 3 in one go.
1459 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1460 (define_insn "*cmpfp_i_mixed"
1461 [(set (reg:CCFP FLAGS_REG)
1462 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1463 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1464 "TARGET_MIX_SSE_I387
1465 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1466 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1467 "* return output_fp_compare (insn, operands, 1, 0);"
1468 [(set_attr "type" "fcmp,ssecomi")
1469 (set_attr "prefix" "orig,maybe_vex")
1470 (set (attr "mode")
1471 (if_then_else (match_operand:SF 1 "" "")
1472 (const_string "SF")
1473 (const_string "DF")))
1474 (set (attr "prefix_rep")
1475 (if_then_else (eq_attr "type" "ssecomi")
1476 (const_string "0")
1477 (const_string "*")))
1478 (set (attr "prefix_data16")
1479 (cond [(eq_attr "type" "fcmp")
1480 (const_string "*")
1481 (eq_attr "mode" "DF")
1482 (const_string "1")
1483 ]
1484 (const_string "0")))
1485 (set_attr "athlon_decode" "vector")
1486 (set_attr "amdfam10_decode" "direct")])
1487
1488 (define_insn "*cmpfp_i_sse"
1489 [(set (reg:CCFP FLAGS_REG)
1490 (compare:CCFP (match_operand 0 "register_operand" "x")
1491 (match_operand 1 "nonimmediate_operand" "xm")))]
1492 "TARGET_SSE_MATH
1493 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, 1, 0);"
1496 [(set_attr "type" "ssecomi")
1497 (set_attr "prefix" "maybe_vex")
1498 (set (attr "mode")
1499 (if_then_else (match_operand:SF 1 "" "")
1500 (const_string "SF")
1501 (const_string "DF")))
1502 (set_attr "prefix_rep" "0")
1503 (set (attr "prefix_data16")
1504 (if_then_else (eq_attr "mode" "DF")
1505 (const_string "1")
1506 (const_string "0")))
1507 (set_attr "athlon_decode" "vector")
1508 (set_attr "amdfam10_decode" "direct")])
1509
1510 (define_insn "*cmpfp_i_i387"
1511 [(set (reg:CCFP FLAGS_REG)
1512 (compare:CCFP (match_operand 0 "register_operand" "f")
1513 (match_operand 1 "register_operand" "f")))]
1514 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1515 && TARGET_CMOVE
1516 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1517 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1518 "* return output_fp_compare (insn, operands, 1, 0);"
1519 [(set_attr "type" "fcmp")
1520 (set (attr "mode")
1521 (cond [(match_operand:SF 1 "" "")
1522 (const_string "SF")
1523 (match_operand:DF 1 "" "")
1524 (const_string "DF")
1525 ]
1526 (const_string "XF")))
1527 (set_attr "athlon_decode" "vector")
1528 (set_attr "amdfam10_decode" "direct")])
1529
1530 (define_insn "*cmpfp_iu_mixed"
1531 [(set (reg:CCFPU FLAGS_REG)
1532 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1533 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1534 "TARGET_MIX_SSE_I387
1535 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1536 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1537 "* return output_fp_compare (insn, operands, 1, 1);"
1538 [(set_attr "type" "fcmp,ssecomi")
1539 (set_attr "prefix" "orig,maybe_vex")
1540 (set (attr "mode")
1541 (if_then_else (match_operand:SF 1 "" "")
1542 (const_string "SF")
1543 (const_string "DF")))
1544 (set (attr "prefix_rep")
1545 (if_then_else (eq_attr "type" "ssecomi")
1546 (const_string "0")
1547 (const_string "*")))
1548 (set (attr "prefix_data16")
1549 (cond [(eq_attr "type" "fcmp")
1550 (const_string "*")
1551 (eq_attr "mode" "DF")
1552 (const_string "1")
1553 ]
1554 (const_string "0")))
1555 (set_attr "athlon_decode" "vector")
1556 (set_attr "amdfam10_decode" "direct")])
1557
1558 (define_insn "*cmpfp_iu_sse"
1559 [(set (reg:CCFPU FLAGS_REG)
1560 (compare:CCFPU (match_operand 0 "register_operand" "x")
1561 (match_operand 1 "nonimmediate_operand" "xm")))]
1562 "TARGET_SSE_MATH
1563 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1564 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1565 "* return output_fp_compare (insn, operands, 1, 1);"
1566 [(set_attr "type" "ssecomi")
1567 (set_attr "prefix" "maybe_vex")
1568 (set (attr "mode")
1569 (if_then_else (match_operand:SF 1 "" "")
1570 (const_string "SF")
1571 (const_string "DF")))
1572 (set_attr "prefix_rep" "0")
1573 (set (attr "prefix_data16")
1574 (if_then_else (eq_attr "mode" "DF")
1575 (const_string "1")
1576 (const_string "0")))
1577 (set_attr "athlon_decode" "vector")
1578 (set_attr "amdfam10_decode" "direct")])
1579
1580 (define_insn "*cmpfp_iu_387"
1581 [(set (reg:CCFPU FLAGS_REG)
1582 (compare:CCFPU (match_operand 0 "register_operand" "f")
1583 (match_operand 1 "register_operand" "f")))]
1584 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1585 && TARGET_CMOVE
1586 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1587 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1588 "* return output_fp_compare (insn, operands, 1, 1);"
1589 [(set_attr "type" "fcmp")
1590 (set (attr "mode")
1591 (cond [(match_operand:SF 1 "" "")
1592 (const_string "SF")
1593 (match_operand:DF 1 "" "")
1594 (const_string "DF")
1595 ]
1596 (const_string "XF")))
1597 (set_attr "athlon_decode" "vector")
1598 (set_attr "amdfam10_decode" "direct")])
1599 \f
1600 ;; Move instructions.
1601
1602 (define_expand "movoi"
1603 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1604 (match_operand:OI 1 "general_operand" ""))]
1605 "TARGET_AVX"
1606 "ix86_expand_move (OImode, operands); DONE;")
1607
1608 (define_expand "movti"
1609 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1610 (match_operand:TI 1 "nonimmediate_operand" ""))]
1611 "TARGET_64BIT || TARGET_SSE"
1612 {
1613 if (TARGET_64BIT)
1614 ix86_expand_move (TImode, operands);
1615 else if (push_operand (operands[0], TImode))
1616 ix86_expand_push (TImode, operands[1]);
1617 else
1618 ix86_expand_vector_move (TImode, operands);
1619 DONE;
1620 })
1621
1622 ;; This expands to what emit_move_complex would generate if we didn't
1623 ;; have a movti pattern. Having this avoids problems with reload on
1624 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1625 ;; to have around all the time.
1626 (define_expand "movcdi"
1627 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1628 (match_operand:CDI 1 "general_operand" ""))]
1629 ""
1630 {
1631 if (push_operand (operands[0], CDImode))
1632 emit_move_complex_push (CDImode, operands[0], operands[1]);
1633 else
1634 emit_move_complex_parts (operands[0], operands[1]);
1635 DONE;
1636 })
1637
1638 (define_expand "mov<mode>"
1639 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1640 (match_operand:SWI1248x 1 "general_operand" ""))]
1641 ""
1642 "ix86_expand_move (<MODE>mode, operands); DONE;")
1643
1644 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1645 ;; general_operand.
1646 ;;
1647 ;; %%% We don't use a post-inc memory reference because x86 is not a
1648 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1649 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1650 ;; targets without our curiosities, and it is just as easy to represent
1651 ;; this differently.
1652
1653 (define_insn "*pushdi2_rex64"
1654 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1655 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1656 "TARGET_64BIT"
1657 "@
1658 push{q}\t%1
1659 #"
1660 [(set_attr "type" "push,multi")
1661 (set_attr "mode" "DI")])
1662
1663 ;; Convert impossible pushes of immediate to existing instructions.
1664 ;; First try to get scratch register and go through it. In case this
1665 ;; fails, push sign extended lower part first and then overwrite
1666 ;; upper part by 32bit move.
1667 (define_peephole2
1668 [(match_scratch:DI 2 "r")
1669 (set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "immediate_operand" ""))]
1671 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1672 && !x86_64_immediate_operand (operands[1], DImode)"
1673 [(set (match_dup 2) (match_dup 1))
1674 (set (match_dup 0) (match_dup 2))]
1675 "")
1676
1677 ;; We need to define this as both peepholer and splitter for case
1678 ;; peephole2 pass is not run.
1679 ;; "&& 1" is needed to keep it from matching the previous pattern.
1680 (define_peephole2
1681 [(set (match_operand:DI 0 "push_operand" "")
1682 (match_operand:DI 1 "immediate_operand" ""))]
1683 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1684 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1685 [(set (match_dup 0) (match_dup 1))
1686 (set (match_dup 2) (match_dup 3))]
1687 {
1688 split_di (&operands[1], 1, &operands[2], &operands[3]);
1689
1690 operands[1] = gen_lowpart (DImode, operands[2]);
1691 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1692 GEN_INT (4)));
1693 })
1694
1695 (define_split
1696 [(set (match_operand:DI 0 "push_operand" "")
1697 (match_operand:DI 1 "immediate_operand" ""))]
1698 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1699 ? epilogue_completed : reload_completed)
1700 && !symbolic_operand (operands[1], DImode)
1701 && !x86_64_immediate_operand (operands[1], DImode)"
1702 [(set (match_dup 0) (match_dup 1))
1703 (set (match_dup 2) (match_dup 3))]
1704 {
1705 split_di (&operands[1], 1, &operands[2], &operands[3]);
1706
1707 operands[1] = gen_lowpart (DImode, operands[2]);
1708 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1709 GEN_INT (4)));
1710 })
1711
1712 (define_insn "*pushdi2"
1713 [(set (match_operand:DI 0 "push_operand" "=<")
1714 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1715 "!TARGET_64BIT"
1716 "#")
1717
1718 (define_split
1719 [(set (match_operand:DI 0 "push_operand" "")
1720 (match_operand:DI 1 "general_operand" ""))]
1721 "!TARGET_64BIT && reload_completed
1722 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1723 [(const_int 0)]
1724 "ix86_split_long_move (operands); DONE;")
1725
1726 (define_insn "*pushsi2"
1727 [(set (match_operand:SI 0 "push_operand" "=<")
1728 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 "!TARGET_64BIT"
1730 "push{l}\t%1"
1731 [(set_attr "type" "push")
1732 (set_attr "mode" "SI")])
1733
1734 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1735 ;; "push a byte/word". But actually we use pushl, which has the effect
1736 ;; of rounding the amount pushed up to a word.
1737
1738 ;; For 64BIT abi we always round up to 8 bytes.
1739 (define_insn "*push<mode>2_rex64"
1740 [(set (match_operand:SWI124 0 "push_operand" "=X")
1741 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1742 "TARGET_64BIT"
1743 "push{q}\t%q1"
1744 [(set_attr "type" "push")
1745 (set_attr "mode" "DI")])
1746
1747 (define_insn "*push<mode>2"
1748 [(set (match_operand:SWI12 0 "push_operand" "=X")
1749 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1750 "!TARGET_64BIT"
1751 "push{l}\t%k1"
1752 [(set_attr "type" "push")
1753 (set_attr "mode" "SI")])
1754
1755 (define_insn "*push<mode>2_prologue"
1756 [(set (match_operand:P 0 "push_operand" "=<")
1757 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1758 (clobber (mem:BLK (scratch)))]
1759 ""
1760 "push{<imodesuffix>}\t%1"
1761 [(set_attr "type" "push")
1762 (set_attr "mode" "<MODE>")])
1763
1764 (define_insn "popdi1"
1765 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1766 (mem:DI (reg:DI SP_REG)))
1767 (set (reg:DI SP_REG)
1768 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1769 "TARGET_64BIT"
1770 "pop{q}\t%0"
1771 [(set_attr "type" "pop")
1772 (set_attr "mode" "DI")])
1773
1774 (define_insn "popsi1"
1775 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1776 (mem:SI (reg:SI SP_REG)))
1777 (set (reg:SI SP_REG)
1778 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1779 "!TARGET_64BIT"
1780 "pop{l}\t%0"
1781 [(set_attr "type" "pop")
1782 (set_attr "mode" "SI")])
1783
1784 (define_insn "*popdi1_epilogue"
1785 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1786 (mem:DI (reg:DI SP_REG)))
1787 (set (reg:DI SP_REG)
1788 (plus:DI (reg:DI SP_REG) (const_int 8)))
1789 (clobber (mem:BLK (scratch)))]
1790 "TARGET_64BIT"
1791 "pop{q}\t%0"
1792 [(set_attr "type" "pop")
1793 (set_attr "mode" "DI")])
1794
1795 (define_insn "*popsi1_epilogue"
1796 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1797 (mem:SI (reg:SI SP_REG)))
1798 (set (reg:SI SP_REG)
1799 (plus:SI (reg:SI SP_REG) (const_int 4)))
1800 (clobber (mem:BLK (scratch)))]
1801 "!TARGET_64BIT"
1802 "pop{l}\t%0"
1803 [(set_attr "type" "pop")
1804 (set_attr "mode" "SI")])
1805
1806 (define_insn "*mov<mode>_xor"
1807 [(set (match_operand:SWI48 0 "register_operand" "=r")
1808 (match_operand:SWI48 1 "const0_operand" ""))
1809 (clobber (reg:CC FLAGS_REG))]
1810 "reload_completed"
1811 "xor{l}\t%k0, %k0"
1812 [(set_attr "type" "alu1")
1813 (set_attr "mode" "SI")
1814 (set_attr "length_immediate" "0")])
1815
1816 (define_insn "*mov<mode>_or"
1817 [(set (match_operand:SWI48 0 "register_operand" "=r")
1818 (match_operand:SWI48 1 "const_int_operand" ""))
1819 (clobber (reg:CC FLAGS_REG))]
1820 "reload_completed
1821 && operands[1] == constm1_rtx"
1822 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1823 [(set_attr "type" "alu1")
1824 (set_attr "mode" "<MODE>")
1825 (set_attr "length_immediate" "1")])
1826
1827 (define_insn "*movoi_internal_avx"
1828 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1829 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1830 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1831 {
1832 switch (which_alternative)
1833 {
1834 case 0:
1835 return "vxorps\t%0, %0, %0";
1836 case 1:
1837 case 2:
1838 if (misaligned_operand (operands[0], OImode)
1839 || misaligned_operand (operands[1], OImode))
1840 return "vmovdqu\t{%1, %0|%0, %1}";
1841 else
1842 return "vmovdqa\t{%1, %0|%0, %1}";
1843 default:
1844 gcc_unreachable ();
1845 }
1846 }
1847 [(set_attr "type" "sselog1,ssemov,ssemov")
1848 (set_attr "prefix" "vex")
1849 (set_attr "mode" "OI")])
1850
1851 (define_insn "*movti_internal_rex64"
1852 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1853 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1854 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1855 {
1856 switch (which_alternative)
1857 {
1858 case 0:
1859 case 1:
1860 return "#";
1861 case 2:
1862 if (get_attr_mode (insn) == MODE_V4SF)
1863 return "%vxorps\t%0, %d0";
1864 else
1865 return "%vpxor\t%0, %d0";
1866 case 3:
1867 case 4:
1868 /* TDmode values are passed as TImode on the stack. Moving them
1869 to stack may result in unaligned memory access. */
1870 if (misaligned_operand (operands[0], TImode)
1871 || misaligned_operand (operands[1], TImode))
1872 {
1873 if (get_attr_mode (insn) == MODE_V4SF)
1874 return "%vmovups\t{%1, %0|%0, %1}";
1875 else
1876 return "%vmovdqu\t{%1, %0|%0, %1}";
1877 }
1878 else
1879 {
1880 if (get_attr_mode (insn) == MODE_V4SF)
1881 return "%vmovaps\t{%1, %0|%0, %1}";
1882 else
1883 return "%vmovdqa\t{%1, %0|%0, %1}";
1884 }
1885 default:
1886 gcc_unreachable ();
1887 }
1888 }
1889 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1890 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1891 (set (attr "mode")
1892 (cond [(eq_attr "alternative" "2,3")
1893 (if_then_else
1894 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1895 (const_int 0))
1896 (const_string "V4SF")
1897 (const_string "TI"))
1898 (eq_attr "alternative" "4")
1899 (if_then_else
1900 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1901 (const_int 0))
1902 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1903 (const_int 0)))
1904 (const_string "V4SF")
1905 (const_string "TI"))]
1906 (const_string "DI")))])
1907
1908 (define_split
1909 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1910 (match_operand:TI 1 "general_operand" ""))]
1911 "reload_completed
1912 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1913 [(const_int 0)]
1914 "ix86_split_long_move (operands); DONE;")
1915
1916 (define_insn "*movti_internal_sse"
1917 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1918 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1919 "TARGET_SSE && !TARGET_64BIT
1920 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1921 {
1922 switch (which_alternative)
1923 {
1924 case 0:
1925 if (get_attr_mode (insn) == MODE_V4SF)
1926 return "%vxorps\t%0, %d0";
1927 else
1928 return "%vpxor\t%0, %d0";
1929 case 1:
1930 case 2:
1931 /* TDmode values are passed as TImode on the stack. Moving them
1932 to stack may result in unaligned memory access. */
1933 if (misaligned_operand (operands[0], TImode)
1934 || misaligned_operand (operands[1], TImode))
1935 {
1936 if (get_attr_mode (insn) == MODE_V4SF)
1937 return "%vmovups\t{%1, %0|%0, %1}";
1938 else
1939 return "%vmovdqu\t{%1, %0|%0, %1}";
1940 }
1941 else
1942 {
1943 if (get_attr_mode (insn) == MODE_V4SF)
1944 return "%vmovaps\t{%1, %0|%0, %1}";
1945 else
1946 return "%vmovdqa\t{%1, %0|%0, %1}";
1947 }
1948 default:
1949 gcc_unreachable ();
1950 }
1951 }
1952 [(set_attr "type" "sselog1,ssemov,ssemov")
1953 (set_attr "prefix" "maybe_vex")
1954 (set (attr "mode")
1955 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1956 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1957 (const_int 0)))
1958 (const_string "V4SF")
1959 (and (eq_attr "alternative" "2")
1960 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1961 (const_int 0)))
1962 (const_string "V4SF")]
1963 (const_string "TI")))])
1964
1965 (define_insn "*movdi_internal_rex64"
1966 [(set (match_operand:DI 0 "nonimmediate_operand"
1967 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1968 (match_operand:DI 1 "general_operand"
1969 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1970 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 {
1972 switch (get_attr_type (insn))
1973 {
1974 case TYPE_SSECVT:
1975 if (SSE_REG_P (operands[0]))
1976 return "movq2dq\t{%1, %0|%0, %1}";
1977 else
1978 return "movdq2q\t{%1, %0|%0, %1}";
1979
1980 case TYPE_SSEMOV:
1981 if (TARGET_AVX)
1982 {
1983 if (get_attr_mode (insn) == MODE_TI)
1984 return "vmovdqa\t{%1, %0|%0, %1}";
1985 else
1986 return "vmovq\t{%1, %0|%0, %1}";
1987 }
1988
1989 if (get_attr_mode (insn) == MODE_TI)
1990 return "movdqa\t{%1, %0|%0, %1}";
1991 /* FALLTHRU */
1992
1993 case TYPE_MMXMOV:
1994 /* Moves from and into integer register is done using movd
1995 opcode with REX prefix. */
1996 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997 return "movd\t{%1, %0|%0, %1}";
1998 return "movq\t{%1, %0|%0, %1}";
1999
2000 case TYPE_SSELOG1:
2001 return "%vpxor\t%0, %d0";
2002
2003 case TYPE_MMX:
2004 return "pxor\t%0, %0";
2005
2006 case TYPE_MULTI:
2007 return "#";
2008
2009 case TYPE_LEA:
2010 return "lea{q}\t{%a1, %0|%0, %a1}";
2011
2012 default:
2013 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2014 if (get_attr_mode (insn) == MODE_SI)
2015 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2016 else if (which_alternative == 2)
2017 return "movabs{q}\t{%1, %0|%0, %1}";
2018 else
2019 return "mov{q}\t{%1, %0|%0, %1}";
2020 }
2021 }
2022 [(set (attr "type")
2023 (cond [(eq_attr "alternative" "5")
2024 (const_string "mmx")
2025 (eq_attr "alternative" "6,7,8,9,10")
2026 (const_string "mmxmov")
2027 (eq_attr "alternative" "11")
2028 (const_string "sselog1")
2029 (eq_attr "alternative" "12,13,14,15,16")
2030 (const_string "ssemov")
2031 (eq_attr "alternative" "17,18")
2032 (const_string "ssecvt")
2033 (eq_attr "alternative" "4")
2034 (const_string "multi")
2035 (match_operand:DI 1 "pic_32bit_operand" "")
2036 (const_string "lea")
2037 ]
2038 (const_string "imov")))
2039 (set (attr "modrm")
2040 (if_then_else
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2042 (const_string "0")
2043 (const_string "*")))
2044 (set (attr "length_immediate")
2045 (if_then_else
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2047 (const_string "8")
2048 (const_string "*")))
2049 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2050 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2051 (set (attr "prefix")
2052 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2053 (const_string "maybe_vex")
2054 (const_string "orig")))
2055 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2056
2057 ;; Convert impossible stores of immediate to existing instructions.
2058 ;; First try to get scratch register and go through it. In case this
2059 ;; fails, move by 32bit parts.
2060 (define_peephole2
2061 [(match_scratch:DI 2 "r")
2062 (set (match_operand:DI 0 "memory_operand" "")
2063 (match_operand:DI 1 "immediate_operand" ""))]
2064 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2065 && !x86_64_immediate_operand (operands[1], DImode)"
2066 [(set (match_dup 2) (match_dup 1))
2067 (set (match_dup 0) (match_dup 2))]
2068 "")
2069
2070 ;; We need to define this as both peepholer and splitter for case
2071 ;; peephole2 pass is not run.
2072 ;; "&& 1" is needed to keep it from matching the previous pattern.
2073 (define_peephole2
2074 [(set (match_operand:DI 0 "memory_operand" "")
2075 (match_operand:DI 1 "immediate_operand" ""))]
2076 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2077 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2078 [(set (match_dup 2) (match_dup 3))
2079 (set (match_dup 4) (match_dup 5))]
2080 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2081
2082 (define_split
2083 [(set (match_operand:DI 0 "memory_operand" "")
2084 (match_operand:DI 1 "immediate_operand" ""))]
2085 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2086 ? epilogue_completed : reload_completed)
2087 && !symbolic_operand (operands[1], DImode)
2088 && !x86_64_immediate_operand (operands[1], DImode)"
2089 [(set (match_dup 2) (match_dup 3))
2090 (set (match_dup 4) (match_dup 5))]
2091 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2092
2093 (define_insn "*movdi_internal"
2094 [(set (match_operand:DI 0 "nonimmediate_operand"
2095 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2096 (match_operand:DI 1 "general_operand"
2097 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2098 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2099 "@
2100 #
2101 #
2102 pxor\t%0, %0
2103 movq\t{%1, %0|%0, %1}
2104 movq\t{%1, %0|%0, %1}
2105 %vpxor\t%0, %d0
2106 %vmovq\t{%1, %0|%0, %1}
2107 %vmovdqa\t{%1, %0|%0, %1}
2108 %vmovq\t{%1, %0|%0, %1}
2109 xorps\t%0, %0
2110 movlps\t{%1, %0|%0, %1}
2111 movaps\t{%1, %0|%0, %1}
2112 movlps\t{%1, %0|%0, %1}"
2113 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2114 (set (attr "prefix")
2115 (if_then_else (eq_attr "alternative" "5,6,7,8")
2116 (const_string "vex")
2117 (const_string "orig")))
2118 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2119
2120 (define_split
2121 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2122 (match_operand:DI 1 "general_operand" ""))]
2123 "!TARGET_64BIT && reload_completed
2124 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2125 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2126 [(const_int 0)]
2127 "ix86_split_long_move (operands); DONE;")
2128
2129 (define_insn "*movsi_internal"
2130 [(set (match_operand:SI 0 "nonimmediate_operand"
2131 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2132 (match_operand:SI 1 "general_operand"
2133 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2134 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2135 {
2136 switch (get_attr_type (insn))
2137 {
2138 case TYPE_SSELOG1:
2139 if (get_attr_mode (insn) == MODE_TI)
2140 return "%vpxor\t%0, %d0";
2141 return "%vxorps\t%0, %d0";
2142
2143 case TYPE_SSEMOV:
2144 switch (get_attr_mode (insn))
2145 {
2146 case MODE_TI:
2147 return "%vmovdqa\t{%1, %0|%0, %1}";
2148 case MODE_V4SF:
2149 return "%vmovaps\t{%1, %0|%0, %1}";
2150 case MODE_SI:
2151 return "%vmovd\t{%1, %0|%0, %1}";
2152 case MODE_SF:
2153 return "%vmovss\t{%1, %0|%0, %1}";
2154 default:
2155 gcc_unreachable ();
2156 }
2157
2158 case TYPE_MMX:
2159 return "pxor\t%0, %0";
2160
2161 case TYPE_MMXMOV:
2162 if (get_attr_mode (insn) == MODE_DI)
2163 return "movq\t{%1, %0|%0, %1}";
2164 return "movd\t{%1, %0|%0, %1}";
2165
2166 case TYPE_LEA:
2167 return "lea{l}\t{%a1, %0|%0, %a1}";
2168
2169 default:
2170 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2171 return "mov{l}\t{%1, %0|%0, %1}";
2172 }
2173 }
2174 [(set (attr "type")
2175 (cond [(eq_attr "alternative" "2")
2176 (const_string "mmx")
2177 (eq_attr "alternative" "3,4,5")
2178 (const_string "mmxmov")
2179 (eq_attr "alternative" "6")
2180 (const_string "sselog1")
2181 (eq_attr "alternative" "7,8,9,10,11")
2182 (const_string "ssemov")
2183 (match_operand:DI 1 "pic_32bit_operand" "")
2184 (const_string "lea")
2185 ]
2186 (const_string "imov")))
2187 (set (attr "prefix")
2188 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2189 (const_string "orig")
2190 (const_string "maybe_vex")))
2191 (set (attr "prefix_data16")
2192 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2193 (const_string "1")
2194 (const_string "*")))
2195 (set (attr "mode")
2196 (cond [(eq_attr "alternative" "2,3")
2197 (const_string "DI")
2198 (eq_attr "alternative" "6,7")
2199 (if_then_else
2200 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2201 (const_string "V4SF")
2202 (const_string "TI"))
2203 (and (eq_attr "alternative" "8,9,10,11")
2204 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2205 (const_string "SF")
2206 ]
2207 (const_string "SI")))])
2208
2209 (define_insn "*movhi_internal"
2210 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2211 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2212 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2213 {
2214 switch (get_attr_type (insn))
2215 {
2216 case TYPE_IMOVX:
2217 /* movzwl is faster than movw on p2 due to partial word stalls,
2218 though not as fast as an aligned movl. */
2219 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2220 default:
2221 if (get_attr_mode (insn) == MODE_SI)
2222 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2223 else
2224 return "mov{w}\t{%1, %0|%0, %1}";
2225 }
2226 }
2227 [(set (attr "type")
2228 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2229 (const_int 0))
2230 (const_string "imov")
2231 (and (eq_attr "alternative" "0")
2232 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2233 (const_int 0))
2234 (eq (symbol_ref "TARGET_HIMODE_MATH")
2235 (const_int 0))))
2236 (const_string "imov")
2237 (and (eq_attr "alternative" "1,2")
2238 (match_operand:HI 1 "aligned_operand" ""))
2239 (const_string "imov")
2240 (and (ne (symbol_ref "TARGET_MOVX")
2241 (const_int 0))
2242 (eq_attr "alternative" "0,2"))
2243 (const_string "imovx")
2244 ]
2245 (const_string "imov")))
2246 (set (attr "mode")
2247 (cond [(eq_attr "type" "imovx")
2248 (const_string "SI")
2249 (and (eq_attr "alternative" "1,2")
2250 (match_operand:HI 1 "aligned_operand" ""))
2251 (const_string "SI")
2252 (and (eq_attr "alternative" "0")
2253 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2254 (const_int 0))
2255 (eq (symbol_ref "TARGET_HIMODE_MATH")
2256 (const_int 0))))
2257 (const_string "SI")
2258 ]
2259 (const_string "HI")))])
2260
2261 ;; Situation is quite tricky about when to choose full sized (SImode) move
2262 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2263 ;; partial register dependency machines (such as AMD Athlon), where QImode
2264 ;; moves issue extra dependency and for partial register stalls machines
2265 ;; that don't use QImode patterns (and QImode move cause stall on the next
2266 ;; instruction).
2267 ;;
2268 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2269 ;; register stall machines with, where we use QImode instructions, since
2270 ;; partial register stall can be caused there. Then we use movzx.
2271 (define_insn "*movqi_internal"
2272 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2273 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2274 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2275 {
2276 switch (get_attr_type (insn))
2277 {
2278 case TYPE_IMOVX:
2279 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2280 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2281 default:
2282 if (get_attr_mode (insn) == MODE_SI)
2283 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2284 else
2285 return "mov{b}\t{%1, %0|%0, %1}";
2286 }
2287 }
2288 [(set (attr "type")
2289 (cond [(and (eq_attr "alternative" "5")
2290 (not (match_operand:QI 1 "aligned_operand" "")))
2291 (const_string "imovx")
2292 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2293 (const_int 0))
2294 (const_string "imov")
2295 (and (eq_attr "alternative" "3")
2296 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2297 (const_int 0))
2298 (eq (symbol_ref "TARGET_QIMODE_MATH")
2299 (const_int 0))))
2300 (const_string "imov")
2301 (eq_attr "alternative" "3,5")
2302 (const_string "imovx")
2303 (and (ne (symbol_ref "TARGET_MOVX")
2304 (const_int 0))
2305 (eq_attr "alternative" "2"))
2306 (const_string "imovx")
2307 ]
2308 (const_string "imov")))
2309 (set (attr "mode")
2310 (cond [(eq_attr "alternative" "3,4,5")
2311 (const_string "SI")
2312 (eq_attr "alternative" "6")
2313 (const_string "QI")
2314 (eq_attr "type" "imovx")
2315 (const_string "SI")
2316 (and (eq_attr "type" "imov")
2317 (and (eq_attr "alternative" "0,1")
2318 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2319 (const_int 0))
2320 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2321 (const_int 0))
2322 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2323 (const_int 0))))))
2324 (const_string "SI")
2325 ;; Avoid partial register stalls when not using QImode arithmetic
2326 (and (eq_attr "type" "imov")
2327 (and (eq_attr "alternative" "0,1")
2328 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2329 (const_int 0))
2330 (eq (symbol_ref "TARGET_QIMODE_MATH")
2331 (const_int 0)))))
2332 (const_string "SI")
2333 ]
2334 (const_string "QI")))])
2335
2336 ;; Stores and loads of ax to arbitrary constant address.
2337 ;; We fake an second form of instruction to force reload to load address
2338 ;; into register when rax is not available
2339 (define_insn "*movabs<mode>_1"
2340 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2341 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2342 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2343 "@
2344 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2345 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2346 [(set_attr "type" "imov")
2347 (set_attr "modrm" "0,*")
2348 (set_attr "length_address" "8,0")
2349 (set_attr "length_immediate" "0,*")
2350 (set_attr "memory" "store")
2351 (set_attr "mode" "<MODE>")])
2352
2353 (define_insn "*movabs<mode>_2"
2354 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2355 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2356 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2357 "@
2358 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2359 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2360 [(set_attr "type" "imov")
2361 (set_attr "modrm" "0,*")
2362 (set_attr "length_address" "8,0")
2363 (set_attr "length_immediate" "0")
2364 (set_attr "memory" "load")
2365 (set_attr "mode" "<MODE>")])
2366
2367 (define_insn "*swap<mode>"
2368 [(set (match_operand:SWI48 0 "register_operand" "+r")
2369 (match_operand:SWI48 1 "register_operand" "+r"))
2370 (set (match_dup 1)
2371 (match_dup 0))]
2372 ""
2373 "xchg{<imodesuffix>}\t%1, %0"
2374 [(set_attr "type" "imov")
2375 (set_attr "mode" "<MODE>")
2376 (set_attr "pent_pair" "np")
2377 (set_attr "athlon_decode" "vector")
2378 (set_attr "amdfam10_decode" "double")])
2379
2380 (define_insn "*swap<mode>_1"
2381 [(set (match_operand:SWI12 0 "register_operand" "+r")
2382 (match_operand:SWI12 1 "register_operand" "+r"))
2383 (set (match_dup 1)
2384 (match_dup 0))]
2385 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2386 "xchg{l}\t%k1, %k0"
2387 [(set_attr "type" "imov")
2388 (set_attr "mode" "SI")
2389 (set_attr "pent_pair" "np")
2390 (set_attr "athlon_decode" "vector")
2391 (set_attr "amdfam10_decode" "double")])
2392
2393 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2394 ;; is disabled for AMDFAM10
2395 (define_insn "*swap<mode>_2"
2396 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2397 (match_operand:SWI12 1 "register_operand" "+<r>"))
2398 (set (match_dup 1)
2399 (match_dup 0))]
2400 "TARGET_PARTIAL_REG_STALL"
2401 "xchg{<imodesuffix>}\t%1, %0"
2402 [(set_attr "type" "imov")
2403 (set_attr "mode" "<MODE>")
2404 (set_attr "pent_pair" "np")
2405 (set_attr "athlon_decode" "vector")])
2406
2407 (define_expand "movstrict<mode>"
2408 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2409 (match_operand:SWI12 1 "general_operand" ""))]
2410 ""
2411 {
2412 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2413 FAIL;
2414 /* Don't generate memory->memory moves, go through a register */
2415 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2416 operands[1] = force_reg (<MODE>mode, operands[1]);
2417 })
2418
2419 (define_insn "*movstrict<mode>_1"
2420 [(set (strict_low_part
2421 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2422 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2423 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2424 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2425 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2426 [(set_attr "type" "imov")
2427 (set_attr "mode" "<MODE>")])
2428
2429 (define_insn "*movstrict<mode>_xor"
2430 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2431 (match_operand:SWI12 1 "const0_operand" ""))
2432 (clobber (reg:CC FLAGS_REG))]
2433 "reload_completed"
2434 "xor{<imodesuffix>}\t%0, %0"
2435 [(set_attr "type" "alu1")
2436 (set_attr "mode" "<MODE>")
2437 (set_attr "length_immediate" "0")])
2438
2439 (define_insn "*mov<mode>_extv_1"
2440 [(set (match_operand:SWI24 0 "register_operand" "=R")
2441 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2442 (const_int 8)
2443 (const_int 8)))]
2444 ""
2445 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2446 [(set_attr "type" "imovx")
2447 (set_attr "mode" "SI")])
2448
2449 (define_insn "*movqi_extv_1_rex64"
2450 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2451 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2452 (const_int 8)
2453 (const_int 8)))]
2454 "TARGET_64BIT"
2455 {
2456 switch (get_attr_type (insn))
2457 {
2458 case TYPE_IMOVX:
2459 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2460 default:
2461 return "mov{b}\t{%h1, %0|%0, %h1}";
2462 }
2463 }
2464 [(set (attr "type")
2465 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2466 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2467 (ne (symbol_ref "TARGET_MOVX")
2468 (const_int 0))))
2469 (const_string "imovx")
2470 (const_string "imov")))
2471 (set (attr "mode")
2472 (if_then_else (eq_attr "type" "imovx")
2473 (const_string "SI")
2474 (const_string "QI")))])
2475
2476 (define_insn "*movqi_extv_1"
2477 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2478 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2479 (const_int 8)
2480 (const_int 8)))]
2481 "!TARGET_64BIT"
2482 {
2483 switch (get_attr_type (insn))
2484 {
2485 case TYPE_IMOVX:
2486 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2487 default:
2488 return "mov{b}\t{%h1, %0|%0, %h1}";
2489 }
2490 }
2491 [(set (attr "type")
2492 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2493 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2494 (ne (symbol_ref "TARGET_MOVX")
2495 (const_int 0))))
2496 (const_string "imovx")
2497 (const_string "imov")))
2498 (set (attr "mode")
2499 (if_then_else (eq_attr "type" "imovx")
2500 (const_string "SI")
2501 (const_string "QI")))])
2502
2503 (define_insn "*mov<mode>_extzv_1"
2504 [(set (match_operand:SWI48 0 "register_operand" "=R")
2505 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2506 (const_int 8)
2507 (const_int 8)))]
2508 ""
2509 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2510 [(set_attr "type" "imovx")
2511 (set_attr "mode" "SI")])
2512
2513 (define_insn "*movqi_extzv_2_rex64"
2514 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2515 (subreg:QI
2516 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2517 (const_int 8)
2518 (const_int 8)) 0))]
2519 "TARGET_64BIT"
2520 {
2521 switch (get_attr_type (insn))
2522 {
2523 case TYPE_IMOVX:
2524 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2525 default:
2526 return "mov{b}\t{%h1, %0|%0, %h1}";
2527 }
2528 }
2529 [(set (attr "type")
2530 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2531 (ne (symbol_ref "TARGET_MOVX")
2532 (const_int 0)))
2533 (const_string "imovx")
2534 (const_string "imov")))
2535 (set (attr "mode")
2536 (if_then_else (eq_attr "type" "imovx")
2537 (const_string "SI")
2538 (const_string "QI")))])
2539
2540 (define_insn "*movqi_extzv_2"
2541 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2542 (subreg:QI
2543 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2544 (const_int 8)
2545 (const_int 8)) 0))]
2546 "!TARGET_64BIT"
2547 {
2548 switch (get_attr_type (insn))
2549 {
2550 case TYPE_IMOVX:
2551 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2552 default:
2553 return "mov{b}\t{%h1, %0|%0, %h1}";
2554 }
2555 }
2556 [(set (attr "type")
2557 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2558 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2559 (ne (symbol_ref "TARGET_MOVX")
2560 (const_int 0))))
2561 (const_string "imovx")
2562 (const_string "imov")))
2563 (set (attr "mode")
2564 (if_then_else (eq_attr "type" "imovx")
2565 (const_string "SI")
2566 (const_string "QI")))])
2567
2568 (define_expand "mov<mode>_insv_1"
2569 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2570 (const_int 8)
2571 (const_int 8))
2572 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2573 ""
2574 "")
2575
2576 (define_insn "*mov<mode>_insv_1_rex64"
2577 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2578 (const_int 8)
2579 (const_int 8))
2580 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2581 "TARGET_64BIT"
2582 "mov{b}\t{%b1, %h0|%h0, %b1}"
2583 [(set_attr "type" "imov")
2584 (set_attr "mode" "QI")])
2585
2586 (define_insn "*movsi_insv_1"
2587 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2588 (const_int 8)
2589 (const_int 8))
2590 (match_operand:SI 1 "general_operand" "Qmn"))]
2591 "!TARGET_64BIT"
2592 "mov{b}\t{%b1, %h0|%h0, %b1}"
2593 [(set_attr "type" "imov")
2594 (set_attr "mode" "QI")])
2595
2596 (define_insn "*movqi_insv_2"
2597 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2598 (const_int 8)
2599 (const_int 8))
2600 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2601 (const_int 8)))]
2602 ""
2603 "mov{b}\t{%h1, %h0|%h0, %h1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2606 \f
2607 ;; Floating point move instructions.
2608
2609 (define_expand "movtf"
2610 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2611 (match_operand:TF 1 "nonimmediate_operand" ""))]
2612 "TARGET_SSE2"
2613 {
2614 ix86_expand_move (TFmode, operands);
2615 DONE;
2616 })
2617
2618 (define_expand "mov<mode>"
2619 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2620 (match_operand:X87MODEF 1 "general_operand" ""))]
2621 ""
2622 "ix86_expand_move (<MODE>mode, operands); DONE;")
2623
2624 (define_insn "*pushtf"
2625 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2626 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2627 "TARGET_SSE2"
2628 {
2629 /* This insn should be already split before reg-stack. */
2630 gcc_unreachable ();
2631 }
2632 [(set_attr "type" "multi")
2633 (set_attr "unit" "sse,*,*")
2634 (set_attr "mode" "TF,SI,SI")])
2635
2636 (define_split
2637 [(set (match_operand:TF 0 "push_operand" "")
2638 (match_operand:TF 1 "general_operand" ""))]
2639 "TARGET_SSE2 && reload_completed
2640 && !SSE_REG_P (operands[1])"
2641 [(const_int 0)]
2642 "ix86_split_long_move (operands); DONE;")
2643
2644 (define_split
2645 [(set (match_operand:TF 0 "push_operand" "")
2646 (match_operand:TF 1 "any_fp_register_operand" ""))]
2647 "TARGET_SSE2"
2648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
2650 "")
2651
2652 (define_insn "*pushxf"
2653 [(set (match_operand:XF 0 "push_operand" "=<,<")
2654 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2655 "optimize_function_for_speed_p (cfun)"
2656 {
2657 /* This insn should be already split before reg-stack. */
2658 gcc_unreachable ();
2659 }
2660 [(set_attr "type" "multi")
2661 (set_attr "unit" "i387,*")
2662 (set_attr "mode" "XF,SI")])
2663
2664 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2665 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2666 ;; Pushing using integer instructions is longer except for constants
2667 ;; and direct memory references (assuming that any given constant is pushed
2668 ;; only once, but this ought to be handled elsewhere).
2669
2670 (define_insn "*pushxf_nointeger"
2671 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2672 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2673 "optimize_function_for_size_p (cfun)"
2674 {
2675 /* This insn should be already split before reg-stack. */
2676 gcc_unreachable ();
2677 }
2678 [(set_attr "type" "multi")
2679 (set_attr "unit" "i387,*,*")
2680 (set_attr "mode" "XF,SI,SI")])
2681
2682 (define_split
2683 [(set (match_operand:XF 0 "push_operand" "")
2684 (match_operand:XF 1 "any_fp_register_operand" ""))]
2685 "reload_completed"
2686 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2687 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2688 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2689
2690 (define_split
2691 [(set (match_operand:XF 0 "push_operand" "")
2692 (match_operand:XF 1 "general_operand" ""))]
2693 "reload_completed
2694 && !ANY_FP_REG_P (operands[1])"
2695 [(const_int 0)]
2696 "ix86_split_long_move (operands); DONE;")
2697
2698 (define_insn "*pushdf"
2699 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2700 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2701 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2702 {
2703 /* This insn should be already split before reg-stack. */
2704 gcc_unreachable ();
2705 }
2706 [(set_attr "type" "multi")
2707 (set_attr "unit" "i387,*,*")
2708 (set_attr "mode" "DF,SI,DF")])
2709
2710 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2711 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2712 ;; On the average, pushdf using integers can be still shorter. Allow this
2713 ;; pattern for optimize_size too.
2714
2715 (define_insn "*pushdf_nointeger"
2716 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2717 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2718 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2719 {
2720 /* This insn should be already split before reg-stack. */
2721 gcc_unreachable ();
2722 }
2723 [(set_attr "type" "multi")
2724 (set_attr "unit" "i387,*,*,*")
2725 (set_attr "mode" "DF,SI,SI,DF")])
2726
2727 ;; %%% Kill this when call knows how to work this out.
2728 (define_split
2729 [(set (match_operand:DF 0 "push_operand" "")
2730 (match_operand:DF 1 "any_fp_register_operand" ""))]
2731 "reload_completed"
2732 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2733 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2734 "")
2735
2736 (define_split
2737 [(set (match_operand:DF 0 "push_operand" "")
2738 (match_operand:DF 1 "general_operand" ""))]
2739 "reload_completed
2740 && !ANY_FP_REG_P (operands[1])"
2741 [(const_int 0)]
2742 "ix86_split_long_move (operands); DONE;")
2743
2744 (define_insn "*pushsf_rex64"
2745 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2746 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2747 "TARGET_64BIT"
2748 {
2749 /* Anything else should be already split before reg-stack. */
2750 gcc_assert (which_alternative == 1);
2751 return "push{q}\t%q1";
2752 }
2753 [(set_attr "type" "multi,push,multi")
2754 (set_attr "unit" "i387,*,*")
2755 (set_attr "mode" "SF,DI,SF")])
2756
2757 (define_insn "*pushsf"
2758 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2759 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2760 "!TARGET_64BIT"
2761 {
2762 /* Anything else should be already split before reg-stack. */
2763 gcc_assert (which_alternative == 1);
2764 return "push{l}\t%1";
2765 }
2766 [(set_attr "type" "multi,push,multi")
2767 (set_attr "unit" "i387,*,*")
2768 (set_attr "mode" "SF,SI,SF")])
2769
2770 (define_split
2771 [(set (match_operand:SF 0 "push_operand" "")
2772 (match_operand:SF 1 "memory_operand" ""))]
2773 "reload_completed
2774 && MEM_P (operands[1])
2775 && (operands[2] = find_constant_src (insn))"
2776 [(set (match_dup 0)
2777 (match_dup 2))])
2778
2779 ;; %%% Kill this when call knows how to work this out.
2780 (define_split
2781 [(set (match_operand:SF 0 "push_operand" "")
2782 (match_operand:SF 1 "any_fp_register_operand" ""))]
2783 "reload_completed"
2784 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2785 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2786 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2787
2788 (define_insn "*movtf_internal"
2789 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2790 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2791 "TARGET_SSE2
2792 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2793 {
2794 switch (which_alternative)
2795 {
2796 case 0:
2797 case 1:
2798 if (get_attr_mode (insn) == MODE_V4SF)
2799 return "%vmovaps\t{%1, %0|%0, %1}";
2800 else
2801 return "%vmovdqa\t{%1, %0|%0, %1}";
2802 case 2:
2803 if (get_attr_mode (insn) == MODE_V4SF)
2804 return "%vxorps\t%0, %d0";
2805 else
2806 return "%vpxor\t%0, %d0";
2807 case 3:
2808 case 4:
2809 return "#";
2810 default:
2811 gcc_unreachable ();
2812 }
2813 }
2814 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2815 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2816 (set (attr "mode")
2817 (cond [(eq_attr "alternative" "0,2")
2818 (if_then_else
2819 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2820 (const_int 0))
2821 (const_string "V4SF")
2822 (const_string "TI"))
2823 (eq_attr "alternative" "1")
2824 (if_then_else
2825 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2826 (const_int 0))
2827 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2828 (const_int 0)))
2829 (const_string "V4SF")
2830 (const_string "TI"))]
2831 (const_string "DI")))])
2832
2833 (define_split
2834 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2835 (match_operand:TF 1 "general_operand" ""))]
2836 "reload_completed
2837 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2838 [(const_int 0)]
2839 "ix86_split_long_move (operands); DONE;")
2840
2841 (define_insn "*movxf_internal"
2842 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2843 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2844 "optimize_function_for_speed_p (cfun)
2845 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2846 && (reload_in_progress || reload_completed
2847 || GET_CODE (operands[1]) != CONST_DOUBLE
2848 || memory_operand (operands[0], XFmode))"
2849 {
2850 switch (which_alternative)
2851 {
2852 case 0:
2853 case 1:
2854 return output_387_reg_move (insn, operands);
2855
2856 case 2:
2857 return standard_80387_constant_opcode (operands[1]);
2858
2859 case 3: case 4:
2860 return "#";
2861
2862 default:
2863 gcc_unreachable ();
2864 }
2865 }
2866 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2867 (set_attr "mode" "XF,XF,XF,SI,SI")])
2868
2869 ;; Do not use integer registers when optimizing for size
2870 (define_insn "*movxf_internal_nointeger"
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2872 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2873 "optimize_function_for_size_p (cfun)
2874 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2875 && (reload_in_progress || reload_completed
2876 || standard_80387_constant_p (operands[1])
2877 || GET_CODE (operands[1]) != CONST_DOUBLE
2878 || memory_operand (operands[0], XFmode))"
2879 {
2880 switch (which_alternative)
2881 {
2882 case 0:
2883 case 1:
2884 return output_387_reg_move (insn, operands);
2885
2886 case 2:
2887 return standard_80387_constant_opcode (operands[1]);
2888
2889 case 3: case 4:
2890 return "#";
2891 default:
2892 gcc_unreachable ();
2893 }
2894 }
2895 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2896 (set_attr "mode" "XF,XF,XF,SI,SI")])
2897
2898 (define_split
2899 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900 (match_operand:XF 1 "general_operand" ""))]
2901 "reload_completed
2902 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2903 && ! (ANY_FP_REG_P (operands[0]) ||
2904 (GET_CODE (operands[0]) == SUBREG
2905 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2906 && ! (ANY_FP_REG_P (operands[1]) ||
2907 (GET_CODE (operands[1]) == SUBREG
2908 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2909 [(const_int 0)]
2910 "ix86_split_long_move (operands); DONE;")
2911
2912 (define_insn "*movdf_internal_rex64"
2913 [(set (match_operand:DF 0 "nonimmediate_operand"
2914 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2915 (match_operand:DF 1 "general_operand"
2916 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2917 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2918 && (reload_in_progress || reload_completed
2919 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2920 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2921 && optimize_function_for_size_p (cfun)
2922 && standard_80387_constant_p (operands[1]))
2923 || GET_CODE (operands[1]) != CONST_DOUBLE
2924 || memory_operand (operands[0], DFmode))"
2925 {
2926 switch (which_alternative)
2927 {
2928 case 0:
2929 case 1:
2930 return output_387_reg_move (insn, operands);
2931
2932 case 2:
2933 return standard_80387_constant_opcode (operands[1]);
2934
2935 case 3:
2936 case 4:
2937 return "#";
2938
2939 case 5:
2940 switch (get_attr_mode (insn))
2941 {
2942 case MODE_V4SF:
2943 return "%vxorps\t%0, %d0";
2944 case MODE_V2DF:
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vxorps\t%0, %d0";
2947 else
2948 return "%vxorpd\t%0, %d0";
2949 case MODE_TI:
2950 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2951 return "%vxorps\t%0, %d0";
2952 else
2953 return "%vpxor\t%0, %d0";
2954 default:
2955 gcc_unreachable ();
2956 }
2957 case 6:
2958 case 7:
2959 case 8:
2960 switch (get_attr_mode (insn))
2961 {
2962 case MODE_V4SF:
2963 return "%vmovaps\t{%1, %0|%0, %1}";
2964 case MODE_V2DF:
2965 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2966 return "%vmovaps\t{%1, %0|%0, %1}";
2967 else
2968 return "%vmovapd\t{%1, %0|%0, %1}";
2969 case MODE_TI:
2970 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2971 return "%vmovaps\t{%1, %0|%0, %1}";
2972 else
2973 return "%vmovdqa\t{%1, %0|%0, %1}";
2974 case MODE_DI:
2975 return "%vmovq\t{%1, %0|%0, %1}";
2976 case MODE_DF:
2977 if (TARGET_AVX)
2978 {
2979 if (REG_P (operands[0]) && REG_P (operands[1]))
2980 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2981 else
2982 return "vmovsd\t{%1, %0|%0, %1}";
2983 }
2984 else
2985 return "movsd\t{%1, %0|%0, %1}";
2986 case MODE_V1DF:
2987 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2988 case MODE_V2SF:
2989 return "%vmovlps\t{%1, %d0|%d0, %1}";
2990 default:
2991 gcc_unreachable ();
2992 }
2993
2994 case 9:
2995 case 10:
2996 return "%vmovd\t{%1, %0|%0, %1}";
2997
2998 default:
2999 gcc_unreachable();
3000 }
3001 }
3002 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3003 (set (attr "prefix")
3004 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3005 (const_string "orig")
3006 (const_string "maybe_vex")))
3007 (set (attr "prefix_data16")
3008 (if_then_else (eq_attr "mode" "V1DF")
3009 (const_string "1")
3010 (const_string "*")))
3011 (set (attr "mode")
3012 (cond [(eq_attr "alternative" "0,1,2")
3013 (const_string "DF")
3014 (eq_attr "alternative" "3,4,9,10")
3015 (const_string "DI")
3016
3017 /* For SSE1, we have many fewer alternatives. */
3018 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3019 (cond [(eq_attr "alternative" "5,6")
3020 (const_string "V4SF")
3021 ]
3022 (const_string "V2SF"))
3023
3024 /* xorps is one byte shorter. */
3025 (eq_attr "alternative" "5")
3026 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3027 (const_int 0))
3028 (const_string "V4SF")
3029 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3030 (const_int 0))
3031 (const_string "TI")
3032 ]
3033 (const_string "V2DF"))
3034
3035 /* For architectures resolving dependencies on
3036 whole SSE registers use APD move to break dependency
3037 chains, otherwise use short move to avoid extra work.
3038
3039 movaps encodes one byte shorter. */
3040 (eq_attr "alternative" "6")
3041 (cond
3042 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3043 (const_int 0))
3044 (const_string "V4SF")
3045 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3046 (const_int 0))
3047 (const_string "V2DF")
3048 ]
3049 (const_string "DF"))
3050 /* For architectures resolving dependencies on register
3051 parts we may avoid extra work to zero out upper part
3052 of register. */
3053 (eq_attr "alternative" "7")
3054 (if_then_else
3055 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3056 (const_int 0))
3057 (const_string "V1DF")
3058 (const_string "DF"))
3059 ]
3060 (const_string "DF")))])
3061
3062 (define_insn "*movdf_internal"
3063 [(set (match_operand:DF 0 "nonimmediate_operand"
3064 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3065 (match_operand:DF 1 "general_operand"
3066 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3067 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3068 && optimize_function_for_speed_p (cfun)
3069 && TARGET_INTEGER_DFMODE_MOVES
3070 && (reload_in_progress || reload_completed
3071 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3072 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3073 && optimize_function_for_size_p (cfun)
3074 && standard_80387_constant_p (operands[1]))
3075 || GET_CODE (operands[1]) != CONST_DOUBLE
3076 || memory_operand (operands[0], DFmode))"
3077 {
3078 switch (which_alternative)
3079 {
3080 case 0:
3081 case 1:
3082 return output_387_reg_move (insn, operands);
3083
3084 case 2:
3085 return standard_80387_constant_opcode (operands[1]);
3086
3087 case 3:
3088 case 4:
3089 return "#";
3090
3091 case 5:
3092 switch (get_attr_mode (insn))
3093 {
3094 case MODE_V4SF:
3095 return "xorps\t%0, %0";
3096 case MODE_V2DF:
3097 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098 return "xorps\t%0, %0";
3099 else
3100 return "xorpd\t%0, %0";
3101 case MODE_TI:
3102 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3103 return "xorps\t%0, %0";
3104 else
3105 return "pxor\t%0, %0";
3106 default:
3107 gcc_unreachable ();
3108 }
3109 case 6:
3110 case 7:
3111 case 8:
3112 switch (get_attr_mode (insn))
3113 {
3114 case MODE_V4SF:
3115 return "movaps\t{%1, %0|%0, %1}";
3116 case MODE_V2DF:
3117 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3118 return "movaps\t{%1, %0|%0, %1}";
3119 else
3120 return "movapd\t{%1, %0|%0, %1}";
3121 case MODE_TI:
3122 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3123 return "movaps\t{%1, %0|%0, %1}";
3124 else
3125 return "movdqa\t{%1, %0|%0, %1}";
3126 case MODE_DI:
3127 return "movq\t{%1, %0|%0, %1}";
3128 case MODE_DF:
3129 return "movsd\t{%1, %0|%0, %1}";
3130 case MODE_V1DF:
3131 return "movlpd\t{%1, %0|%0, %1}";
3132 case MODE_V2SF:
3133 return "movlps\t{%1, %0|%0, %1}";
3134 default:
3135 gcc_unreachable ();
3136 }
3137
3138 default:
3139 gcc_unreachable();
3140 }
3141 }
3142 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3143 (set (attr "prefix_data16")
3144 (if_then_else (eq_attr "mode" "V1DF")
3145 (const_string "1")
3146 (const_string "*")))
3147 (set (attr "mode")
3148 (cond [(eq_attr "alternative" "0,1,2")
3149 (const_string "DF")
3150 (eq_attr "alternative" "3,4")
3151 (const_string "SI")
3152
3153 /* For SSE1, we have many fewer alternatives. */
3154 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3155 (cond [(eq_attr "alternative" "5,6")
3156 (const_string "V4SF")
3157 ]
3158 (const_string "V2SF"))
3159
3160 /* xorps is one byte shorter. */
3161 (eq_attr "alternative" "5")
3162 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3163 (const_int 0))
3164 (const_string "V4SF")
3165 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3166 (const_int 0))
3167 (const_string "TI")
3168 ]
3169 (const_string "V2DF"))
3170
3171 /* For architectures resolving dependencies on
3172 whole SSE registers use APD move to break dependency
3173 chains, otherwise use short move to avoid extra work.
3174
3175 movaps encodes one byte shorter. */
3176 (eq_attr "alternative" "6")
3177 (cond
3178 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3179 (const_int 0))
3180 (const_string "V4SF")
3181 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3182 (const_int 0))
3183 (const_string "V2DF")
3184 ]
3185 (const_string "DF"))
3186 /* For architectures resolving dependencies on register
3187 parts we may avoid extra work to zero out upper part
3188 of register. */
3189 (eq_attr "alternative" "7")
3190 (if_then_else
3191 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3192 (const_int 0))
3193 (const_string "V1DF")
3194 (const_string "DF"))
3195 ]
3196 (const_string "DF")))])
3197
3198 ;; Moving is usually shorter when only FP registers are used. This separate
3199 ;; movdf pattern avoids the use of integer registers for FP operations
3200 ;; when optimizing for size.
3201
3202 (define_insn "*movdf_internal_nointeger"
3203 [(set (match_operand:DF 0 "nonimmediate_operand"
3204 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3205 (match_operand:DF 1 "general_operand"
3206 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3207 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208 && ((optimize_function_for_size_p (cfun)
3209 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3210 && (reload_in_progress || reload_completed
3211 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3212 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3213 && optimize_function_for_size_p (cfun)
3214 && !memory_operand (operands[0], DFmode)
3215 && standard_80387_constant_p (operands[1]))
3216 || GET_CODE (operands[1]) != CONST_DOUBLE
3217 || ((optimize_function_for_size_p (cfun)
3218 || !TARGET_MEMORY_MISMATCH_STALL
3219 || reload_in_progress || reload_completed)
3220 && memory_operand (operands[0], DFmode)))"
3221 {
3222 switch (which_alternative)
3223 {
3224 case 0:
3225 case 1:
3226 return output_387_reg_move (insn, operands);
3227
3228 case 2:
3229 return standard_80387_constant_opcode (operands[1]);
3230
3231 case 3:
3232 case 4:
3233 return "#";
3234 case 5:
3235 switch (get_attr_mode (insn))
3236 {
3237 case MODE_V4SF:
3238 return "%vxorps\t%0, %d0";
3239 case MODE_V2DF:
3240 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3241 return "%vxorps\t%0, %d0";
3242 else
3243 return "%vxorpd\t%0, %d0";
3244 case MODE_TI:
3245 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3246 return "%vxorps\t%0, %d0";
3247 else
3248 return "%vpxor\t%0, %d0";
3249 default:
3250 gcc_unreachable ();
3251 }
3252 case 6:
3253 case 7:
3254 case 8:
3255 switch (get_attr_mode (insn))
3256 {
3257 case MODE_V4SF:
3258 return "%vmovaps\t{%1, %0|%0, %1}";
3259 case MODE_V2DF:
3260 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3261 return "%vmovaps\t{%1, %0|%0, %1}";
3262 else
3263 return "%vmovapd\t{%1, %0|%0, %1}";
3264 case MODE_TI:
3265 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3266 return "%vmovaps\t{%1, %0|%0, %1}";
3267 else
3268 return "%vmovdqa\t{%1, %0|%0, %1}";
3269 case MODE_DI:
3270 return "%vmovq\t{%1, %0|%0, %1}";
3271 case MODE_DF:
3272 if (TARGET_AVX)
3273 {
3274 if (REG_P (operands[0]) && REG_P (operands[1]))
3275 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3276 else
3277 return "vmovsd\t{%1, %0|%0, %1}";
3278 }
3279 else
3280 return "movsd\t{%1, %0|%0, %1}";
3281 case MODE_V1DF:
3282 if (TARGET_AVX)
3283 {
3284 if (REG_P (operands[0]))
3285 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3286 else
3287 return "vmovlpd\t{%1, %0|%0, %1}";
3288 }
3289 else
3290 return "movlpd\t{%1, %0|%0, %1}";
3291 case MODE_V2SF:
3292 if (TARGET_AVX)
3293 {
3294 if (REG_P (operands[0]))
3295 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3296 else
3297 return "vmovlps\t{%1, %0|%0, %1}";
3298 }
3299 else
3300 return "movlps\t{%1, %0|%0, %1}";
3301 default:
3302 gcc_unreachable ();
3303 }
3304
3305 default:
3306 gcc_unreachable ();
3307 }
3308 }
3309 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3310 (set (attr "prefix")
3311 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3312 (const_string "orig")
3313 (const_string "maybe_vex")))
3314 (set (attr "prefix_data16")
3315 (if_then_else (eq_attr "mode" "V1DF")
3316 (const_string "1")
3317 (const_string "*")))
3318 (set (attr "mode")
3319 (cond [(eq_attr "alternative" "0,1,2")
3320 (const_string "DF")
3321 (eq_attr "alternative" "3,4")
3322 (const_string "SI")
3323
3324 /* For SSE1, we have many fewer alternatives. */
3325 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3326 (cond [(eq_attr "alternative" "5,6")
3327 (const_string "V4SF")
3328 ]
3329 (const_string "V2SF"))
3330
3331 /* xorps is one byte shorter. */
3332 (eq_attr "alternative" "5")
3333 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3334 (const_int 0))
3335 (const_string "V4SF")
3336 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3337 (const_int 0))
3338 (const_string "TI")
3339 ]
3340 (const_string "V2DF"))
3341
3342 /* For architectures resolving dependencies on
3343 whole SSE registers use APD move to break dependency
3344 chains, otherwise use short move to avoid extra work.
3345
3346 movaps encodes one byte shorter. */
3347 (eq_attr "alternative" "6")
3348 (cond
3349 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3350 (const_int 0))
3351 (const_string "V4SF")
3352 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3353 (const_int 0))
3354 (const_string "V2DF")
3355 ]
3356 (const_string "DF"))
3357 /* For architectures resolving dependencies on register
3358 parts we may avoid extra work to zero out upper part
3359 of register. */
3360 (eq_attr "alternative" "7")
3361 (if_then_else
3362 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3363 (const_int 0))
3364 (const_string "V1DF")
3365 (const_string "DF"))
3366 ]
3367 (const_string "DF")))])
3368
3369 (define_split
3370 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3371 (match_operand:DF 1 "general_operand" ""))]
3372 "reload_completed
3373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3374 && ! (ANY_FP_REG_P (operands[0]) ||
3375 (GET_CODE (operands[0]) == SUBREG
3376 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3377 && ! (ANY_FP_REG_P (operands[1]) ||
3378 (GET_CODE (operands[1]) == SUBREG
3379 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3380 [(const_int 0)]
3381 "ix86_split_long_move (operands); DONE;")
3382
3383 (define_insn "*movsf_internal"
3384 [(set (match_operand:SF 0 "nonimmediate_operand"
3385 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3386 (match_operand:SF 1 "general_operand"
3387 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3388 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3389 && (reload_in_progress || reload_completed
3390 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3391 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3392 && standard_80387_constant_p (operands[1]))
3393 || GET_CODE (operands[1]) != CONST_DOUBLE
3394 || memory_operand (operands[0], SFmode))"
3395 {
3396 switch (which_alternative)
3397 {
3398 case 0:
3399 case 1:
3400 return output_387_reg_move (insn, operands);
3401
3402 case 2:
3403 return standard_80387_constant_opcode (operands[1]);
3404
3405 case 3:
3406 case 4:
3407 return "mov{l}\t{%1, %0|%0, %1}";
3408 case 5:
3409 if (get_attr_mode (insn) == MODE_TI)
3410 return "%vpxor\t%0, %d0";
3411 else
3412 return "%vxorps\t%0, %d0";
3413 case 6:
3414 if (get_attr_mode (insn) == MODE_V4SF)
3415 return "%vmovaps\t{%1, %0|%0, %1}";
3416 else
3417 return "%vmovss\t{%1, %d0|%d0, %1}";
3418 case 7:
3419 if (TARGET_AVX)
3420 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3421 : "vmovss\t{%1, %0|%0, %1}";
3422 else
3423 return "movss\t{%1, %0|%0, %1}";
3424 case 8:
3425 return "%vmovss\t{%1, %0|%0, %1}";
3426
3427 case 9: case 10: case 14: case 15:
3428 return "movd\t{%1, %0|%0, %1}";
3429 case 12: case 13:
3430 return "%vmovd\t{%1, %0|%0, %1}";
3431
3432 case 11:
3433 return "movq\t{%1, %0|%0, %1}";
3434
3435 default:
3436 gcc_unreachable ();
3437 }
3438 }
3439 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3440 (set (attr "prefix")
3441 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3442 (const_string "maybe_vex")
3443 (const_string "orig")))
3444 (set (attr "mode")
3445 (cond [(eq_attr "alternative" "3,4,9,10")
3446 (const_string "SI")
3447 (eq_attr "alternative" "5")
3448 (if_then_else
3449 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3450 (const_int 0))
3451 (ne (symbol_ref "TARGET_SSE2")
3452 (const_int 0)))
3453 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3454 (const_int 0)))
3455 (const_string "TI")
3456 (const_string "V4SF"))
3457 /* For architectures resolving dependencies on
3458 whole SSE registers use APS move to break dependency
3459 chains, otherwise use short move to avoid extra work.
3460
3461 Do the same for architectures resolving dependencies on
3462 the parts. While in DF mode it is better to always handle
3463 just register parts, the SF mode is different due to lack
3464 of instructions to load just part of the register. It is
3465 better to maintain the whole registers in single format
3466 to avoid problems on using packed logical operations. */
3467 (eq_attr "alternative" "6")
3468 (if_then_else
3469 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3470 (const_int 0))
3471 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3472 (const_int 0)))
3473 (const_string "V4SF")
3474 (const_string "SF"))
3475 (eq_attr "alternative" "11")
3476 (const_string "DI")]
3477 (const_string "SF")))])
3478
3479 (define_split
3480 [(set (match_operand 0 "register_operand" "")
3481 (match_operand 1 "memory_operand" ""))]
3482 "reload_completed
3483 && MEM_P (operands[1])
3484 && (GET_MODE (operands[0]) == TFmode
3485 || GET_MODE (operands[0]) == XFmode
3486 || GET_MODE (operands[0]) == DFmode
3487 || GET_MODE (operands[0]) == SFmode)
3488 && (operands[2] = find_constant_src (insn))"
3489 [(set (match_dup 0) (match_dup 2))]
3490 {
3491 rtx c = operands[2];
3492 rtx r = operands[0];
3493
3494 if (GET_CODE (r) == SUBREG)
3495 r = SUBREG_REG (r);
3496
3497 if (SSE_REG_P (r))
3498 {
3499 if (!standard_sse_constant_p (c))
3500 FAIL;
3501 }
3502 else if (FP_REG_P (r))
3503 {
3504 if (!standard_80387_constant_p (c))
3505 FAIL;
3506 }
3507 else if (MMX_REG_P (r))
3508 FAIL;
3509 })
3510
3511 (define_split
3512 [(set (match_operand 0 "register_operand" "")
3513 (float_extend (match_operand 1 "memory_operand" "")))]
3514 "reload_completed
3515 && MEM_P (operands[1])
3516 && (GET_MODE (operands[0]) == TFmode
3517 || GET_MODE (operands[0]) == XFmode
3518 || GET_MODE (operands[0]) == DFmode
3519 || GET_MODE (operands[0]) == SFmode)
3520 && (operands[2] = find_constant_src (insn))"
3521 [(set (match_dup 0) (match_dup 2))]
3522 {
3523 rtx c = operands[2];
3524 rtx r = operands[0];
3525
3526 if (GET_CODE (r) == SUBREG)
3527 r = SUBREG_REG (r);
3528
3529 if (SSE_REG_P (r))
3530 {
3531 if (!standard_sse_constant_p (c))
3532 FAIL;
3533 }
3534 else if (FP_REG_P (r))
3535 {
3536 if (!standard_80387_constant_p (c))
3537 FAIL;
3538 }
3539 else if (MMX_REG_P (r))
3540 FAIL;
3541 })
3542
3543 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3544 (define_split
3545 [(set (match_operand:X87MODEF 0 "register_operand" "")
3546 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3547 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3548 && (standard_80387_constant_p (operands[1]) == 8
3549 || standard_80387_constant_p (operands[1]) == 9)"
3550 [(set (match_dup 0)(match_dup 1))
3551 (set (match_dup 0)
3552 (neg:X87MODEF (match_dup 0)))]
3553 {
3554 REAL_VALUE_TYPE r;
3555
3556 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3557 if (real_isnegzero (&r))
3558 operands[1] = CONST0_RTX (<MODE>mode);
3559 else
3560 operands[1] = CONST1_RTX (<MODE>mode);
3561 })
3562
3563 (define_insn "swapxf"
3564 [(set (match_operand:XF 0 "register_operand" "+f")
3565 (match_operand:XF 1 "register_operand" "+f"))
3566 (set (match_dup 1)
3567 (match_dup 0))]
3568 "TARGET_80387"
3569 {
3570 if (STACK_TOP_P (operands[0]))
3571 return "fxch\t%1";
3572 else
3573 return "fxch\t%0";
3574 }
3575 [(set_attr "type" "fxch")
3576 (set_attr "mode" "XF")])
3577
3578 (define_insn "*swap<mode>"
3579 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3580 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3581 (set (match_dup 1)
3582 (match_dup 0))]
3583 "TARGET_80387 || reload_completed"
3584 {
3585 if (STACK_TOP_P (operands[0]))
3586 return "fxch\t%1";
3587 else
3588 return "fxch\t%0";
3589 }
3590 [(set_attr "type" "fxch")
3591 (set_attr "mode" "<MODE>")])
3592 \f
3593 ;; Zero extension instructions
3594
3595 (define_expand "zero_extendhisi2"
3596 [(set (match_operand:SI 0 "register_operand" "")
3597 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3598 ""
3599 {
3600 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3601 {
3602 operands[1] = force_reg (HImode, operands[1]);
3603 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3604 DONE;
3605 }
3606 })
3607
3608 (define_insn "zero_extendhisi2_and"
3609 [(set (match_operand:SI 0 "register_operand" "=r")
3610 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3611 (clobber (reg:CC FLAGS_REG))]
3612 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3613 "#"
3614 [(set_attr "type" "alu1")
3615 (set_attr "mode" "SI")])
3616
3617 (define_split
3618 [(set (match_operand:SI 0 "register_operand" "")
3619 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3620 (clobber (reg:CC FLAGS_REG))]
3621 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3622 && optimize_function_for_speed_p (cfun)"
3623 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3624 (clobber (reg:CC FLAGS_REG))])]
3625 "")
3626
3627 (define_insn "*zero_extendhisi2_movzwl"
3628 [(set (match_operand:SI 0 "register_operand" "=r")
3629 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3630 "!TARGET_ZERO_EXTEND_WITH_AND
3631 || optimize_function_for_size_p (cfun)"
3632 "movz{wl|x}\t{%1, %0|%0, %1}"
3633 [(set_attr "type" "imovx")
3634 (set_attr "mode" "SI")])
3635
3636 (define_expand "zero_extendqihi2"
3637 [(parallel
3638 [(set (match_operand:HI 0 "register_operand" "")
3639 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3640 (clobber (reg:CC FLAGS_REG))])]
3641 ""
3642 "")
3643
3644 (define_insn "*zero_extendqihi2_and"
3645 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3646 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3647 (clobber (reg:CC FLAGS_REG))]
3648 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3649 "#"
3650 [(set_attr "type" "alu1")
3651 (set_attr "mode" "HI")])
3652
3653 (define_insn "*zero_extendqihi2_movzbw_and"
3654 [(set (match_operand:HI 0 "register_operand" "=r,r")
3655 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3656 (clobber (reg:CC FLAGS_REG))]
3657 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3658 "#"
3659 [(set_attr "type" "imovx,alu1")
3660 (set_attr "mode" "HI")])
3661
3662 ; zero extend to SImode here to avoid partial register stalls
3663 (define_insn "*zero_extendqihi2_movzbl"
3664 [(set (match_operand:HI 0 "register_operand" "=r")
3665 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3666 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3667 && reload_completed"
3668 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "SI")])
3671
3672 ;; For the movzbw case strip only the clobber
3673 (define_split
3674 [(set (match_operand:HI 0 "register_operand" "")
3675 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3676 (clobber (reg:CC FLAGS_REG))]
3677 "reload_completed
3678 && (!TARGET_ZERO_EXTEND_WITH_AND
3679 || optimize_function_for_size_p (cfun))
3680 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3681 [(set (match_operand:HI 0 "register_operand" "")
3682 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3683
3684 ;; When source and destination does not overlap, clear destination
3685 ;; first and then do the movb
3686 (define_split
3687 [(set (match_operand:HI 0 "register_operand" "")
3688 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3689 (clobber (reg:CC FLAGS_REG))]
3690 "reload_completed
3691 && ANY_QI_REG_P (operands[0])
3692 && (TARGET_ZERO_EXTEND_WITH_AND
3693 && optimize_function_for_speed_p (cfun))
3694 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3695 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3696 {
3697 operands[2] = gen_lowpart (QImode, operands[0]);
3698 ix86_expand_clear (operands[0]);
3699 })
3700
3701 ;; Rest is handled by single and.
3702 (define_split
3703 [(set (match_operand:HI 0 "register_operand" "")
3704 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3705 (clobber (reg:CC FLAGS_REG))]
3706 "reload_completed
3707 && true_regnum (operands[0]) == true_regnum (operands[1])"
3708 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3709 (clobber (reg:CC FLAGS_REG))])]
3710 "")
3711
3712 (define_expand "zero_extendqisi2"
3713 [(parallel
3714 [(set (match_operand:SI 0 "register_operand" "")
3715 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3716 (clobber (reg:CC FLAGS_REG))])]
3717 ""
3718 "")
3719
3720 (define_insn "*zero_extendqisi2_and"
3721 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3722 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3723 (clobber (reg:CC FLAGS_REG))]
3724 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3725 "#"
3726 [(set_attr "type" "alu1")
3727 (set_attr "mode" "SI")])
3728
3729 (define_insn "*zero_extendqisi2_movzbl_and"
3730 [(set (match_operand:SI 0 "register_operand" "=r,r")
3731 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3732 (clobber (reg:CC FLAGS_REG))]
3733 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3734 "#"
3735 [(set_attr "type" "imovx,alu1")
3736 (set_attr "mode" "SI")])
3737
3738 (define_insn "*zero_extendqisi2_movzbl"
3739 [(set (match_operand:SI 0 "register_operand" "=r")
3740 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3741 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3742 && reload_completed"
3743 "movz{bl|x}\t{%1, %0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "SI")])
3746
3747 ;; For the movzbl case strip only the clobber
3748 (define_split
3749 [(set (match_operand:SI 0 "register_operand" "")
3750 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3751 (clobber (reg:CC FLAGS_REG))]
3752 "reload_completed
3753 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3754 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3755 [(set (match_dup 0)
3756 (zero_extend:SI (match_dup 1)))])
3757
3758 ;; When source and destination does not overlap, clear destination
3759 ;; first and then do the movb
3760 (define_split
3761 [(set (match_operand:SI 0 "register_operand" "")
3762 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3763 (clobber (reg:CC FLAGS_REG))]
3764 "reload_completed
3765 && ANY_QI_REG_P (operands[0])
3766 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3767 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3768 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3769 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3770 {
3771 operands[2] = gen_lowpart (QImode, operands[0]);
3772 ix86_expand_clear (operands[0]);
3773 })
3774
3775 ;; Rest is handled by single and.
3776 (define_split
3777 [(set (match_operand:SI 0 "register_operand" "")
3778 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3779 (clobber (reg:CC FLAGS_REG))]
3780 "reload_completed
3781 && true_regnum (operands[0]) == true_regnum (operands[1])"
3782 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3783 (clobber (reg:CC FLAGS_REG))])]
3784 "")
3785
3786 ;; %%% Kill me once multi-word ops are sane.
3787 (define_expand "zero_extendsidi2"
3788 [(set (match_operand:DI 0 "register_operand" "")
3789 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3790 ""
3791 {
3792 if (!TARGET_64BIT)
3793 {
3794 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3795 DONE;
3796 }
3797 })
3798
3799 (define_insn "zero_extendsidi2_32"
3800 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3801 (zero_extend:DI
3802 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3803 (clobber (reg:CC FLAGS_REG))]
3804 "!TARGET_64BIT"
3805 "@
3806 #
3807 #
3808 #
3809 movd\t{%1, %0|%0, %1}
3810 movd\t{%1, %0|%0, %1}
3811 %vmovd\t{%1, %0|%0, %1}
3812 %vmovd\t{%1, %0|%0, %1}"
3813 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3814 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3815 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3816
3817 (define_insn "zero_extendsidi2_rex64"
3818 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3819 (zero_extend:DI
3820 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3821 "TARGET_64BIT"
3822 "@
3823 mov\t{%k1, %k0|%k0, %k1}
3824 #
3825 movd\t{%1, %0|%0, %1}
3826 movd\t{%1, %0|%0, %1}
3827 %vmovd\t{%1, %0|%0, %1}
3828 %vmovd\t{%1, %0|%0, %1}"
3829 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3830 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3831 (set_attr "prefix_0f" "0,*,*,*,*,*")
3832 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3833
3834 (define_split
3835 [(set (match_operand:DI 0 "memory_operand" "")
3836 (zero_extend:DI (match_dup 0)))]
3837 "TARGET_64BIT"
3838 [(set (match_dup 4) (const_int 0))]
3839 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3840
3841 (define_split
3842 [(set (match_operand:DI 0 "register_operand" "")
3843 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3844 (clobber (reg:CC FLAGS_REG))]
3845 "!TARGET_64BIT && reload_completed
3846 && true_regnum (operands[0]) == true_regnum (operands[1])"
3847 [(set (match_dup 4) (const_int 0))]
3848 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3849
3850 (define_split
3851 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3852 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3853 (clobber (reg:CC FLAGS_REG))]
3854 "!TARGET_64BIT && reload_completed
3855 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3856 [(set (match_dup 3) (match_dup 1))
3857 (set (match_dup 4) (const_int 0))]
3858 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3859
3860 (define_insn "zero_extendhidi2"
3861 [(set (match_operand:DI 0 "register_operand" "=r")
3862 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3863 "TARGET_64BIT"
3864 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3865 [(set_attr "type" "imovx")
3866 (set_attr "mode" "SI")])
3867
3868 (define_insn "zero_extendqidi2"
3869 [(set (match_operand:DI 0 "register_operand" "=r")
3870 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3871 "TARGET_64BIT"
3872 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3873 [(set_attr "type" "imovx")
3874 (set_attr "mode" "SI")])
3875 \f
3876 ;; Sign extension instructions
3877
3878 (define_expand "extendsidi2"
3879 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3880 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3881 (clobber (reg:CC FLAGS_REG))
3882 (clobber (match_scratch:SI 2 ""))])]
3883 ""
3884 {
3885 if (TARGET_64BIT)
3886 {
3887 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3888 DONE;
3889 }
3890 })
3891
3892 (define_insn "*extendsidi2_1"
3893 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3894 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3895 (clobber (reg:CC FLAGS_REG))
3896 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3897 "!TARGET_64BIT"
3898 "#")
3899
3900 (define_insn "extendsidi2_rex64"
3901 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3902 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3903 "TARGET_64BIT"
3904 "@
3905 {cltq|cdqe}
3906 movs{lq|x}\t{%1, %0|%0, %1}"
3907 [(set_attr "type" "imovx")
3908 (set_attr "mode" "DI")
3909 (set_attr "prefix_0f" "0")
3910 (set_attr "modrm" "0,1")])
3911
3912 (define_insn "extendhidi2"
3913 [(set (match_operand:DI 0 "register_operand" "=r")
3914 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3915 "TARGET_64BIT"
3916 "movs{wq|x}\t{%1, %0|%0, %1}"
3917 [(set_attr "type" "imovx")
3918 (set_attr "mode" "DI")])
3919
3920 (define_insn "extendqidi2"
3921 [(set (match_operand:DI 0 "register_operand" "=r")
3922 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3923 "TARGET_64BIT"
3924 "movs{bq|x}\t{%1, %0|%0, %1}"
3925 [(set_attr "type" "imovx")
3926 (set_attr "mode" "DI")])
3927
3928 ;; Extend to memory case when source register does die.
3929 (define_split
3930 [(set (match_operand:DI 0 "memory_operand" "")
3931 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3932 (clobber (reg:CC FLAGS_REG))
3933 (clobber (match_operand:SI 2 "register_operand" ""))]
3934 "(reload_completed
3935 && dead_or_set_p (insn, operands[1])
3936 && !reg_mentioned_p (operands[1], operands[0]))"
3937 [(set (match_dup 3) (match_dup 1))
3938 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3939 (clobber (reg:CC FLAGS_REG))])
3940 (set (match_dup 4) (match_dup 1))]
3941 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3942
3943 ;; Extend to memory case when source register does not die.
3944 (define_split
3945 [(set (match_operand:DI 0 "memory_operand" "")
3946 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3947 (clobber (reg:CC FLAGS_REG))
3948 (clobber (match_operand:SI 2 "register_operand" ""))]
3949 "reload_completed"
3950 [(const_int 0)]
3951 {
3952 split_di (&operands[0], 1, &operands[3], &operands[4]);
3953
3954 emit_move_insn (operands[3], operands[1]);
3955
3956 /* Generate a cltd if possible and doing so it profitable. */
3957 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3958 && true_regnum (operands[1]) == AX_REG
3959 && true_regnum (operands[2]) == DX_REG)
3960 {
3961 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3962 }
3963 else
3964 {
3965 emit_move_insn (operands[2], operands[1]);
3966 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3967 }
3968 emit_move_insn (operands[4], operands[2]);
3969 DONE;
3970 })
3971
3972 ;; Extend to register case. Optimize case where source and destination
3973 ;; registers match and cases where we can use cltd.
3974 (define_split
3975 [(set (match_operand:DI 0 "register_operand" "")
3976 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3977 (clobber (reg:CC FLAGS_REG))
3978 (clobber (match_scratch:SI 2 ""))]
3979 "reload_completed"
3980 [(const_int 0)]
3981 {
3982 split_di (&operands[0], 1, &operands[3], &operands[4]);
3983
3984 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3985 emit_move_insn (operands[3], operands[1]);
3986
3987 /* Generate a cltd if possible and doing so it profitable. */
3988 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3989 && true_regnum (operands[3]) == AX_REG
3990 && true_regnum (operands[4]) == DX_REG)
3991 {
3992 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3993 DONE;
3994 }
3995
3996 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3997 emit_move_insn (operands[4], operands[1]);
3998
3999 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4000 DONE;
4001 })
4002
4003 (define_insn "extendhisi2"
4004 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4005 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4006 ""
4007 {
4008 switch (get_attr_prefix_0f (insn))
4009 {
4010 case 0:
4011 return "{cwtl|cwde}";
4012 default:
4013 return "movs{wl|x}\t{%1, %0|%0, %1}";
4014 }
4015 }
4016 [(set_attr "type" "imovx")
4017 (set_attr "mode" "SI")
4018 (set (attr "prefix_0f")
4019 ;; movsx is short decodable while cwtl is vector decoded.
4020 (if_then_else (and (eq_attr "cpu" "!k6")
4021 (eq_attr "alternative" "0"))
4022 (const_string "0")
4023 (const_string "1")))
4024 (set (attr "modrm")
4025 (if_then_else (eq_attr "prefix_0f" "0")
4026 (const_string "0")
4027 (const_string "1")))])
4028
4029 (define_insn "*extendhisi2_zext"
4030 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4031 (zero_extend:DI
4032 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4033 "TARGET_64BIT"
4034 {
4035 switch (get_attr_prefix_0f (insn))
4036 {
4037 case 0:
4038 return "{cwtl|cwde}";
4039 default:
4040 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4041 }
4042 }
4043 [(set_attr "type" "imovx")
4044 (set_attr "mode" "SI")
4045 (set (attr "prefix_0f")
4046 ;; movsx is short decodable while cwtl is vector decoded.
4047 (if_then_else (and (eq_attr "cpu" "!k6")
4048 (eq_attr "alternative" "0"))
4049 (const_string "0")
4050 (const_string "1")))
4051 (set (attr "modrm")
4052 (if_then_else (eq_attr "prefix_0f" "0")
4053 (const_string "0")
4054 (const_string "1")))])
4055
4056 (define_insn "extendqihi2"
4057 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4058 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4059 ""
4060 {
4061 switch (get_attr_prefix_0f (insn))
4062 {
4063 case 0:
4064 return "{cbtw|cbw}";
4065 default:
4066 return "movs{bw|x}\t{%1, %0|%0, %1}";
4067 }
4068 }
4069 [(set_attr "type" "imovx")
4070 (set_attr "mode" "HI")
4071 (set (attr "prefix_0f")
4072 ;; movsx is short decodable while cwtl is vector decoded.
4073 (if_then_else (and (eq_attr "cpu" "!k6")
4074 (eq_attr "alternative" "0"))
4075 (const_string "0")
4076 (const_string "1")))
4077 (set (attr "modrm")
4078 (if_then_else (eq_attr "prefix_0f" "0")
4079 (const_string "0")
4080 (const_string "1")))])
4081
4082 (define_insn "extendqisi2"
4083 [(set (match_operand:SI 0 "register_operand" "=r")
4084 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4085 ""
4086 "movs{bl|x}\t{%1, %0|%0, %1}"
4087 [(set_attr "type" "imovx")
4088 (set_attr "mode" "SI")])
4089
4090 (define_insn "*extendqisi2_zext"
4091 [(set (match_operand:DI 0 "register_operand" "=r")
4092 (zero_extend:DI
4093 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4094 "TARGET_64BIT"
4095 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4096 [(set_attr "type" "imovx")
4097 (set_attr "mode" "SI")])
4098 \f
4099 ;; Conversions between float and double.
4100
4101 ;; These are all no-ops in the model used for the 80387. So just
4102 ;; emit moves.
4103
4104 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4105 (define_insn "*dummy_extendsfdf2"
4106 [(set (match_operand:DF 0 "push_operand" "=<")
4107 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4108 "0"
4109 "#")
4110
4111 (define_split
4112 [(set (match_operand:DF 0 "push_operand" "")
4113 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4114 ""
4115 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4116 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4117
4118 (define_insn "*dummy_extendsfxf2"
4119 [(set (match_operand:XF 0 "push_operand" "=<")
4120 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4121 "0"
4122 "#")
4123
4124 (define_split
4125 [(set (match_operand:XF 0 "push_operand" "")
4126 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4127 ""
4128 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4129 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4130 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4131
4132 (define_split
4133 [(set (match_operand:XF 0 "push_operand" "")
4134 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4135 ""
4136 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4137 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4138 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4139
4140 (define_expand "extendsfdf2"
4141 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4142 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4143 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4144 {
4145 /* ??? Needed for compress_float_constant since all fp constants
4146 are LEGITIMATE_CONSTANT_P. */
4147 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4148 {
4149 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4150 && standard_80387_constant_p (operands[1]) > 0)
4151 {
4152 operands[1] = simplify_const_unary_operation
4153 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4154 emit_move_insn_1 (operands[0], operands[1]);
4155 DONE;
4156 }
4157 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4158 }
4159 })
4160
4161 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4162 cvtss2sd:
4163 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4164 cvtps2pd xmm2,xmm1
4165 We do the conversion post reload to avoid producing of 128bit spills
4166 that might lead to ICE on 32bit target. The sequence unlikely combine
4167 anyway. */
4168 (define_split
4169 [(set (match_operand:DF 0 "register_operand" "")
4170 (float_extend:DF
4171 (match_operand:SF 1 "nonimmediate_operand" "")))]
4172 "TARGET_USE_VECTOR_FP_CONVERTS
4173 && optimize_insn_for_speed_p ()
4174 && reload_completed && SSE_REG_P (operands[0])"
4175 [(set (match_dup 2)
4176 (float_extend:V2DF
4177 (vec_select:V2SF
4178 (match_dup 3)
4179 (parallel [(const_int 0) (const_int 1)]))))]
4180 {
4181 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4182 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4183 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4184 Try to avoid move when unpacking can be done in source. */
4185 if (REG_P (operands[1]))
4186 {
4187 /* If it is unsafe to overwrite upper half of source, we need
4188 to move to destination and unpack there. */
4189 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4190 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4191 && true_regnum (operands[0]) != true_regnum (operands[1]))
4192 {
4193 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4194 emit_move_insn (tmp, operands[1]);
4195 }
4196 else
4197 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4198 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4199 operands[3]));
4200 }
4201 else
4202 emit_insn (gen_vec_setv4sf_0 (operands[3],
4203 CONST0_RTX (V4SFmode), operands[1]));
4204 })
4205
4206 (define_insn "*extendsfdf2_mixed"
4207 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4208 (float_extend:DF
4209 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4210 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4211 {
4212 switch (which_alternative)
4213 {
4214 case 0:
4215 case 1:
4216 return output_387_reg_move (insn, operands);
4217
4218 case 2:
4219 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4220
4221 default:
4222 gcc_unreachable ();
4223 }
4224 }
4225 [(set_attr "type" "fmov,fmov,ssecvt")
4226 (set_attr "prefix" "orig,orig,maybe_vex")
4227 (set_attr "mode" "SF,XF,DF")])
4228
4229 (define_insn "*extendsfdf2_sse"
4230 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4231 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4232 "TARGET_SSE2 && TARGET_SSE_MATH"
4233 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4234 [(set_attr "type" "ssecvt")
4235 (set_attr "prefix" "maybe_vex")
4236 (set_attr "mode" "DF")])
4237
4238 (define_insn "*extendsfdf2_i387"
4239 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4240 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4241 "TARGET_80387"
4242 "* return output_387_reg_move (insn, operands);"
4243 [(set_attr "type" "fmov")
4244 (set_attr "mode" "SF,XF")])
4245
4246 (define_expand "extend<mode>xf2"
4247 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4248 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4249 "TARGET_80387"
4250 {
4251 /* ??? Needed for compress_float_constant since all fp constants
4252 are LEGITIMATE_CONSTANT_P. */
4253 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4254 {
4255 if (standard_80387_constant_p (operands[1]) > 0)
4256 {
4257 operands[1] = simplify_const_unary_operation
4258 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4259 emit_move_insn_1 (operands[0], operands[1]);
4260 DONE;
4261 }
4262 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4263 }
4264 })
4265
4266 (define_insn "*extend<mode>xf2_i387"
4267 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4268 (float_extend:XF
4269 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4270 "TARGET_80387"
4271 "* return output_387_reg_move (insn, operands);"
4272 [(set_attr "type" "fmov")
4273 (set_attr "mode" "<MODE>,XF")])
4274
4275 ;; %%% This seems bad bad news.
4276 ;; This cannot output into an f-reg because there is no way to be sure
4277 ;; of truncating in that case. Otherwise this is just like a simple move
4278 ;; insn. So we pretend we can output to a reg in order to get better
4279 ;; register preferencing, but we really use a stack slot.
4280
4281 ;; Conversion from DFmode to SFmode.
4282
4283 (define_expand "truncdfsf2"
4284 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4285 (float_truncate:SF
4286 (match_operand:DF 1 "nonimmediate_operand" "")))]
4287 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4288 {
4289 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4290 ;
4291 else if (flag_unsafe_math_optimizations)
4292 ;
4293 else
4294 {
4295 enum ix86_stack_slot slot = (virtuals_instantiated
4296 ? SLOT_TEMP
4297 : SLOT_VIRTUAL);
4298 rtx temp = assign_386_stack_local (SFmode, slot);
4299 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4300 DONE;
4301 }
4302 })
4303
4304 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4305 cvtsd2ss:
4306 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4307 cvtpd2ps xmm2,xmm1
4308 We do the conversion post reload to avoid producing of 128bit spills
4309 that might lead to ICE on 32bit target. The sequence unlikely combine
4310 anyway. */
4311 (define_split
4312 [(set (match_operand:SF 0 "register_operand" "")
4313 (float_truncate:SF
4314 (match_operand:DF 1 "nonimmediate_operand" "")))]
4315 "TARGET_USE_VECTOR_FP_CONVERTS
4316 && optimize_insn_for_speed_p ()
4317 && reload_completed && SSE_REG_P (operands[0])"
4318 [(set (match_dup 2)
4319 (vec_concat:V4SF
4320 (float_truncate:V2SF
4321 (match_dup 4))
4322 (match_dup 3)))]
4323 {
4324 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4325 operands[3] = CONST0_RTX (V2SFmode);
4326 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4327 /* Use movsd for loading from memory, unpcklpd for registers.
4328 Try to avoid move when unpacking can be done in source, or SSE3
4329 movddup is available. */
4330 if (REG_P (operands[1]))
4331 {
4332 if (!TARGET_SSE3
4333 && true_regnum (operands[0]) != true_regnum (operands[1])
4334 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4335 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4336 {
4337 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4338 emit_move_insn (tmp, operands[1]);
4339 operands[1] = tmp;
4340 }
4341 else if (!TARGET_SSE3)
4342 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4343 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4344 }
4345 else
4346 emit_insn (gen_sse2_loadlpd (operands[4],
4347 CONST0_RTX (V2DFmode), operands[1]));
4348 })
4349
4350 (define_expand "truncdfsf2_with_temp"
4351 [(parallel [(set (match_operand:SF 0 "" "")
4352 (float_truncate:SF (match_operand:DF 1 "" "")))
4353 (clobber (match_operand:SF 2 "" ""))])]
4354 "")
4355
4356 (define_insn "*truncdfsf_fast_mixed"
4357 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4358 (float_truncate:SF
4359 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4360 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4361 {
4362 switch (which_alternative)
4363 {
4364 case 0:
4365 return output_387_reg_move (insn, operands);
4366 case 1:
4367 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4368 default:
4369 gcc_unreachable ();
4370 }
4371 }
4372 [(set_attr "type" "fmov,ssecvt")
4373 (set_attr "prefix" "orig,maybe_vex")
4374 (set_attr "mode" "SF")])
4375
4376 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4377 ;; because nothing we do here is unsafe.
4378 (define_insn "*truncdfsf_fast_sse"
4379 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4380 (float_truncate:SF
4381 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4382 "TARGET_SSE2 && TARGET_SSE_MATH"
4383 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4384 [(set_attr "type" "ssecvt")
4385 (set_attr "prefix" "maybe_vex")
4386 (set_attr "mode" "SF")])
4387
4388 (define_insn "*truncdfsf_fast_i387"
4389 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4390 (float_truncate:SF
4391 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4392 "TARGET_80387 && flag_unsafe_math_optimizations"
4393 "* return output_387_reg_move (insn, operands);"
4394 [(set_attr "type" "fmov")
4395 (set_attr "mode" "SF")])
4396
4397 (define_insn "*truncdfsf_mixed"
4398 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4399 (float_truncate:SF
4400 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4401 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4402 "TARGET_MIX_SSE_I387"
4403 {
4404 switch (which_alternative)
4405 {
4406 case 0:
4407 return output_387_reg_move (insn, operands);
4408 case 1:
4409 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4410
4411 default:
4412 return "#";
4413 }
4414 }
4415 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4416 (set_attr "unit" "*,*,i387,i387,i387")
4417 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4418 (set_attr "mode" "SF")])
4419
4420 (define_insn "*truncdfsf_i387"
4421 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4422 (float_truncate:SF
4423 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4424 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4425 "TARGET_80387"
4426 {
4427 switch (which_alternative)
4428 {
4429 case 0:
4430 return output_387_reg_move (insn, operands);
4431
4432 default:
4433 return "#";
4434 }
4435 }
4436 [(set_attr "type" "fmov,multi,multi,multi")
4437 (set_attr "unit" "*,i387,i387,i387")
4438 (set_attr "mode" "SF")])
4439
4440 (define_insn "*truncdfsf2_i387_1"
4441 [(set (match_operand:SF 0 "memory_operand" "=m")
4442 (float_truncate:SF
4443 (match_operand:DF 1 "register_operand" "f")))]
4444 "TARGET_80387
4445 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4446 && !TARGET_MIX_SSE_I387"
4447 "* return output_387_reg_move (insn, operands);"
4448 [(set_attr "type" "fmov")
4449 (set_attr "mode" "SF")])
4450
4451 (define_split
4452 [(set (match_operand:SF 0 "register_operand" "")
4453 (float_truncate:SF
4454 (match_operand:DF 1 "fp_register_operand" "")))
4455 (clobber (match_operand 2 "" ""))]
4456 "reload_completed"
4457 [(set (match_dup 2) (match_dup 1))
4458 (set (match_dup 0) (match_dup 2))]
4459 {
4460 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4461 })
4462
4463 ;; Conversion from XFmode to {SF,DF}mode
4464
4465 (define_expand "truncxf<mode>2"
4466 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4467 (float_truncate:MODEF
4468 (match_operand:XF 1 "register_operand" "")))
4469 (clobber (match_dup 2))])]
4470 "TARGET_80387"
4471 {
4472 if (flag_unsafe_math_optimizations)
4473 {
4474 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4475 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4476 if (reg != operands[0])
4477 emit_move_insn (operands[0], reg);
4478 DONE;
4479 }
4480 else
4481 {
4482 enum ix86_stack_slot slot = (virtuals_instantiated
4483 ? SLOT_TEMP
4484 : SLOT_VIRTUAL);
4485 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4486 }
4487 })
4488
4489 (define_insn "*truncxfsf2_mixed"
4490 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4491 (float_truncate:SF
4492 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4493 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4494 "TARGET_80387"
4495 {
4496 gcc_assert (!which_alternative);
4497 return output_387_reg_move (insn, operands);
4498 }
4499 [(set_attr "type" "fmov,multi,multi,multi")
4500 (set_attr "unit" "*,i387,i387,i387")
4501 (set_attr "mode" "SF")])
4502
4503 (define_insn "*truncxfdf2_mixed"
4504 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4505 (float_truncate:DF
4506 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4507 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4508 "TARGET_80387"
4509 {
4510 gcc_assert (!which_alternative);
4511 return output_387_reg_move (insn, operands);
4512 }
4513 [(set_attr "type" "fmov,multi,multi,multi")
4514 (set_attr "unit" "*,i387,i387,i387")
4515 (set_attr "mode" "DF")])
4516
4517 (define_insn "truncxf<mode>2_i387_noop"
4518 [(set (match_operand:MODEF 0 "register_operand" "=f")
4519 (float_truncate:MODEF
4520 (match_operand:XF 1 "register_operand" "f")))]
4521 "TARGET_80387 && flag_unsafe_math_optimizations"
4522 "* return output_387_reg_move (insn, operands);"
4523 [(set_attr "type" "fmov")
4524 (set_attr "mode" "<MODE>")])
4525
4526 (define_insn "*truncxf<mode>2_i387"
4527 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4528 (float_truncate:MODEF
4529 (match_operand:XF 1 "register_operand" "f")))]
4530 "TARGET_80387"
4531 "* return output_387_reg_move (insn, operands);"
4532 [(set_attr "type" "fmov")
4533 (set_attr "mode" "<MODE>")])
4534
4535 (define_split
4536 [(set (match_operand:MODEF 0 "register_operand" "")
4537 (float_truncate:MODEF
4538 (match_operand:XF 1 "register_operand" "")))
4539 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4540 "TARGET_80387 && reload_completed"
4541 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4542 (set (match_dup 0) (match_dup 2))]
4543 "")
4544
4545 (define_split
4546 [(set (match_operand:MODEF 0 "memory_operand" "")
4547 (float_truncate:MODEF
4548 (match_operand:XF 1 "register_operand" "")))
4549 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4550 "TARGET_80387"
4551 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4552 "")
4553 \f
4554 ;; Signed conversion to DImode.
4555
4556 (define_expand "fix_truncxfdi2"
4557 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4558 (fix:DI (match_operand:XF 1 "register_operand" "")))
4559 (clobber (reg:CC FLAGS_REG))])]
4560 "TARGET_80387"
4561 {
4562 if (TARGET_FISTTP)
4563 {
4564 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4565 DONE;
4566 }
4567 })
4568
4569 (define_expand "fix_trunc<mode>di2"
4570 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4571 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4572 (clobber (reg:CC FLAGS_REG))])]
4573 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4574 {
4575 if (TARGET_FISTTP
4576 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4577 {
4578 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4579 DONE;
4580 }
4581 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4582 {
4583 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4584 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4585 if (out != operands[0])
4586 emit_move_insn (operands[0], out);
4587 DONE;
4588 }
4589 })
4590
4591 ;; Signed conversion to SImode.
4592
4593 (define_expand "fix_truncxfsi2"
4594 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4595 (fix:SI (match_operand:XF 1 "register_operand" "")))
4596 (clobber (reg:CC FLAGS_REG))])]
4597 "TARGET_80387"
4598 {
4599 if (TARGET_FISTTP)
4600 {
4601 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4602 DONE;
4603 }
4604 })
4605
4606 (define_expand "fix_trunc<mode>si2"
4607 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4608 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4609 (clobber (reg:CC FLAGS_REG))])]
4610 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4611 {
4612 if (TARGET_FISTTP
4613 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4614 {
4615 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4616 DONE;
4617 }
4618 if (SSE_FLOAT_MODE_P (<MODE>mode))
4619 {
4620 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4621 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4622 if (out != operands[0])
4623 emit_move_insn (operands[0], out);
4624 DONE;
4625 }
4626 })
4627
4628 ;; Signed conversion to HImode.
4629
4630 (define_expand "fix_trunc<mode>hi2"
4631 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4632 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4633 (clobber (reg:CC FLAGS_REG))])]
4634 "TARGET_80387
4635 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4636 {
4637 if (TARGET_FISTTP)
4638 {
4639 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4640 DONE;
4641 }
4642 })
4643
4644 ;; Unsigned conversion to SImode.
4645
4646 (define_expand "fixuns_trunc<mode>si2"
4647 [(parallel
4648 [(set (match_operand:SI 0 "register_operand" "")
4649 (unsigned_fix:SI
4650 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4651 (use (match_dup 2))
4652 (clobber (match_scratch:<ssevecmode> 3 ""))
4653 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4654 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4655 {
4656 enum machine_mode mode = <MODE>mode;
4657 enum machine_mode vecmode = <ssevecmode>mode;
4658 REAL_VALUE_TYPE TWO31r;
4659 rtx two31;
4660
4661 if (optimize_insn_for_size_p ())
4662 FAIL;
4663
4664 real_ldexp (&TWO31r, &dconst1, 31);
4665 two31 = const_double_from_real_value (TWO31r, mode);
4666 two31 = ix86_build_const_vector (mode, true, two31);
4667 operands[2] = force_reg (vecmode, two31);
4668 })
4669
4670 (define_insn_and_split "*fixuns_trunc<mode>_1"
4671 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4672 (unsigned_fix:SI
4673 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4674 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4675 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4676 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4677 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4678 && optimize_function_for_speed_p (cfun)"
4679 "#"
4680 "&& reload_completed"
4681 [(const_int 0)]
4682 {
4683 ix86_split_convert_uns_si_sse (operands);
4684 DONE;
4685 })
4686
4687 ;; Unsigned conversion to HImode.
4688 ;; Without these patterns, we'll try the unsigned SI conversion which
4689 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4690
4691 (define_expand "fixuns_trunc<mode>hi2"
4692 [(set (match_dup 2)
4693 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4694 (set (match_operand:HI 0 "nonimmediate_operand" "")
4695 (subreg:HI (match_dup 2) 0))]
4696 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4697 "operands[2] = gen_reg_rtx (SImode);")
4698
4699 ;; When SSE is available, it is always faster to use it!
4700 (define_insn "fix_trunc<mode>di_sse"
4701 [(set (match_operand:DI 0 "register_operand" "=r,r")
4702 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4703 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4704 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4705 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4706 [(set_attr "type" "sseicvt")
4707 (set_attr "prefix" "maybe_vex")
4708 (set_attr "prefix_rex" "1")
4709 (set_attr "mode" "<MODE>")
4710 (set_attr "athlon_decode" "double,vector")
4711 (set_attr "amdfam10_decode" "double,double")])
4712
4713 (define_insn "fix_trunc<mode>si_sse"
4714 [(set (match_operand:SI 0 "register_operand" "=r,r")
4715 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4716 "SSE_FLOAT_MODE_P (<MODE>mode)
4717 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4718 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4719 [(set_attr "type" "sseicvt")
4720 (set_attr "prefix" "maybe_vex")
4721 (set_attr "mode" "<MODE>")
4722 (set_attr "athlon_decode" "double,vector")
4723 (set_attr "amdfam10_decode" "double,double")])
4724
4725 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4726 (define_peephole2
4727 [(set (match_operand:MODEF 0 "register_operand" "")
4728 (match_operand:MODEF 1 "memory_operand" ""))
4729 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4730 (fix:SSEMODEI24 (match_dup 0)))]
4731 "TARGET_SHORTEN_X87_SSE
4732 && peep2_reg_dead_p (2, operands[0])"
4733 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4734 "")
4735
4736 ;; Avoid vector decoded forms of the instruction.
4737 (define_peephole2
4738 [(match_scratch:DF 2 "Y2")
4739 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4740 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4741 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4742 [(set (match_dup 2) (match_dup 1))
4743 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4744 "")
4745
4746 (define_peephole2
4747 [(match_scratch:SF 2 "x")
4748 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4749 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4750 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4751 [(set (match_dup 2) (match_dup 1))
4752 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4753 "")
4754
4755 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4756 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4757 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4758 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4759 && TARGET_FISTTP
4760 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4761 && (TARGET_64BIT || <MODE>mode != DImode))
4762 && TARGET_SSE_MATH)
4763 && can_create_pseudo_p ()"
4764 "#"
4765 "&& 1"
4766 [(const_int 0)]
4767 {
4768 if (memory_operand (operands[0], VOIDmode))
4769 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4770 else
4771 {
4772 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4773 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4774 operands[1],
4775 operands[2]));
4776 }
4777 DONE;
4778 }
4779 [(set_attr "type" "fisttp")
4780 (set_attr "mode" "<MODE>")])
4781
4782 (define_insn "fix_trunc<mode>_i387_fisttp"
4783 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4784 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4785 (clobber (match_scratch:XF 2 "=&1f"))]
4786 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && TARGET_FISTTP
4788 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4789 && (TARGET_64BIT || <MODE>mode != DImode))
4790 && TARGET_SSE_MATH)"
4791 "* return output_fix_trunc (insn, operands, 1);"
4792 [(set_attr "type" "fisttp")
4793 (set_attr "mode" "<MODE>")])
4794
4795 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4796 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4797 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4798 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4799 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4800 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4801 && TARGET_FISTTP
4802 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4803 && (TARGET_64BIT || <MODE>mode != DImode))
4804 && TARGET_SSE_MATH)"
4805 "#"
4806 [(set_attr "type" "fisttp")
4807 (set_attr "mode" "<MODE>")])
4808
4809 (define_split
4810 [(set (match_operand:X87MODEI 0 "register_operand" "")
4811 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4812 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4813 (clobber (match_scratch 3 ""))]
4814 "reload_completed"
4815 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4816 (clobber (match_dup 3))])
4817 (set (match_dup 0) (match_dup 2))]
4818 "")
4819
4820 (define_split
4821 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4822 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4823 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4824 (clobber (match_scratch 3 ""))]
4825 "reload_completed"
4826 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4827 (clobber (match_dup 3))])]
4828 "")
4829
4830 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4831 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4832 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4833 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4834 ;; function in i386.c.
4835 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4836 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4837 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4840 && !TARGET_FISTTP
4841 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4842 && (TARGET_64BIT || <MODE>mode != DImode))
4843 && can_create_pseudo_p ()"
4844 "#"
4845 "&& 1"
4846 [(const_int 0)]
4847 {
4848 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4849
4850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4852 if (memory_operand (operands[0], VOIDmode))
4853 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4854 operands[2], operands[3]));
4855 else
4856 {
4857 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4858 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4859 operands[2], operands[3],
4860 operands[4]));
4861 }
4862 DONE;
4863 }
4864 [(set_attr "type" "fistp")
4865 (set_attr "i387_cw" "trunc")
4866 (set_attr "mode" "<MODE>")])
4867
4868 (define_insn "fix_truncdi_i387"
4869 [(set (match_operand:DI 0 "memory_operand" "=m")
4870 (fix:DI (match_operand 1 "register_operand" "f")))
4871 (use (match_operand:HI 2 "memory_operand" "m"))
4872 (use (match_operand:HI 3 "memory_operand" "m"))
4873 (clobber (match_scratch:XF 4 "=&1f"))]
4874 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4875 && !TARGET_FISTTP
4876 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4877 "* return output_fix_trunc (insn, operands, 0);"
4878 [(set_attr "type" "fistp")
4879 (set_attr "i387_cw" "trunc")
4880 (set_attr "mode" "DI")])
4881
4882 (define_insn "fix_truncdi_i387_with_temp"
4883 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4884 (fix:DI (match_operand 1 "register_operand" "f,f")))
4885 (use (match_operand:HI 2 "memory_operand" "m,m"))
4886 (use (match_operand:HI 3 "memory_operand" "m,m"))
4887 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4888 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4889 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4890 && !TARGET_FISTTP
4891 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4892 "#"
4893 [(set_attr "type" "fistp")
4894 (set_attr "i387_cw" "trunc")
4895 (set_attr "mode" "DI")])
4896
4897 (define_split
4898 [(set (match_operand:DI 0 "register_operand" "")
4899 (fix:DI (match_operand 1 "register_operand" "")))
4900 (use (match_operand:HI 2 "memory_operand" ""))
4901 (use (match_operand:HI 3 "memory_operand" ""))
4902 (clobber (match_operand:DI 4 "memory_operand" ""))
4903 (clobber (match_scratch 5 ""))]
4904 "reload_completed"
4905 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4906 (use (match_dup 2))
4907 (use (match_dup 3))
4908 (clobber (match_dup 5))])
4909 (set (match_dup 0) (match_dup 4))]
4910 "")
4911
4912 (define_split
4913 [(set (match_operand:DI 0 "memory_operand" "")
4914 (fix:DI (match_operand 1 "register_operand" "")))
4915 (use (match_operand:HI 2 "memory_operand" ""))
4916 (use (match_operand:HI 3 "memory_operand" ""))
4917 (clobber (match_operand:DI 4 "memory_operand" ""))
4918 (clobber (match_scratch 5 ""))]
4919 "reload_completed"
4920 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4921 (use (match_dup 2))
4922 (use (match_dup 3))
4923 (clobber (match_dup 5))])]
4924 "")
4925
4926 (define_insn "fix_trunc<mode>_i387"
4927 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4928 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4929 (use (match_operand:HI 2 "memory_operand" "m"))
4930 (use (match_operand:HI 3 "memory_operand" "m"))]
4931 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4932 && !TARGET_FISTTP
4933 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4934 "* return output_fix_trunc (insn, operands, 0);"
4935 [(set_attr "type" "fistp")
4936 (set_attr "i387_cw" "trunc")
4937 (set_attr "mode" "<MODE>")])
4938
4939 (define_insn "fix_trunc<mode>_i387_with_temp"
4940 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4941 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4942 (use (match_operand:HI 2 "memory_operand" "m,m"))
4943 (use (match_operand:HI 3 "memory_operand" "m,m"))
4944 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4945 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4946 && !TARGET_FISTTP
4947 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4948 "#"
4949 [(set_attr "type" "fistp")
4950 (set_attr "i387_cw" "trunc")
4951 (set_attr "mode" "<MODE>")])
4952
4953 (define_split
4954 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4955 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4956 (use (match_operand:HI 2 "memory_operand" ""))
4957 (use (match_operand:HI 3 "memory_operand" ""))
4958 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4959 "reload_completed"
4960 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4961 (use (match_dup 2))
4962 (use (match_dup 3))])
4963 (set (match_dup 0) (match_dup 4))]
4964 "")
4965
4966 (define_split
4967 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4968 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4969 (use (match_operand:HI 2 "memory_operand" ""))
4970 (use (match_operand:HI 3 "memory_operand" ""))
4971 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4972 "reload_completed"
4973 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4974 (use (match_dup 2))
4975 (use (match_dup 3))])]
4976 "")
4977
4978 (define_insn "x86_fnstcw_1"
4979 [(set (match_operand:HI 0 "memory_operand" "=m")
4980 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4981 "TARGET_80387"
4982 "fnstcw\t%0"
4983 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4984 (set_attr "mode" "HI")
4985 (set_attr "unit" "i387")])
4986
4987 (define_insn "x86_fldcw_1"
4988 [(set (reg:HI FPCR_REG)
4989 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4990 "TARGET_80387"
4991 "fldcw\t%0"
4992 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4993 (set_attr "mode" "HI")
4994 (set_attr "unit" "i387")
4995 (set_attr "athlon_decode" "vector")
4996 (set_attr "amdfam10_decode" "vector")])
4997 \f
4998 ;; Conversion between fixed point and floating point.
4999
5000 ;; Even though we only accept memory inputs, the backend _really_
5001 ;; wants to be able to do this between registers.
5002
5003 (define_expand "floathi<mode>2"
5004 [(set (match_operand:X87MODEF 0 "register_operand" "")
5005 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5006 "TARGET_80387
5007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5008 || TARGET_MIX_SSE_I387)"
5009 "")
5010
5011 ;; Pre-reload splitter to add memory clobber to the pattern.
5012 (define_insn_and_split "*floathi<mode>2_1"
5013 [(set (match_operand:X87MODEF 0 "register_operand" "")
5014 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5015 "TARGET_80387
5016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5017 || TARGET_MIX_SSE_I387)
5018 && can_create_pseudo_p ()"
5019 "#"
5020 "&& 1"
5021 [(parallel [(set (match_dup 0)
5022 (float:X87MODEF (match_dup 1)))
5023 (clobber (match_dup 2))])]
5024 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5025
5026 (define_insn "*floathi<mode>2_i387_with_temp"
5027 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5028 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5029 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5030 "TARGET_80387
5031 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5032 || TARGET_MIX_SSE_I387)"
5033 "#"
5034 [(set_attr "type" "fmov,multi")
5035 (set_attr "mode" "<MODE>")
5036 (set_attr "unit" "*,i387")
5037 (set_attr "fp_int_src" "true")])
5038
5039 (define_insn "*floathi<mode>2_i387"
5040 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5041 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5042 "TARGET_80387
5043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5044 || TARGET_MIX_SSE_I387)"
5045 "fild%Z1\t%1"
5046 [(set_attr "type" "fmov")
5047 (set_attr "mode" "<MODE>")
5048 (set_attr "fp_int_src" "true")])
5049
5050 (define_split
5051 [(set (match_operand:X87MODEF 0 "register_operand" "")
5052 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5053 (clobber (match_operand:HI 2 "memory_operand" ""))]
5054 "TARGET_80387
5055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5056 || TARGET_MIX_SSE_I387)
5057 && reload_completed"
5058 [(set (match_dup 2) (match_dup 1))
5059 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5060 "")
5061
5062 (define_split
5063 [(set (match_operand:X87MODEF 0 "register_operand" "")
5064 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5065 (clobber (match_operand:HI 2 "memory_operand" ""))]
5066 "TARGET_80387
5067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5068 || TARGET_MIX_SSE_I387)
5069 && reload_completed"
5070 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5071 "")
5072
5073 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5074 [(set (match_operand:X87MODEF 0 "register_operand" "")
5075 (float:X87MODEF
5076 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5077 "TARGET_80387
5078 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5080 {
5081 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5082 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5083 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5084 {
5085 rtx reg = gen_reg_rtx (XFmode);
5086 rtx insn;
5087
5088 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5089
5090 if (<X87MODEF:MODE>mode == SFmode)
5091 insn = gen_truncxfsf2 (operands[0], reg);
5092 else if (<X87MODEF:MODE>mode == DFmode)
5093 insn = gen_truncxfdf2 (operands[0], reg);
5094 else
5095 gcc_unreachable ();
5096
5097 emit_insn (insn);
5098 DONE;
5099 }
5100 })
5101
5102 ;; Pre-reload splitter to add memory clobber to the pattern.
5103 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5104 [(set (match_operand:X87MODEF 0 "register_operand" "")
5105 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5106 "((TARGET_80387
5107 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5108 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5109 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5110 || TARGET_MIX_SSE_I387))
5111 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5112 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5113 && ((<SSEMODEI24:MODE>mode == SImode
5114 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5115 && optimize_function_for_speed_p (cfun)
5116 && flag_trapping_math)
5117 || !(TARGET_INTER_UNIT_CONVERSIONS
5118 || optimize_function_for_size_p (cfun)))))
5119 && can_create_pseudo_p ()"
5120 "#"
5121 "&& 1"
5122 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5123 (clobber (match_dup 2))])]
5124 {
5125 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5126
5127 /* Avoid store forwarding (partial memory) stall penalty
5128 by passing DImode value through XMM registers. */
5129 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5130 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5131 && optimize_function_for_speed_p (cfun))
5132 {
5133 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5134 operands[1],
5135 operands[2]));
5136 DONE;
5137 }
5138 })
5139
5140 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5141 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5142 (float:MODEF
5143 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5144 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5145 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5146 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5147 "#"
5148 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5149 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5150 (set_attr "unit" "*,i387,*,*,*")
5151 (set_attr "athlon_decode" "*,*,double,direct,double")
5152 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5153 (set_attr "fp_int_src" "true")])
5154
5155 (define_insn "*floatsi<mode>2_vector_mixed"
5156 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5157 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5158 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5159 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5160 "@
5161 fild%Z1\t%1
5162 #"
5163 [(set_attr "type" "fmov,sseicvt")
5164 (set_attr "mode" "<MODE>,<ssevecmode>")
5165 (set_attr "unit" "i387,*")
5166 (set_attr "athlon_decode" "*,direct")
5167 (set_attr "amdfam10_decode" "*,double")
5168 (set_attr "fp_int_src" "true")])
5169
5170 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5171 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5172 (float:MODEF
5173 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5174 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5175 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5177 "#"
5178 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5179 (set_attr "mode" "<MODEF:MODE>")
5180 (set_attr "unit" "*,i387,*,*")
5181 (set_attr "athlon_decode" "*,*,double,direct")
5182 (set_attr "amdfam10_decode" "*,*,vector,double")
5183 (set_attr "fp_int_src" "true")])
5184
5185 (define_split
5186 [(set (match_operand:MODEF 0 "register_operand" "")
5187 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5188 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5189 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5191 && TARGET_INTER_UNIT_CONVERSIONS
5192 && reload_completed
5193 && (SSE_REG_P (operands[0])
5194 || (GET_CODE (operands[0]) == SUBREG
5195 && SSE_REG_P (operands[0])))"
5196 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5197 "")
5198
5199 (define_split
5200 [(set (match_operand:MODEF 0 "register_operand" "")
5201 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5202 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5203 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5204 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5205 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5206 && reload_completed
5207 && (SSE_REG_P (operands[0])
5208 || (GET_CODE (operands[0]) == SUBREG
5209 && SSE_REG_P (operands[0])))"
5210 [(set (match_dup 2) (match_dup 1))
5211 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5212 "")
5213
5214 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5215 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5216 (float:MODEF
5217 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5218 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5220 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5221 "@
5222 fild%Z1\t%1
5223 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5224 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5225 [(set_attr "type" "fmov,sseicvt,sseicvt")
5226 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5227 (set_attr "mode" "<MODEF:MODE>")
5228 (set (attr "prefix_rex")
5229 (if_then_else
5230 (and (eq_attr "prefix" "maybe_vex")
5231 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5232 (const_string "1")
5233 (const_string "*")))
5234 (set_attr "unit" "i387,*,*")
5235 (set_attr "athlon_decode" "*,double,direct")
5236 (set_attr "amdfam10_decode" "*,vector,double")
5237 (set_attr "fp_int_src" "true")])
5238
5239 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5240 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5241 (float:MODEF
5242 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5243 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5245 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5246 "@
5247 fild%Z1\t%1
5248 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5249 [(set_attr "type" "fmov,sseicvt")
5250 (set_attr "prefix" "orig,maybe_vex")
5251 (set_attr "mode" "<MODEF:MODE>")
5252 (set (attr "prefix_rex")
5253 (if_then_else
5254 (and (eq_attr "prefix" "maybe_vex")
5255 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5256 (const_string "1")
5257 (const_string "*")))
5258 (set_attr "athlon_decode" "*,direct")
5259 (set_attr "amdfam10_decode" "*,double")
5260 (set_attr "fp_int_src" "true")])
5261
5262 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5263 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5264 (float:MODEF
5265 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5266 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5267 "TARGET_SSE2 && TARGET_SSE_MATH
5268 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5269 "#"
5270 [(set_attr "type" "sseicvt")
5271 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5272 (set_attr "athlon_decode" "double,direct,double")
5273 (set_attr "amdfam10_decode" "vector,double,double")
5274 (set_attr "fp_int_src" "true")])
5275
5276 (define_insn "*floatsi<mode>2_vector_sse"
5277 [(set (match_operand:MODEF 0 "register_operand" "=x")
5278 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5279 "TARGET_SSE2 && TARGET_SSE_MATH
5280 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5281 "#"
5282 [(set_attr "type" "sseicvt")
5283 (set_attr "mode" "<MODE>")
5284 (set_attr "athlon_decode" "direct")
5285 (set_attr "amdfam10_decode" "double")
5286 (set_attr "fp_int_src" "true")])
5287
5288 (define_split
5289 [(set (match_operand:MODEF 0 "register_operand" "")
5290 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5291 (clobber (match_operand:SI 2 "memory_operand" ""))]
5292 "TARGET_SSE2 && TARGET_SSE_MATH
5293 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5294 && reload_completed
5295 && (SSE_REG_P (operands[0])
5296 || (GET_CODE (operands[0]) == SUBREG
5297 && SSE_REG_P (operands[0])))"
5298 [(const_int 0)]
5299 {
5300 rtx op1 = operands[1];
5301
5302 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5303 <MODE>mode, 0);
5304 if (GET_CODE (op1) == SUBREG)
5305 op1 = SUBREG_REG (op1);
5306
5307 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5308 {
5309 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5310 emit_insn (gen_sse2_loadld (operands[4],
5311 CONST0_RTX (V4SImode), operands[1]));
5312 }
5313 /* We can ignore possible trapping value in the
5314 high part of SSE register for non-trapping math. */
5315 else if (SSE_REG_P (op1) && !flag_trapping_math)
5316 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5317 else
5318 {
5319 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5320 emit_move_insn (operands[2], operands[1]);
5321 emit_insn (gen_sse2_loadld (operands[4],
5322 CONST0_RTX (V4SImode), operands[2]));
5323 }
5324 emit_insn
5325 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5326 DONE;
5327 })
5328
5329 (define_split
5330 [(set (match_operand:MODEF 0 "register_operand" "")
5331 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5332 (clobber (match_operand:SI 2 "memory_operand" ""))]
5333 "TARGET_SSE2 && TARGET_SSE_MATH
5334 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5335 && reload_completed
5336 && (SSE_REG_P (operands[0])
5337 || (GET_CODE (operands[0]) == SUBREG
5338 && SSE_REG_P (operands[0])))"
5339 [(const_int 0)]
5340 {
5341 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5342 <MODE>mode, 0);
5343 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5344
5345 emit_insn (gen_sse2_loadld (operands[4],
5346 CONST0_RTX (V4SImode), operands[1]));
5347 emit_insn
5348 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5349 DONE;
5350 })
5351
5352 (define_split
5353 [(set (match_operand:MODEF 0 "register_operand" "")
5354 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5355 "TARGET_SSE2 && TARGET_SSE_MATH
5356 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5357 && reload_completed
5358 && (SSE_REG_P (operands[0])
5359 || (GET_CODE (operands[0]) == SUBREG
5360 && SSE_REG_P (operands[0])))"
5361 [(const_int 0)]
5362 {
5363 rtx op1 = operands[1];
5364
5365 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5366 <MODE>mode, 0);
5367 if (GET_CODE (op1) == SUBREG)
5368 op1 = SUBREG_REG (op1);
5369
5370 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5371 {
5372 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5373 emit_insn (gen_sse2_loadld (operands[4],
5374 CONST0_RTX (V4SImode), operands[1]));
5375 }
5376 /* We can ignore possible trapping value in the
5377 high part of SSE register for non-trapping math. */
5378 else if (SSE_REG_P (op1) && !flag_trapping_math)
5379 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5380 else
5381 gcc_unreachable ();
5382 emit_insn
5383 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5384 DONE;
5385 })
5386
5387 (define_split
5388 [(set (match_operand:MODEF 0 "register_operand" "")
5389 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5390 "TARGET_SSE2 && TARGET_SSE_MATH
5391 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5392 && reload_completed
5393 && (SSE_REG_P (operands[0])
5394 || (GET_CODE (operands[0]) == SUBREG
5395 && SSE_REG_P (operands[0])))"
5396 [(const_int 0)]
5397 {
5398 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5399 <MODE>mode, 0);
5400 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5401
5402 emit_insn (gen_sse2_loadld (operands[4],
5403 CONST0_RTX (V4SImode), operands[1]));
5404 emit_insn
5405 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5406 DONE;
5407 })
5408
5409 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5410 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5411 (float:MODEF
5412 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5413 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5414 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5415 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5416 "#"
5417 [(set_attr "type" "sseicvt")
5418 (set_attr "mode" "<MODEF:MODE>")
5419 (set_attr "athlon_decode" "double,direct")
5420 (set_attr "amdfam10_decode" "vector,double")
5421 (set_attr "fp_int_src" "true")])
5422
5423 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5424 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5425 (float:MODEF
5426 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5427 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5428 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5429 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5430 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5431 [(set_attr "type" "sseicvt")
5432 (set_attr "prefix" "maybe_vex")
5433 (set_attr "mode" "<MODEF:MODE>")
5434 (set (attr "prefix_rex")
5435 (if_then_else
5436 (and (eq_attr "prefix" "maybe_vex")
5437 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5438 (const_string "1")
5439 (const_string "*")))
5440 (set_attr "athlon_decode" "double,direct")
5441 (set_attr "amdfam10_decode" "vector,double")
5442 (set_attr "fp_int_src" "true")])
5443
5444 (define_split
5445 [(set (match_operand:MODEF 0 "register_operand" "")
5446 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5447 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5448 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5449 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5450 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5451 && reload_completed
5452 && (SSE_REG_P (operands[0])
5453 || (GET_CODE (operands[0]) == SUBREG
5454 && SSE_REG_P (operands[0])))"
5455 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5456 "")
5457
5458 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5459 [(set (match_operand:MODEF 0 "register_operand" "=x")
5460 (float:MODEF
5461 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5462 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5463 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5464 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5465 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5466 [(set_attr "type" "sseicvt")
5467 (set_attr "prefix" "maybe_vex")
5468 (set_attr "mode" "<MODEF:MODE>")
5469 (set (attr "prefix_rex")
5470 (if_then_else
5471 (and (eq_attr "prefix" "maybe_vex")
5472 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5473 (const_string "1")
5474 (const_string "*")))
5475 (set_attr "athlon_decode" "direct")
5476 (set_attr "amdfam10_decode" "double")
5477 (set_attr "fp_int_src" "true")])
5478
5479 (define_split
5480 [(set (match_operand:MODEF 0 "register_operand" "")
5481 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5482 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5483 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5486 && reload_completed
5487 && (SSE_REG_P (operands[0])
5488 || (GET_CODE (operands[0]) == SUBREG
5489 && SSE_REG_P (operands[0])))"
5490 [(set (match_dup 2) (match_dup 1))
5491 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5492 "")
5493
5494 (define_split
5495 [(set (match_operand:MODEF 0 "register_operand" "")
5496 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5497 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500 && reload_completed
5501 && (SSE_REG_P (operands[0])
5502 || (GET_CODE (operands[0]) == SUBREG
5503 && SSE_REG_P (operands[0])))"
5504 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5505 "")
5506
5507 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5508 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5509 (float:X87MODEF
5510 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5511 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5512 "TARGET_80387
5513 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5514 "@
5515 fild%Z1\t%1
5516 #"
5517 [(set_attr "type" "fmov,multi")
5518 (set_attr "mode" "<X87MODEF:MODE>")
5519 (set_attr "unit" "*,i387")
5520 (set_attr "fp_int_src" "true")])
5521
5522 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5523 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5524 (float:X87MODEF
5525 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5526 "TARGET_80387
5527 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5528 "fild%Z1\t%1"
5529 [(set_attr "type" "fmov")
5530 (set_attr "mode" "<X87MODEF:MODE>")
5531 (set_attr "fp_int_src" "true")])
5532
5533 (define_split
5534 [(set (match_operand:X87MODEF 0 "register_operand" "")
5535 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5536 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5537 "TARGET_80387
5538 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5539 && reload_completed
5540 && FP_REG_P (operands[0])"
5541 [(set (match_dup 2) (match_dup 1))
5542 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5543 "")
5544
5545 (define_split
5546 [(set (match_operand:X87MODEF 0 "register_operand" "")
5547 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5548 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5549 "TARGET_80387
5550 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5551 && reload_completed
5552 && FP_REG_P (operands[0])"
5553 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5554 "")
5555
5556 ;; Avoid store forwarding (partial memory) stall penalty
5557 ;; by passing DImode value through XMM registers. */
5558
5559 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5560 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5561 (float:X87MODEF
5562 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5563 (clobber (match_scratch:V4SI 3 "=X,x"))
5564 (clobber (match_scratch:V4SI 4 "=X,x"))
5565 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5566 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5567 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5568 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5569 "#"
5570 [(set_attr "type" "multi")
5571 (set_attr "mode" "<X87MODEF:MODE>")
5572 (set_attr "unit" "i387")
5573 (set_attr "fp_int_src" "true")])
5574
5575 (define_split
5576 [(set (match_operand:X87MODEF 0 "register_operand" "")
5577 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5578 (clobber (match_scratch:V4SI 3 ""))
5579 (clobber (match_scratch:V4SI 4 ""))
5580 (clobber (match_operand:DI 2 "memory_operand" ""))]
5581 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5582 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5583 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5584 && reload_completed
5585 && FP_REG_P (operands[0])"
5586 [(set (match_dup 2) (match_dup 3))
5587 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5588 {
5589 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5590 Assemble the 64-bit DImode value in an xmm register. */
5591 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5592 gen_rtx_SUBREG (SImode, operands[1], 0)));
5593 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5594 gen_rtx_SUBREG (SImode, operands[1], 4)));
5595 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5596 operands[4]));
5597
5598 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5599 })
5600
5601 (define_split
5602 [(set (match_operand:X87MODEF 0 "register_operand" "")
5603 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5604 (clobber (match_scratch:V4SI 3 ""))
5605 (clobber (match_scratch:V4SI 4 ""))
5606 (clobber (match_operand:DI 2 "memory_operand" ""))]
5607 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5608 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5609 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5610 && reload_completed
5611 && FP_REG_P (operands[0])"
5612 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5613 "")
5614
5615 ;; Avoid store forwarding (partial memory) stall penalty by extending
5616 ;; SImode value to DImode through XMM register instead of pushing two
5617 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5618 ;; targets benefit from this optimization. Also note that fild
5619 ;; loads from memory only.
5620
5621 (define_insn "*floatunssi<mode>2_1"
5622 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5623 (unsigned_float:X87MODEF
5624 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5625 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5626 (clobber (match_scratch:SI 3 "=X,x"))]
5627 "!TARGET_64BIT
5628 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5629 && TARGET_SSE"
5630 "#"
5631 [(set_attr "type" "multi")
5632 (set_attr "mode" "<MODE>")])
5633
5634 (define_split
5635 [(set (match_operand:X87MODEF 0 "register_operand" "")
5636 (unsigned_float:X87MODEF
5637 (match_operand:SI 1 "register_operand" "")))
5638 (clobber (match_operand:DI 2 "memory_operand" ""))
5639 (clobber (match_scratch:SI 3 ""))]
5640 "!TARGET_64BIT
5641 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5642 && TARGET_SSE
5643 && reload_completed"
5644 [(set (match_dup 2) (match_dup 1))
5645 (set (match_dup 0)
5646 (float:X87MODEF (match_dup 2)))]
5647 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5648
5649 (define_split
5650 [(set (match_operand:X87MODEF 0 "register_operand" "")
5651 (unsigned_float:X87MODEF
5652 (match_operand:SI 1 "memory_operand" "")))
5653 (clobber (match_operand:DI 2 "memory_operand" ""))
5654 (clobber (match_scratch:SI 3 ""))]
5655 "!TARGET_64BIT
5656 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5657 && TARGET_SSE
5658 && reload_completed"
5659 [(set (match_dup 2) (match_dup 3))
5660 (set (match_dup 0)
5661 (float:X87MODEF (match_dup 2)))]
5662 {
5663 emit_move_insn (operands[3], operands[1]);
5664 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5665 })
5666
5667 (define_expand "floatunssi<mode>2"
5668 [(parallel
5669 [(set (match_operand:X87MODEF 0 "register_operand" "")
5670 (unsigned_float:X87MODEF
5671 (match_operand:SI 1 "nonimmediate_operand" "")))
5672 (clobber (match_dup 2))
5673 (clobber (match_scratch:SI 3 ""))])]
5674 "!TARGET_64BIT
5675 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5676 && TARGET_SSE)
5677 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5678 {
5679 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5680 {
5681 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5682 DONE;
5683 }
5684 else
5685 {
5686 enum ix86_stack_slot slot = (virtuals_instantiated
5687 ? SLOT_TEMP
5688 : SLOT_VIRTUAL);
5689 operands[2] = assign_386_stack_local (DImode, slot);
5690 }
5691 })
5692
5693 (define_expand "floatunsdisf2"
5694 [(use (match_operand:SF 0 "register_operand" ""))
5695 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5696 "TARGET_64BIT && TARGET_SSE_MATH"
5697 "x86_emit_floatuns (operands); DONE;")
5698
5699 (define_expand "floatunsdidf2"
5700 [(use (match_operand:DF 0 "register_operand" ""))
5701 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5702 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5703 && TARGET_SSE2 && TARGET_SSE_MATH"
5704 {
5705 if (TARGET_64BIT)
5706 x86_emit_floatuns (operands);
5707 else
5708 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5709 DONE;
5710 })
5711 \f
5712 ;; Add instructions
5713
5714 (define_expand "add<mode>3"
5715 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5716 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5717 (match_operand:SDWIM 2 "<general_operand>" "")))]
5718 ""
5719 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5720
5721 (define_insn_and_split "*add<dwi>3_doubleword"
5722 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5723 (plus:<DWI>
5724 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5725 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5726 (clobber (reg:CC FLAGS_REG))]
5727 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5728 "#"
5729 "reload_completed"
5730 [(parallel [(set (reg:CC FLAGS_REG)
5731 (unspec:CC [(match_dup 1) (match_dup 2)]
5732 UNSPEC_ADD_CARRY))
5733 (set (match_dup 0)
5734 (plus:DWIH (match_dup 1) (match_dup 2)))])
5735 (parallel [(set (match_dup 3)
5736 (plus:DWIH
5737 (match_dup 4)
5738 (plus:DWIH
5739 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5740 (match_dup 5))))
5741 (clobber (reg:CC FLAGS_REG))])]
5742 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5743
5744 (define_insn "*add<mode>3_cc"
5745 [(set (reg:CC FLAGS_REG)
5746 (unspec:CC
5747 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5748 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5749 UNSPEC_ADD_CARRY))
5750 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5751 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5752 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5753 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5754 [(set_attr "type" "alu")
5755 (set_attr "mode" "<MODE>")])
5756
5757 (define_insn "addqi3_cc"
5758 [(set (reg:CC FLAGS_REG)
5759 (unspec:CC
5760 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5761 (match_operand:QI 2 "general_operand" "qn,qm")]
5762 UNSPEC_ADD_CARRY))
5763 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5764 (plus:QI (match_dup 1) (match_dup 2)))]
5765 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5766 "add{b}\t{%2, %0|%0, %2}"
5767 [(set_attr "type" "alu")
5768 (set_attr "mode" "QI")])
5769
5770 (define_insn "*lea_1"
5771 [(set (match_operand:DWIH 0 "register_operand" "=r")
5772 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5773 ""
5774 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5775 [(set_attr "type" "lea")
5776 (set_attr "mode" "<MODE>")])
5777
5778 (define_insn "*lea_2"
5779 [(set (match_operand:SI 0 "register_operand" "=r")
5780 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5781 "TARGET_64BIT"
5782 "lea{l}\t{%a1, %0|%0, %a1}"
5783 [(set_attr "type" "lea")
5784 (set_attr "mode" "SI")])
5785
5786 (define_insn "*lea_2_zext"
5787 [(set (match_operand:DI 0 "register_operand" "=r")
5788 (zero_extend:DI
5789 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5790 "TARGET_64BIT"
5791 "lea{l}\t{%a1, %k0|%k0, %a1}"
5792 [(set_attr "type" "lea")
5793 (set_attr "mode" "SI")])
5794
5795 (define_insn "*add<mode>_1"
5796 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5797 (plus:SWI48
5798 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5799 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5800 (clobber (reg:CC FLAGS_REG))]
5801 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5802 {
5803 switch (get_attr_type (insn))
5804 {
5805 case TYPE_LEA:
5806 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5807 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5808
5809 case TYPE_INCDEC:
5810 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5811 if (operands[2] == const1_rtx)
5812 return "inc{<imodesuffix>}\t%0";
5813 else
5814 {
5815 gcc_assert (operands[2] == constm1_rtx);
5816 return "dec{<imodesuffix>}\t%0";
5817 }
5818
5819 default:
5820 /* Use add as much as possible to replace lea for AGU optimization. */
5821 if (which_alternative == 2 && TARGET_OPT_AGU)
5822 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
5823
5824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5826 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5827
5828 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5829 }
5830 }
5831 [(set (attr "type")
5832 (cond [(and (eq_attr "alternative" "2")
5833 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
5834 (const_string "lea")
5835 (eq_attr "alternative" "3")
5836 (const_string "lea")
5837 (match_operand:SWI48 2 "incdec_operand" "")
5838 (const_string "incdec")
5839 ]
5840 (const_string "alu")))
5841 (set (attr "length_immediate")
5842 (if_then_else
5843 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5844 (const_string "1")
5845 (const_string "*")))
5846 (set_attr "mode" "<MODE>")])
5847
5848 ;; It may seem that nonimmediate operand is proper one for operand 1.
5849 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5850 ;; we take care in ix86_binary_operator_ok to not allow two memory
5851 ;; operands so proper swapping will be done in reload. This allow
5852 ;; patterns constructed from addsi_1 to match.
5853
5854 (define_insn "*addsi_1_zext"
5855 [(set (match_operand:DI 0 "register_operand" "=r,r")
5856 (zero_extend:DI
5857 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5858 (match_operand:SI 2 "general_operand" "g,li"))))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5861 {
5862 switch (get_attr_type (insn))
5863 {
5864 case TYPE_LEA:
5865 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
5866 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5867
5868 case TYPE_INCDEC:
5869 if (operands[2] == const1_rtx)
5870 return "inc{l}\t%k0";
5871 else
5872 {
5873 gcc_assert (operands[2] == constm1_rtx);
5874 return "dec{l}\t%k0";
5875 }
5876
5877 default:
5878 if (x86_maybe_negate_const_int (&operands[2], SImode))
5879 return "sub{l}\t{%2, %k0|%k0, %2}";
5880
5881 return "add{l}\t{%2, %k0|%k0, %2}";
5882 }
5883 }
5884 [(set (attr "type")
5885 (cond [(eq_attr "alternative" "1")
5886 (const_string "lea")
5887 (match_operand:SI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 ]
5890 (const_string "alu")))
5891 (set (attr "length_immediate")
5892 (if_then_else
5893 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5894 (const_string "1")
5895 (const_string "*")))
5896 (set_attr "mode" "SI")])
5897
5898 (define_insn "*addhi_1"
5899 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5900 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5901 (match_operand:HI 2 "general_operand" "rn,rm")))
5902 (clobber (reg:CC FLAGS_REG))]
5903 "TARGET_PARTIAL_REG_STALL
5904 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5905 {
5906 switch (get_attr_type (insn))
5907 {
5908 case TYPE_INCDEC:
5909 if (operands[2] == const1_rtx)
5910 return "inc{w}\t%0";
5911 else
5912 {
5913 gcc_assert (operands[2] == constm1_rtx);
5914 return "dec{w}\t%0";
5915 }
5916
5917 default:
5918 if (x86_maybe_negate_const_int (&operands[2], HImode))
5919 return "sub{w}\t{%2, %0|%0, %2}";
5920
5921 return "add{w}\t{%2, %0|%0, %2}";
5922 }
5923 }
5924 [(set (attr "type")
5925 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set (attr "length_immediate")
5929 (if_then_else
5930 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5931 (const_string "1")
5932 (const_string "*")))
5933 (set_attr "mode" "HI")])
5934
5935 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5936 ;; type optimizations enabled by define-splits. This is not important
5937 ;; for PII, and in fact harmful because of partial register stalls.
5938
5939 (define_insn "*addhi_1_lea"
5940 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5941 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5942 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
5943 (clobber (reg:CC FLAGS_REG))]
5944 "!TARGET_PARTIAL_REG_STALL
5945 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5946 {
5947 switch (get_attr_type (insn))
5948 {
5949 case TYPE_LEA:
5950 return "#";
5951
5952 case TYPE_INCDEC:
5953 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5954 if (operands[2] == const1_rtx)
5955 return "inc{w}\t%0";
5956 else
5957 {
5958 gcc_assert (operands[2] == constm1_rtx);
5959 return "dec{w}\t%0";
5960 }
5961
5962 default:
5963 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964 if (x86_maybe_negate_const_int (&operands[2], HImode))
5965 return "sub{w}\t{%2, %0|%0, %2}";
5966
5967 return "add{w}\t{%2, %0|%0, %2}";
5968 }
5969 }
5970 [(set (attr "type")
5971 (if_then_else (eq_attr "alternative" "2")
5972 (const_string "lea")
5973 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974 (const_string "incdec")
5975 (const_string "alu"))))
5976 (set (attr "length_immediate")
5977 (if_then_else
5978 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5979 (const_string "1")
5980 (const_string "*")))
5981 (set_attr "mode" "HI,HI,SI")])
5982
5983 (define_insn "*addqi_1"
5984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5985 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5986 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5987 (clobber (reg:CC FLAGS_REG))]
5988 "TARGET_PARTIAL_REG_STALL
5989 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5990 {
5991 int widen = (which_alternative == 2);
5992 switch (get_attr_type (insn))
5993 {
5994 case TYPE_INCDEC:
5995 if (operands[2] == const1_rtx)
5996 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5997 else
5998 {
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6001 }
6002
6003 default:
6004 if (x86_maybe_negate_const_int (&operands[2], QImode))
6005 {
6006 if (widen)
6007 return "sub{l}\t{%2, %k0|%k0, %2}";
6008 else
6009 return "sub{b}\t{%2, %0|%0, %2}";
6010 }
6011 if (widen)
6012 return "add{l}\t{%k2, %k0|%k0, %k2}";
6013 else
6014 return "add{b}\t{%2, %0|%0, %2}";
6015 }
6016 }
6017 [(set (attr "type")
6018 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set (attr "length_immediate")
6022 (if_then_else
6023 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6024 (const_string "1")
6025 (const_string "*")))
6026 (set_attr "mode" "QI,QI,SI")])
6027
6028 ;; %%% Potential partial reg stall on alternative 2. What to do?
6029 (define_insn "*addqi_1_lea"
6030 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033 (clobber (reg:CC FLAGS_REG))]
6034 "!TARGET_PARTIAL_REG_STALL
6035 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6036 {
6037 int widen = (which_alternative == 2);
6038 switch (get_attr_type (insn))
6039 {
6040 case TYPE_LEA:
6041 return "#";
6042
6043 case TYPE_INCDEC:
6044 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6045 if (operands[2] == const1_rtx)
6046 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6047 else
6048 {
6049 gcc_assert (operands[2] == constm1_rtx);
6050 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6051 }
6052
6053 default:
6054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055 if (x86_maybe_negate_const_int (&operands[2], QImode))
6056 {
6057 if (widen)
6058 return "sub{l}\t{%2, %k0|%k0, %2}";
6059 else
6060 return "sub{b}\t{%2, %0|%0, %2}";
6061 }
6062 if (widen)
6063 return "add{l}\t{%k2, %k0|%k0, %k2}";
6064 else
6065 return "add{b}\t{%2, %0|%0, %2}";
6066 }
6067 }
6068 [(set (attr "type")
6069 (if_then_else (eq_attr "alternative" "3")
6070 (const_string "lea")
6071 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6072 (const_string "incdec")
6073 (const_string "alu"))))
6074 (set (attr "length_immediate")
6075 (if_then_else
6076 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6077 (const_string "1")
6078 (const_string "*")))
6079 (set_attr "mode" "QI,QI,SI,SI")])
6080
6081 (define_insn "*addqi_1_slp"
6082 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6083 (plus:QI (match_dup 0)
6084 (match_operand:QI 1 "general_operand" "qn,qnm")))
6085 (clobber (reg:CC FLAGS_REG))]
6086 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6087 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6088 {
6089 switch (get_attr_type (insn))
6090 {
6091 case TYPE_INCDEC:
6092 if (operands[1] == const1_rtx)
6093 return "inc{b}\t%0";
6094 else
6095 {
6096 gcc_assert (operands[1] == constm1_rtx);
6097 return "dec{b}\t%0";
6098 }
6099
6100 default:
6101 if (x86_maybe_negate_const_int (&operands[1], QImode))
6102 return "sub{b}\t{%1, %0|%0, %1}";
6103
6104 return "add{b}\t{%1, %0|%0, %1}";
6105 }
6106 }
6107 [(set (attr "type")
6108 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6109 (const_string "incdec")
6110 (const_string "alu1")))
6111 (set (attr "memory")
6112 (if_then_else (match_operand 1 "memory_operand" "")
6113 (const_string "load")
6114 (const_string "none")))
6115 (set_attr "mode" "QI")])
6116
6117 (define_insn "*add<mode>_2"
6118 [(set (reg FLAGS_REG)
6119 (compare
6120 (plus:SWI
6121 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6122 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6123 (const_int 0)))
6124 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6125 (plus:SWI (match_dup 1) (match_dup 2)))]
6126 "ix86_match_ccmode (insn, CCGOCmode)
6127 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6128 {
6129 switch (get_attr_type (insn))
6130 {
6131 case TYPE_INCDEC:
6132 if (operands[2] == const1_rtx)
6133 return "inc{<imodesuffix>}\t%0";
6134 else
6135 {
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return "dec{<imodesuffix>}\t%0";
6138 }
6139
6140 default:
6141 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6142 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6143
6144 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6145 }
6146 }
6147 [(set (attr "type")
6148 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6149 (const_string "incdec")
6150 (const_string "alu")))
6151 (set (attr "length_immediate")
6152 (if_then_else
6153 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6154 (const_string "1")
6155 (const_string "*")))
6156 (set_attr "mode" "<MODE>")])
6157
6158 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6159 (define_insn "*addsi_2_zext"
6160 [(set (reg FLAGS_REG)
6161 (compare
6162 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6163 (match_operand:SI 2 "general_operand" "g"))
6164 (const_int 0)))
6165 (set (match_operand:DI 0 "register_operand" "=r")
6166 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6167 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6168 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6169 {
6170 switch (get_attr_type (insn))
6171 {
6172 case TYPE_INCDEC:
6173 if (operands[2] == const1_rtx)
6174 return "inc{l}\t%k0";
6175 else
6176 {
6177 gcc_assert (operands[2] == constm1_rtx);
6178 return "dec{l}\t%k0";
6179 }
6180
6181 default:
6182 if (x86_maybe_negate_const_int (&operands[2], SImode))
6183 return "sub{l}\t{%2, %k0|%k0, %2}";
6184
6185 return "add{l}\t{%2, %k0|%k0, %2}";
6186 }
6187 }
6188 [(set (attr "type")
6189 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6190 (const_string "incdec")
6191 (const_string "alu")))
6192 (set (attr "length_immediate")
6193 (if_then_else
6194 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6195 (const_string "1")
6196 (const_string "*")))
6197 (set_attr "mode" "SI")])
6198
6199 (define_insn "*add<mode>_3"
6200 [(set (reg FLAGS_REG)
6201 (compare
6202 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6203 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6204 (clobber (match_scratch:SWI 0 "=<r>"))]
6205 "ix86_match_ccmode (insn, CCZmode)
6206 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6207 {
6208 switch (get_attr_type (insn))
6209 {
6210 case TYPE_INCDEC:
6211 if (operands[2] == const1_rtx)
6212 return "inc{<imodesuffix>}\t%0";
6213 else
6214 {
6215 gcc_assert (operands[2] == constm1_rtx);
6216 return "dec{<imodesuffix>}\t%0";
6217 }
6218
6219 default:
6220 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6221 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6222
6223 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6224 }
6225 }
6226 [(set (attr "type")
6227 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6228 (const_string "incdec")
6229 (const_string "alu")))
6230 (set (attr "length_immediate")
6231 (if_then_else
6232 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6233 (const_string "1")
6234 (const_string "*")))
6235 (set_attr "mode" "<MODE>")])
6236
6237 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6238 (define_insn "*addsi_3_zext"
6239 [(set (reg FLAGS_REG)
6240 (compare
6241 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6242 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6243 (set (match_operand:DI 0 "register_operand" "=r")
6244 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6245 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6246 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6247 {
6248 switch (get_attr_type (insn))
6249 {
6250 case TYPE_INCDEC:
6251 if (operands[2] == const1_rtx)
6252 return "inc{l}\t%k0";
6253 else
6254 {
6255 gcc_assert (operands[2] == constm1_rtx);
6256 return "dec{l}\t%k0";
6257 }
6258
6259 default:
6260 if (x86_maybe_negate_const_int (&operands[2], SImode))
6261 return "sub{l}\t{%2, %k0|%k0, %2}";
6262
6263 return "add{l}\t{%2, %k0|%k0, %2}";
6264 }
6265 }
6266 [(set (attr "type")
6267 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6268 (const_string "incdec")
6269 (const_string "alu")))
6270 (set (attr "length_immediate")
6271 (if_then_else
6272 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6273 (const_string "1")
6274 (const_string "*")))
6275 (set_attr "mode" "SI")])
6276
6277 ; For comparisons against 1, -1 and 128, we may generate better code
6278 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6279 ; is matched then. We can't accept general immediate, because for
6280 ; case of overflows, the result is messed up.
6281 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6282 ; only for comparisons not depending on it.
6283
6284 (define_insn "*adddi_4"
6285 [(set (reg FLAGS_REG)
6286 (compare
6287 (match_operand:DI 1 "nonimmediate_operand" "0")
6288 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6289 (clobber (match_scratch:DI 0 "=rm"))]
6290 "TARGET_64BIT
6291 && ix86_match_ccmode (insn, CCGCmode)"
6292 {
6293 switch (get_attr_type (insn))
6294 {
6295 case TYPE_INCDEC:
6296 if (operands[2] == constm1_rtx)
6297 return "inc{q}\t%0";
6298 else
6299 {
6300 gcc_assert (operands[2] == const1_rtx);
6301 return "dec{q}\t%0";
6302 }
6303
6304 default:
6305 if (x86_maybe_negate_const_int (&operands[2], DImode))
6306 return "add{q}\t{%2, %0|%0, %2}";
6307
6308 return "sub{q}\t{%2, %0|%0, %2}";
6309 }
6310 }
6311 [(set (attr "type")
6312 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set (attr "length_immediate")
6316 (if_then_else
6317 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6318 (const_string "1")
6319 (const_string "*")))
6320 (set_attr "mode" "DI")])
6321
6322 ; For comparisons against 1, -1 and 128, we may generate better code
6323 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6324 ; is matched then. We can't accept general immediate, because for
6325 ; case of overflows, the result is messed up.
6326 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6327 ; only for comparisons not depending on it.
6328
6329 (define_insn "*add<mode>_4"
6330 [(set (reg FLAGS_REG)
6331 (compare
6332 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6333 (match_operand:SWI124 2 "const_int_operand" "n")))
6334 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6335 "ix86_match_ccmode (insn, CCGCmode)"
6336 {
6337 switch (get_attr_type (insn))
6338 {
6339 case TYPE_INCDEC:
6340 if (operands[2] == constm1_rtx)
6341 return "inc{<imodesuffix>}\t%0";
6342 else
6343 {
6344 gcc_assert (operands[2] == const1_rtx);
6345 return "dec{<imodesuffix>}\t%0";
6346 }
6347
6348 default:
6349 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6350 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6351
6352 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6353 }
6354 }
6355 [(set (attr "type")
6356 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6357 (const_string "incdec")
6358 (const_string "alu")))
6359 (set (attr "length_immediate")
6360 (if_then_else
6361 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6362 (const_string "1")
6363 (const_string "*")))
6364 (set_attr "mode" "<MODE>")])
6365
6366 (define_insn "*add<mode>_5"
6367 [(set (reg FLAGS_REG)
6368 (compare
6369 (plus:SWI
6370 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6371 (match_operand:SWI 2 "<general_operand>" "<g>"))
6372 (const_int 0)))
6373 (clobber (match_scratch:SWI 0 "=<r>"))]
6374 "ix86_match_ccmode (insn, CCGOCmode)
6375 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6376 {
6377 switch (get_attr_type (insn))
6378 {
6379 case TYPE_INCDEC:
6380 if (operands[2] == const1_rtx)
6381 return "inc{<imodesuffix>}\t%0";
6382 else
6383 {
6384 gcc_assert (operands[2] == constm1_rtx);
6385 return "dec{<imodesuffix>}\t%0";
6386 }
6387
6388 default:
6389 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6390 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6391
6392 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6393 }
6394 }
6395 [(set (attr "type")
6396 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6397 (const_string "incdec")
6398 (const_string "alu")))
6399 (set (attr "length_immediate")
6400 (if_then_else
6401 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6402 (const_string "1")
6403 (const_string "*")))
6404 (set_attr "mode" "<MODE>")])
6405
6406 (define_insn "*addqi_ext_1_rex64"
6407 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6408 (const_int 8)
6409 (const_int 8))
6410 (plus:SI
6411 (zero_extract:SI
6412 (match_operand 1 "ext_register_operand" "0")
6413 (const_int 8)
6414 (const_int 8))
6415 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6416 (clobber (reg:CC FLAGS_REG))]
6417 "TARGET_64BIT"
6418 {
6419 switch (get_attr_type (insn))
6420 {
6421 case TYPE_INCDEC:
6422 if (operands[2] == const1_rtx)
6423 return "inc{b}\t%h0";
6424 else
6425 {
6426 gcc_assert (operands[2] == constm1_rtx);
6427 return "dec{b}\t%h0";
6428 }
6429
6430 default:
6431 return "add{b}\t{%2, %h0|%h0, %2}";
6432 }
6433 }
6434 [(set (attr "type")
6435 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6436 (const_string "incdec")
6437 (const_string "alu")))
6438 (set_attr "modrm" "1")
6439 (set_attr "mode" "QI")])
6440
6441 (define_insn "addqi_ext_1"
6442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6443 (const_int 8)
6444 (const_int 8))
6445 (plus:SI
6446 (zero_extract:SI
6447 (match_operand 1 "ext_register_operand" "0")
6448 (const_int 8)
6449 (const_int 8))
6450 (match_operand:QI 2 "general_operand" "Qmn")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "!TARGET_64BIT"
6453 {
6454 switch (get_attr_type (insn))
6455 {
6456 case TYPE_INCDEC:
6457 if (operands[2] == const1_rtx)
6458 return "inc{b}\t%h0";
6459 else
6460 {
6461 gcc_assert (operands[2] == constm1_rtx);
6462 return "dec{b}\t%h0";
6463 }
6464
6465 default:
6466 return "add{b}\t{%2, %h0|%h0, %2}";
6467 }
6468 }
6469 [(set (attr "type")
6470 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6471 (const_string "incdec")
6472 (const_string "alu")))
6473 (set_attr "modrm" "1")
6474 (set_attr "mode" "QI")])
6475
6476 (define_insn "*addqi_ext_2"
6477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6478 (const_int 8)
6479 (const_int 8))
6480 (plus:SI
6481 (zero_extract:SI
6482 (match_operand 1 "ext_register_operand" "%0")
6483 (const_int 8)
6484 (const_int 8))
6485 (zero_extract:SI
6486 (match_operand 2 "ext_register_operand" "Q")
6487 (const_int 8)
6488 (const_int 8))))
6489 (clobber (reg:CC FLAGS_REG))]
6490 ""
6491 "add{b}\t{%h2, %h0|%h0, %h2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "QI")])
6494
6495 ;; The lea patterns for non-Pmodes needs to be matched by
6496 ;; several insns converted to real lea by splitters.
6497
6498 (define_insn_and_split "*lea_general_1"
6499 [(set (match_operand 0 "register_operand" "=r")
6500 (plus (plus (match_operand 1 "index_register_operand" "l")
6501 (match_operand 2 "register_operand" "r"))
6502 (match_operand 3 "immediate_operand" "i")))]
6503 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6504 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6505 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6506 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6507 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6508 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6509 || GET_MODE (operands[3]) == VOIDmode)"
6510 "#"
6511 "&& reload_completed"
6512 [(const_int 0)]
6513 {
6514 rtx pat;
6515 operands[0] = gen_lowpart (SImode, operands[0]);
6516 operands[1] = gen_lowpart (Pmode, operands[1]);
6517 operands[2] = gen_lowpart (Pmode, operands[2]);
6518 operands[3] = gen_lowpart (Pmode, operands[3]);
6519 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6520 operands[3]);
6521 if (Pmode != SImode)
6522 pat = gen_rtx_SUBREG (SImode, pat, 0);
6523 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6524 DONE;
6525 }
6526 [(set_attr "type" "lea")
6527 (set_attr "mode" "SI")])
6528
6529 (define_insn_and_split "*lea_general_1_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (zero_extend:DI
6532 (plus:SI (plus:SI
6533 (match_operand:SI 1 "index_register_operand" "l")
6534 (match_operand:SI 2 "register_operand" "r"))
6535 (match_operand:SI 3 "immediate_operand" "i"))))]
6536 "TARGET_64BIT"
6537 "#"
6538 "&& reload_completed"
6539 [(set (match_dup 0)
6540 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6541 (match_dup 2))
6542 (match_dup 3)) 0)))]
6543 {
6544 operands[1] = gen_lowpart (Pmode, operands[1]);
6545 operands[2] = gen_lowpart (Pmode, operands[2]);
6546 operands[3] = gen_lowpart (Pmode, operands[3]);
6547 }
6548 [(set_attr "type" "lea")
6549 (set_attr "mode" "SI")])
6550
6551 (define_insn_and_split "*lea_general_2"
6552 [(set (match_operand 0 "register_operand" "=r")
6553 (plus (mult (match_operand 1 "index_register_operand" "l")
6554 (match_operand 2 "const248_operand" "i"))
6555 (match_operand 3 "nonmemory_operand" "ri")))]
6556 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6557 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6558 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6559 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6560 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6561 || GET_MODE (operands[3]) == VOIDmode)"
6562 "#"
6563 "&& reload_completed"
6564 [(const_int 0)]
6565 {
6566 rtx pat;
6567 operands[0] = gen_lowpart (SImode, operands[0]);
6568 operands[1] = gen_lowpart (Pmode, operands[1]);
6569 operands[3] = gen_lowpart (Pmode, operands[3]);
6570 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6571 operands[3]);
6572 if (Pmode != SImode)
6573 pat = gen_rtx_SUBREG (SImode, pat, 0);
6574 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6575 DONE;
6576 }
6577 [(set_attr "type" "lea")
6578 (set_attr "mode" "SI")])
6579
6580 (define_insn_and_split "*lea_general_2_zext"
6581 [(set (match_operand:DI 0 "register_operand" "=r")
6582 (zero_extend:DI
6583 (plus:SI (mult:SI
6584 (match_operand:SI 1 "index_register_operand" "l")
6585 (match_operand:SI 2 "const248_operand" "n"))
6586 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6587 "TARGET_64BIT"
6588 "#"
6589 "&& reload_completed"
6590 [(set (match_dup 0)
6591 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6592 (match_dup 2))
6593 (match_dup 3)) 0)))]
6594 {
6595 operands[1] = gen_lowpart (Pmode, operands[1]);
6596 operands[3] = gen_lowpart (Pmode, operands[3]);
6597 }
6598 [(set_attr "type" "lea")
6599 (set_attr "mode" "SI")])
6600
6601 (define_insn_and_split "*lea_general_3"
6602 [(set (match_operand 0 "register_operand" "=r")
6603 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6604 (match_operand 2 "const248_operand" "i"))
6605 (match_operand 3 "register_operand" "r"))
6606 (match_operand 4 "immediate_operand" "i")))]
6607 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6608 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6609 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6610 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6611 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6612 "#"
6613 "&& reload_completed"
6614 [(const_int 0)]
6615 {
6616 rtx pat;
6617 operands[0] = gen_lowpart (SImode, operands[0]);
6618 operands[1] = gen_lowpart (Pmode, operands[1]);
6619 operands[3] = gen_lowpart (Pmode, operands[3]);
6620 operands[4] = gen_lowpart (Pmode, operands[4]);
6621 pat = gen_rtx_PLUS (Pmode,
6622 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6623 operands[2]),
6624 operands[3]),
6625 operands[4]);
6626 if (Pmode != SImode)
6627 pat = gen_rtx_SUBREG (SImode, pat, 0);
6628 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6629 DONE;
6630 }
6631 [(set_attr "type" "lea")
6632 (set_attr "mode" "SI")])
6633
6634 (define_insn_and_split "*lea_general_3_zext"
6635 [(set (match_operand:DI 0 "register_operand" "=r")
6636 (zero_extend:DI
6637 (plus:SI (plus:SI
6638 (mult:SI
6639 (match_operand:SI 1 "index_register_operand" "l")
6640 (match_operand:SI 2 "const248_operand" "n"))
6641 (match_operand:SI 3 "register_operand" "r"))
6642 (match_operand:SI 4 "immediate_operand" "i"))))]
6643 "TARGET_64BIT"
6644 "#"
6645 "&& reload_completed"
6646 [(set (match_dup 0)
6647 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6648 (match_dup 2))
6649 (match_dup 3))
6650 (match_dup 4)) 0)))]
6651 {
6652 operands[1] = gen_lowpart (Pmode, operands[1]);
6653 operands[3] = gen_lowpart (Pmode, operands[3]);
6654 operands[4] = gen_lowpart (Pmode, operands[4]);
6655 }
6656 [(set_attr "type" "lea")
6657 (set_attr "mode" "SI")])
6658
6659 ;; Convert lea to the lea pattern to avoid flags dependency.
6660 (define_split
6661 [(set (match_operand:DI 0 "register_operand" "")
6662 (plus:DI (match_operand:DI 1 "register_operand" "")
6663 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "TARGET_64BIT && reload_completed
6666 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6667 [(set (match_dup 0)
6668 (plus:DI (match_dup 1)
6669 (match_dup 2)))]
6670 "")
6671
6672 ;; Convert lea to the lea pattern to avoid flags dependency.
6673 (define_split
6674 [(set (match_operand 0 "register_operand" "")
6675 (plus (match_operand 1 "register_operand" "")
6676 (match_operand 2 "nonmemory_operand" "")))
6677 (clobber (reg:CC FLAGS_REG))]
6678 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6679 [(const_int 0)]
6680 {
6681 rtx pat;
6682 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6683 may confuse gen_lowpart. */
6684 if (GET_MODE (operands[0]) != Pmode)
6685 {
6686 operands[1] = gen_lowpart (Pmode, operands[1]);
6687 operands[2] = gen_lowpart (Pmode, operands[2]);
6688 }
6689 operands[0] = gen_lowpart (SImode, operands[0]);
6690 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6691 if (Pmode != SImode)
6692 pat = gen_rtx_SUBREG (SImode, pat, 0);
6693 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6694 DONE;
6695 })
6696
6697 ;; Convert lea to the lea pattern to avoid flags dependency.
6698 (define_split
6699 [(set (match_operand:DI 0 "register_operand" "")
6700 (zero_extend:DI
6701 (plus:SI (match_operand:SI 1 "register_operand" "")
6702 (match_operand:SI 2 "nonmemory_operand" ""))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_64BIT && reload_completed
6705 && true_regnum (operands[0]) != true_regnum (operands[1])"
6706 [(set (match_dup 0)
6707 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6708 {
6709 operands[1] = gen_lowpart (Pmode, operands[1]);
6710 operands[2] = gen_lowpart (Pmode, operands[2]);
6711 })
6712 \f
6713 ;; Subtract instructions
6714
6715 (define_expand "sub<mode>3"
6716 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6717 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6718 (match_operand:SDWIM 2 "<general_operand>" "")))]
6719 ""
6720 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6721
6722 (define_insn_and_split "*sub<dwi>3_doubleword"
6723 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6724 (minus:<DWI>
6725 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6726 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6727 (clobber (reg:CC FLAGS_REG))]
6728 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6729 "#"
6730 "reload_completed"
6731 [(parallel [(set (reg:CC FLAGS_REG)
6732 (compare:CC (match_dup 1) (match_dup 2)))
6733 (set (match_dup 0)
6734 (minus:DWIH (match_dup 1) (match_dup 2)))])
6735 (parallel [(set (match_dup 3)
6736 (minus:DWIH
6737 (match_dup 4)
6738 (plus:DWIH
6739 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6740 (match_dup 5))))
6741 (clobber (reg:CC FLAGS_REG))])]
6742 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6743
6744 (define_insn "*sub<mode>_1"
6745 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6746 (minus:SWI
6747 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6748 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6749 (clobber (reg:CC FLAGS_REG))]
6750 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6751 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "<MODE>")])
6754
6755 (define_insn "*subsi_1_zext"
6756 [(set (match_operand:DI 0 "register_operand" "=r")
6757 (zero_extend:DI
6758 (minus:SI (match_operand:SI 1 "register_operand" "0")
6759 (match_operand:SI 2 "general_operand" "g"))))
6760 (clobber (reg:CC FLAGS_REG))]
6761 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762 "sub{l}\t{%2, %k0|%k0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "SI")])
6765
6766 (define_insn "*subqi_1_slp"
6767 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6768 (minus:QI (match_dup 0)
6769 (match_operand:QI 1 "general_operand" "qn,qm")))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6772 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6773 "sub{b}\t{%1, %0|%0, %1}"
6774 [(set_attr "type" "alu1")
6775 (set_attr "mode" "QI")])
6776
6777 (define_insn "*sub<mode>_2"
6778 [(set (reg FLAGS_REG)
6779 (compare
6780 (minus:SWI
6781 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6782 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6783 (const_int 0)))
6784 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6785 (minus:SWI (match_dup 1) (match_dup 2)))]
6786 "ix86_match_ccmode (insn, CCGOCmode)
6787 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6788 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6789 [(set_attr "type" "alu")
6790 (set_attr "mode" "<MODE>")])
6791
6792 (define_insn "*subsi_2_zext"
6793 [(set (reg FLAGS_REG)
6794 (compare
6795 (minus:SI (match_operand:SI 1 "register_operand" "0")
6796 (match_operand:SI 2 "general_operand" "g"))
6797 (const_int 0)))
6798 (set (match_operand:DI 0 "register_operand" "=r")
6799 (zero_extend:DI
6800 (minus:SI (match_dup 1)
6801 (match_dup 2))))]
6802 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6803 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6804 "sub{l}\t{%2, %k0|%k0, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "SI")])
6807
6808 (define_insn "*sub<mode>_3"
6809 [(set (reg FLAGS_REG)
6810 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6811 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6812 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6813 (minus:SWI (match_dup 1) (match_dup 2)))]
6814 "ix86_match_ccmode (insn, CCmode)
6815 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6816 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "<MODE>")])
6819
6820 (define_insn "*subsi_3_zext"
6821 [(set (reg FLAGS_REG)
6822 (compare (match_operand:SI 1 "register_operand" "0")
6823 (match_operand:SI 2 "general_operand" "g")))
6824 (set (match_operand:DI 0 "register_operand" "=r")
6825 (zero_extend:DI
6826 (minus:SI (match_dup 1)
6827 (match_dup 2))))]
6828 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6829 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6830 "sub{l}\t{%2, %1|%1, %2}"
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "SI")])
6833 \f
6834 ;; Add with carry and subtract with borrow
6835
6836 (define_expand "<plusminus_insn><mode>3_carry"
6837 [(parallel
6838 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6839 (plusminus:SWI
6840 (match_operand:SWI 1 "nonimmediate_operand" "")
6841 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6842 [(match_operand 3 "flags_reg_operand" "")
6843 (const_int 0)])
6844 (match_operand:SWI 2 "<general_operand>" ""))))
6845 (clobber (reg:CC FLAGS_REG))])]
6846 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6847 "")
6848
6849 (define_insn "*<plusminus_insn><mode>3_carry"
6850 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6851 (plusminus:SWI
6852 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6853 (plus:SWI
6854 (match_operator 3 "ix86_carry_flag_operator"
6855 [(reg FLAGS_REG) (const_int 0)])
6856 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6857 (clobber (reg:CC FLAGS_REG))]
6858 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6859 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "alu")
6861 (set_attr "use_carry" "1")
6862 (set_attr "pent_pair" "pu")
6863 (set_attr "mode" "<MODE>")])
6864
6865 (define_insn "*addsi3_carry_zext"
6866 [(set (match_operand:DI 0 "register_operand" "=r")
6867 (zero_extend:DI
6868 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6869 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6870 [(reg FLAGS_REG) (const_int 0)])
6871 (match_operand:SI 2 "general_operand" "g")))))
6872 (clobber (reg:CC FLAGS_REG))]
6873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6874 "adc{l}\t{%2, %k0|%k0, %2}"
6875 [(set_attr "type" "alu")
6876 (set_attr "use_carry" "1")
6877 (set_attr "pent_pair" "pu")
6878 (set_attr "mode" "SI")])
6879
6880 (define_insn "*subsi3_carry_zext"
6881 [(set (match_operand:DI 0 "register_operand" "=r")
6882 (zero_extend:DI
6883 (minus:SI (match_operand:SI 1 "register_operand" "0")
6884 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6885 [(reg FLAGS_REG) (const_int 0)])
6886 (match_operand:SI 2 "general_operand" "g")))))
6887 (clobber (reg:CC FLAGS_REG))]
6888 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6889 "sbb{l}\t{%2, %k0|%k0, %2}"
6890 [(set_attr "type" "alu")
6891 (set_attr "pent_pair" "pu")
6892 (set_attr "mode" "SI")])
6893 \f
6894 ;; Overflow setting add and subtract instructions
6895
6896 (define_insn "*add<mode>3_cconly_overflow"
6897 [(set (reg:CCC FLAGS_REG)
6898 (compare:CCC
6899 (plus:SWI
6900 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6901 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6902 (match_dup 1)))
6903 (clobber (match_scratch:SWI 0 "=<r>"))]
6904 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6905 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6906 [(set_attr "type" "alu")
6907 (set_attr "mode" "<MODE>")])
6908
6909 (define_insn "*sub<mode>3_cconly_overflow"
6910 [(set (reg:CCC FLAGS_REG)
6911 (compare:CCC
6912 (minus:SWI
6913 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6914 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6915 (match_dup 0)))]
6916 ""
6917 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6918 [(set_attr "type" "icmp")
6919 (set_attr "mode" "<MODE>")])
6920
6921 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6922 [(set (reg:CCC FLAGS_REG)
6923 (compare:CCC
6924 (plusminus:SWI
6925 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6926 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6927 (match_dup 1)))
6928 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6929 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6930 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6931 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6932 [(set_attr "type" "alu")
6933 (set_attr "mode" "<MODE>")])
6934
6935 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6936 [(set (reg:CCC FLAGS_REG)
6937 (compare:CCC
6938 (plusminus:SI
6939 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6940 (match_operand:SI 2 "general_operand" "g"))
6941 (match_dup 1)))
6942 (set (match_operand:DI 0 "register_operand" "=r")
6943 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6944 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6945 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6946 [(set_attr "type" "alu")
6947 (set_attr "mode" "SI")])
6948
6949 ;; The patterns that match these are at the end of this file.
6950
6951 (define_expand "<plusminus_insn>xf3"
6952 [(set (match_operand:XF 0 "register_operand" "")
6953 (plusminus:XF
6954 (match_operand:XF 1 "register_operand" "")
6955 (match_operand:XF 2 "register_operand" "")))]
6956 "TARGET_80387"
6957 "")
6958
6959 (define_expand "<plusminus_insn><mode>3"
6960 [(set (match_operand:MODEF 0 "register_operand" "")
6961 (plusminus:MODEF
6962 (match_operand:MODEF 1 "register_operand" "")
6963 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6964 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6965 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6966 "")
6967 \f
6968 ;; Multiply instructions
6969
6970 (define_expand "mul<mode>3"
6971 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6972 (mult:SWIM248
6973 (match_operand:SWIM248 1 "register_operand" "")
6974 (match_operand:SWIM248 2 "<general_operand>" "")))
6975 (clobber (reg:CC FLAGS_REG))])]
6976 ""
6977 "")
6978
6979 (define_expand "mulqi3"
6980 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6981 (mult:QI
6982 (match_operand:QI 1 "register_operand" "")
6983 (match_operand:QI 2 "nonimmediate_operand" "")))
6984 (clobber (reg:CC FLAGS_REG))])]
6985 "TARGET_QIMODE_MATH"
6986 "")
6987
6988 ;; On AMDFAM10
6989 ;; IMUL reg32/64, reg32/64, imm8 Direct
6990 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6991 ;; IMUL reg32/64, reg32/64, imm32 Direct
6992 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6993 ;; IMUL reg32/64, reg32/64 Direct
6994 ;; IMUL reg32/64, mem32/64 Direct
6995
6996 (define_insn "*mul<mode>3_1"
6997 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6998 (mult:SWI48
6999 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7000 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7001 (clobber (reg:CC FLAGS_REG))]
7002 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7003 "@
7004 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7005 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7006 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7007 [(set_attr "type" "imul")
7008 (set_attr "prefix_0f" "0,0,1")
7009 (set (attr "athlon_decode")
7010 (cond [(eq_attr "cpu" "athlon")
7011 (const_string "vector")
7012 (eq_attr "alternative" "1")
7013 (const_string "vector")
7014 (and (eq_attr "alternative" "2")
7015 (match_operand 1 "memory_operand" ""))
7016 (const_string "vector")]
7017 (const_string "direct")))
7018 (set (attr "amdfam10_decode")
7019 (cond [(and (eq_attr "alternative" "0,1")
7020 (match_operand 1 "memory_operand" ""))
7021 (const_string "vector")]
7022 (const_string "direct")))
7023 (set_attr "mode" "<MODE>")])
7024
7025 (define_insn "*mulsi3_1_zext"
7026 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7027 (zero_extend:DI
7028 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7029 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7030 (clobber (reg:CC FLAGS_REG))]
7031 "TARGET_64BIT
7032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7033 "@
7034 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7035 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7036 imul{l}\t{%2, %k0|%k0, %2}"
7037 [(set_attr "type" "imul")
7038 (set_attr "prefix_0f" "0,0,1")
7039 (set (attr "athlon_decode")
7040 (cond [(eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (eq_attr "alternative" "1")
7043 (const_string "vector")
7044 (and (eq_attr "alternative" "2")
7045 (match_operand 1 "memory_operand" ""))
7046 (const_string "vector")]
7047 (const_string "direct")))
7048 (set (attr "amdfam10_decode")
7049 (cond [(and (eq_attr "alternative" "0,1")
7050 (match_operand 1 "memory_operand" ""))
7051 (const_string "vector")]
7052 (const_string "direct")))
7053 (set_attr "mode" "SI")])
7054
7055 ;; On AMDFAM10
7056 ;; IMUL reg16, reg16, imm8 VectorPath
7057 ;; IMUL reg16, mem16, imm8 VectorPath
7058 ;; IMUL reg16, reg16, imm16 VectorPath
7059 ;; IMUL reg16, mem16, imm16 VectorPath
7060 ;; IMUL reg16, reg16 Direct
7061 ;; IMUL reg16, mem16 Direct
7062
7063 (define_insn "*mulhi3_1"
7064 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7065 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7066 (match_operand:HI 2 "general_operand" "K,n,mr")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "TARGET_HIMODE_MATH
7069 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7070 "@
7071 imul{w}\t{%2, %1, %0|%0, %1, %2}
7072 imul{w}\t{%2, %1, %0|%0, %1, %2}
7073 imul{w}\t{%2, %0|%0, %2}"
7074 [(set_attr "type" "imul")
7075 (set_attr "prefix_0f" "0,0,1")
7076 (set (attr "athlon_decode")
7077 (cond [(eq_attr "cpu" "athlon")
7078 (const_string "vector")
7079 (eq_attr "alternative" "1,2")
7080 (const_string "vector")]
7081 (const_string "direct")))
7082 (set (attr "amdfam10_decode")
7083 (cond [(eq_attr "alternative" "0,1")
7084 (const_string "vector")]
7085 (const_string "direct")))
7086 (set_attr "mode" "HI")])
7087
7088 ;;On AMDFAM10
7089 ;; MUL reg8 Direct
7090 ;; MUL mem8 Direct
7091
7092 (define_insn "*mulqi3_1"
7093 [(set (match_operand:QI 0 "register_operand" "=a")
7094 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7095 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7096 (clobber (reg:CC FLAGS_REG))]
7097 "TARGET_QIMODE_MATH
7098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7099 "mul{b}\t%2"
7100 [(set_attr "type" "imul")
7101 (set_attr "length_immediate" "0")
7102 (set (attr "athlon_decode")
7103 (if_then_else (eq_attr "cpu" "athlon")
7104 (const_string "vector")
7105 (const_string "direct")))
7106 (set_attr "amdfam10_decode" "direct")
7107 (set_attr "mode" "QI")])
7108
7109 (define_expand "<u>mul<mode><dwi>3"
7110 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7111 (mult:<DWI>
7112 (any_extend:<DWI>
7113 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7114 (any_extend:<DWI>
7115 (match_operand:DWIH 2 "register_operand" ""))))
7116 (clobber (reg:CC FLAGS_REG))])]
7117 ""
7118 "")
7119
7120 (define_expand "<u>mulqihi3"
7121 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7122 (mult:HI
7123 (any_extend:HI
7124 (match_operand:QI 1 "nonimmediate_operand" ""))
7125 (any_extend:HI
7126 (match_operand:QI 2 "register_operand" ""))))
7127 (clobber (reg:CC FLAGS_REG))])]
7128 "TARGET_QIMODE_MATH"
7129 "")
7130
7131 (define_insn "*<u>mul<mode><dwi>3_1"
7132 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7133 (mult:<DWI>
7134 (any_extend:<DWI>
7135 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7136 (any_extend:<DWI>
7137 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7138 (clobber (reg:CC FLAGS_REG))]
7139 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7140 "<sgnprefix>mul{<imodesuffix>}\t%2"
7141 [(set_attr "type" "imul")
7142 (set_attr "length_immediate" "0")
7143 (set (attr "athlon_decode")
7144 (if_then_else (eq_attr "cpu" "athlon")
7145 (const_string "vector")
7146 (const_string "double")))
7147 (set_attr "amdfam10_decode" "double")
7148 (set_attr "mode" "<MODE>")])
7149
7150 (define_insn "*<u>mulqihi3_1"
7151 [(set (match_operand:HI 0 "register_operand" "=a")
7152 (mult:HI
7153 (any_extend:HI
7154 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7155 (any_extend:HI
7156 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7157 (clobber (reg:CC FLAGS_REG))]
7158 "TARGET_QIMODE_MATH
7159 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7160 "<sgnprefix>mul{b}\t%2"
7161 [(set_attr "type" "imul")
7162 (set_attr "length_immediate" "0")
7163 (set (attr "athlon_decode")
7164 (if_then_else (eq_attr "cpu" "athlon")
7165 (const_string "vector")
7166 (const_string "direct")))
7167 (set_attr "amdfam10_decode" "direct")
7168 (set_attr "mode" "QI")])
7169
7170 (define_expand "<s>mul<mode>3_highpart"
7171 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7172 (truncate:SWI48
7173 (lshiftrt:<DWI>
7174 (mult:<DWI>
7175 (any_extend:<DWI>
7176 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7177 (any_extend:<DWI>
7178 (match_operand:SWI48 2 "register_operand" "")))
7179 (match_dup 4))))
7180 (clobber (match_scratch:SWI48 3 ""))
7181 (clobber (reg:CC FLAGS_REG))])]
7182 ""
7183 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7184
7185 (define_insn "*<s>muldi3_highpart_1"
7186 [(set (match_operand:DI 0 "register_operand" "=d")
7187 (truncate:DI
7188 (lshiftrt:TI
7189 (mult:TI
7190 (any_extend:TI
7191 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7192 (any_extend:TI
7193 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7194 (const_int 64))))
7195 (clobber (match_scratch:DI 3 "=1"))
7196 (clobber (reg:CC FLAGS_REG))]
7197 "TARGET_64BIT
7198 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7199 "<sgnprefix>mul{q}\t%2"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "amdfam10_decode" "double")
7207 (set_attr "mode" "DI")])
7208
7209 (define_insn "*<s>mulsi3_highpart_1"
7210 [(set (match_operand:SI 0 "register_operand" "=d")
7211 (truncate:SI
7212 (lshiftrt:DI
7213 (mult:DI
7214 (any_extend:DI
7215 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7216 (any_extend:DI
7217 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7218 (const_int 32))))
7219 (clobber (match_scratch:SI 3 "=1"))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7222 "<sgnprefix>mul{l}\t%2"
7223 [(set_attr "type" "imul")
7224 (set_attr "length_immediate" "0")
7225 (set (attr "athlon_decode")
7226 (if_then_else (eq_attr "cpu" "athlon")
7227 (const_string "vector")
7228 (const_string "double")))
7229 (set_attr "amdfam10_decode" "double")
7230 (set_attr "mode" "SI")])
7231
7232 (define_insn "*<s>mulsi3_highpart_zext"
7233 [(set (match_operand:DI 0 "register_operand" "=d")
7234 (zero_extend:DI (truncate:SI
7235 (lshiftrt:DI
7236 (mult:DI (any_extend:DI
7237 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7238 (any_extend:DI
7239 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7240 (const_int 32)))))
7241 (clobber (match_scratch:SI 3 "=1"))
7242 (clobber (reg:CC FLAGS_REG))]
7243 "TARGET_64BIT
7244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245 "<sgnprefix>mul{l}\t%2"
7246 [(set_attr "type" "imul")
7247 (set_attr "length_immediate" "0")
7248 (set (attr "athlon_decode")
7249 (if_then_else (eq_attr "cpu" "athlon")
7250 (const_string "vector")
7251 (const_string "double")))
7252 (set_attr "amdfam10_decode" "double")
7253 (set_attr "mode" "SI")])
7254
7255 ;; The patterns that match these are at the end of this file.
7256
7257 (define_expand "mulxf3"
7258 [(set (match_operand:XF 0 "register_operand" "")
7259 (mult:XF (match_operand:XF 1 "register_operand" "")
7260 (match_operand:XF 2 "register_operand" "")))]
7261 "TARGET_80387"
7262 "")
7263
7264 (define_expand "mul<mode>3"
7265 [(set (match_operand:MODEF 0 "register_operand" "")
7266 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7267 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7268 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7269 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7270 "")
7271 \f
7272 ;; Divide instructions
7273
7274 ;; The patterns that match these are at the end of this file.
7275
7276 (define_expand "divxf3"
7277 [(set (match_operand:XF 0 "register_operand" "")
7278 (div:XF (match_operand:XF 1 "register_operand" "")
7279 (match_operand:XF 2 "register_operand" "")))]
7280 "TARGET_80387"
7281 "")
7282
7283 (define_expand "divdf3"
7284 [(set (match_operand:DF 0 "register_operand" "")
7285 (div:DF (match_operand:DF 1 "register_operand" "")
7286 (match_operand:DF 2 "nonimmediate_operand" "")))]
7287 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7288 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7289 "")
7290
7291 (define_expand "divsf3"
7292 [(set (match_operand:SF 0 "register_operand" "")
7293 (div:SF (match_operand:SF 1 "register_operand" "")
7294 (match_operand:SF 2 "nonimmediate_operand" "")))]
7295 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7296 || TARGET_SSE_MATH"
7297 {
7298 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7299 && flag_finite_math_only && !flag_trapping_math
7300 && flag_unsafe_math_optimizations)
7301 {
7302 ix86_emit_swdivsf (operands[0], operands[1],
7303 operands[2], SFmode);
7304 DONE;
7305 }
7306 })
7307 \f
7308 ;; Divmod instructions.
7309
7310 (define_expand "<u>divmodqi4"
7311 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7312 (any_div:QI
7313 (match_operand:QI 1 "register_operand" "")
7314 (match_operand:QI 2 "nonimmediate_operand" "")))
7315 (set (match_operand:QI 3 "register_operand" "")
7316 (mod:QI (match_dup 1) (match_dup 2)))
7317 (clobber (reg:CC FLAGS_REG))])]
7318 "TARGET_QIMODE_MATH"
7319 {
7320 rtx div, mod, insn;
7321 rtx tmp0, tmp1;
7322
7323 tmp0 = gen_reg_rtx (HImode);
7324 tmp1 = gen_reg_rtx (HImode);
7325
7326 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7327 in AX. */
7328 if (<extract_code> == SIGN_EXTRACT)
7329 {
7330 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7331 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7332
7333 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7334 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7335
7336 tmp1 = gen_rtx_<extract_code> (QImode, tmp0,
7337 GEN_INT (8), GEN_INT (8));
7338 }
7339 else
7340 {
7341 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7342 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7343
7344 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7345 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7346
7347 tmp1 = gen_rtx_<extract_code> (SImode, tmp0,
7348 GEN_INT (8), GEN_INT (8));
7349 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7350 }
7351
7352 /* Extract remainder from AH. */
7353 insn = emit_move_insn (operands[3], tmp1);
7354 set_unique_reg_note (insn, REG_EQUAL, mod);
7355
7356 /* Extract quotient from AL. */
7357 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7358 set_unique_reg_note (insn, REG_EQUAL, div);
7359
7360 DONE;
7361 })
7362
7363 ;; Divide AX by r/m8, with result stored in
7364 ;; AL <- Quotient
7365 ;; AH <- Remainder
7366 (define_insn "divmodhiqi3"
7367 [(set (match_operand:HI 0 "register_operand" "=a")
7368 (ior:HI
7369 (ashift:HI
7370 (zero_extend:HI
7371 (mod:QI (match_operand:HI 1 "register_operand" "0")
7372 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7373 (const_int 8))
7374 (zero_extend:HI (div:QI (match_dup 1) (match_dup 2)))))
7375 (clobber (reg:CC FLAGS_REG))]
7376 "TARGET_QIMODE_MATH"
7377 "idiv{b}\t%2"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "QI")])
7380
7381 (define_insn "udivmodhiqi3"
7382 [(set (match_operand:HI 0 "register_operand" "=a")
7383 (ior:HI
7384 (ashift:HI
7385 (zero_extend:HI
7386 (umod:QI (match_operand:HI 1 "register_operand" "0")
7387 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7388 (const_int 8))
7389 (zero_extend:HI (udiv:QI (match_dup 1) (match_dup 2)))))
7390 (clobber (reg:CC FLAGS_REG))]
7391 "TARGET_QIMODE_MATH"
7392 "div{b}\t%2"
7393 [(set_attr "type" "idiv")
7394 (set_attr "mode" "QI")])
7395
7396 (define_expand "divmod<mode>4"
7397 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7398 (div:SWIM248
7399 (match_operand:SWIM248 1 "register_operand" "")
7400 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7401 (set (match_operand:SWIM248 3 "register_operand" "")
7402 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7404 ""
7405 "")
7406
7407 (define_insn_and_split "*divmod<mode>4"
7408 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7409 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7410 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7411 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7412 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7413 (clobber (reg:CC FLAGS_REG))]
7414 ""
7415 "#"
7416 "reload_completed"
7417 [(parallel [(set (match_dup 1)
7418 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7419 (clobber (reg:CC FLAGS_REG))])
7420 (parallel [(set (match_dup 0)
7421 (div:SWIM248 (match_dup 2) (match_dup 3)))
7422 (set (match_dup 1)
7423 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7424 (use (match_dup 1))
7425 (clobber (reg:CC FLAGS_REG))])]
7426 {
7427 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7428
7429 if (<MODE>mode != HImode
7430 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7431 operands[4] = operands[2];
7432 else
7433 {
7434 /* Avoid use of cltd in favor of a mov+shift. */
7435 emit_move_insn (operands[1], operands[2]);
7436 operands[4] = operands[1];
7437 }
7438 }
7439 [(set_attr "type" "multi")
7440 (set_attr "mode" "<MODE>")])
7441
7442 (define_insn "*divmod<mode>4_noext"
7443 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7444 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7445 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7446 (set (match_operand:SWIM248 1 "register_operand" "=d")
7447 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7448 (use (match_operand:SWIM248 4 "register_operand" "1"))
7449 (clobber (reg:CC FLAGS_REG))]
7450 ""
7451 "idiv{<imodesuffix>}\t%3"
7452 [(set_attr "type" "idiv")
7453 (set_attr "mode" "<MODE>")])
7454
7455 (define_expand "udivmod<mode>4"
7456 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7457 (udiv:SWIM248
7458 (match_operand:SWIM248 1 "register_operand" "")
7459 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7460 (set (match_operand:SWIM248 3 "register_operand" "")
7461 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7462 (clobber (reg:CC FLAGS_REG))])]
7463 ""
7464 "")
7465
7466 (define_insn_and_split "*udivmod<mode>4"
7467 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7468 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7469 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7470 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7471 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7472 (clobber (reg:CC FLAGS_REG))]
7473 ""
7474 "#"
7475 "reload_completed"
7476 [(set (match_dup 1) (const_int 0))
7477 (parallel [(set (match_dup 0)
7478 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7479 (set (match_dup 1)
7480 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7481 (use (match_dup 1))
7482 (clobber (reg:CC FLAGS_REG))])]
7483 ""
7484 [(set_attr "type" "multi")
7485 (set_attr "mode" "<MODE>")])
7486
7487 (define_insn "*udivmod<mode>4_noext"
7488 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7489 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7490 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7491 (set (match_operand:SWIM248 1 "register_operand" "=d")
7492 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7493 (use (match_operand:SWIM248 4 "register_operand" "1"))
7494 (clobber (reg:CC FLAGS_REG))]
7495 ""
7496 "div{<imodesuffix>}\t%3"
7497 [(set_attr "type" "idiv")
7498 (set_attr "mode" "<MODE>")])
7499
7500 ;; We cannot use div/idiv for double division, because it causes
7501 ;; "division by zero" on the overflow and that's not what we expect
7502 ;; from truncate. Because true (non truncating) double division is
7503 ;; never generated, we can't create this insn anyway.
7504 ;
7505 ;(define_insn ""
7506 ; [(set (match_operand:SI 0 "register_operand" "=a")
7507 ; (truncate:SI
7508 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7509 ; (zero_extend:DI
7510 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7511 ; (set (match_operand:SI 3 "register_operand" "=d")
7512 ; (truncate:SI
7513 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7514 ; (clobber (reg:CC FLAGS_REG))]
7515 ; ""
7516 ; "div{l}\t{%2, %0|%0, %2}"
7517 ; [(set_attr "type" "idiv")])
7518 \f
7519 ;;- Logical AND instructions
7520
7521 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7522 ;; Note that this excludes ah.
7523
7524 (define_expand "testsi_ccno_1"
7525 [(set (reg:CCNO FLAGS_REG)
7526 (compare:CCNO
7527 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7528 (match_operand:SI 1 "nonmemory_operand" ""))
7529 (const_int 0)))]
7530 ""
7531 "")
7532
7533 (define_expand "testqi_ccz_1"
7534 [(set (reg:CCZ FLAGS_REG)
7535 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7536 (match_operand:QI 1 "nonmemory_operand" ""))
7537 (const_int 0)))]
7538 ""
7539 "")
7540
7541 (define_insn "*testdi_1"
7542 [(set (reg FLAGS_REG)
7543 (compare
7544 (and:DI
7545 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7546 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7547 (const_int 0)))]
7548 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7550 "@
7551 test{l}\t{%k1, %k0|%k0, %k1}
7552 test{l}\t{%k1, %k0|%k0, %k1}
7553 test{q}\t{%1, %0|%0, %1}
7554 test{q}\t{%1, %0|%0, %1}
7555 test{q}\t{%1, %0|%0, %1}"
7556 [(set_attr "type" "test")
7557 (set_attr "modrm" "0,1,0,1,1")
7558 (set_attr "mode" "SI,SI,DI,DI,DI")])
7559
7560 (define_insn "*testqi_1_maybe_si"
7561 [(set (reg FLAGS_REG)
7562 (compare
7563 (and:QI
7564 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7565 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7566 (const_int 0)))]
7567 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7568 && ix86_match_ccmode (insn,
7569 CONST_INT_P (operands[1])
7570 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7571 {
7572 if (which_alternative == 3)
7573 {
7574 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7575 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7576 return "test{l}\t{%1, %k0|%k0, %1}";
7577 }
7578 return "test{b}\t{%1, %0|%0, %1}";
7579 }
7580 [(set_attr "type" "test")
7581 (set_attr "modrm" "0,1,1,1")
7582 (set_attr "mode" "QI,QI,QI,SI")
7583 (set_attr "pent_pair" "uv,np,uv,np")])
7584
7585 (define_insn "*test<mode>_1"
7586 [(set (reg FLAGS_REG)
7587 (compare
7588 (and:SWI124
7589 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7590 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7591 (const_int 0)))]
7592 "ix86_match_ccmode (insn, CCNOmode)
7593 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7594 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7595 [(set_attr "type" "test")
7596 (set_attr "modrm" "0,1,1")
7597 (set_attr "mode" "<MODE>")
7598 (set_attr "pent_pair" "uv,np,uv")])
7599
7600 (define_expand "testqi_ext_ccno_0"
7601 [(set (reg:CCNO FLAGS_REG)
7602 (compare:CCNO
7603 (and:SI
7604 (zero_extract:SI
7605 (match_operand 0 "ext_register_operand" "")
7606 (const_int 8)
7607 (const_int 8))
7608 (match_operand 1 "const_int_operand" ""))
7609 (const_int 0)))]
7610 ""
7611 "")
7612
7613 (define_insn "*testqi_ext_0"
7614 [(set (reg FLAGS_REG)
7615 (compare
7616 (and:SI
7617 (zero_extract:SI
7618 (match_operand 0 "ext_register_operand" "Q")
7619 (const_int 8)
7620 (const_int 8))
7621 (match_operand 1 "const_int_operand" "n"))
7622 (const_int 0)))]
7623 "ix86_match_ccmode (insn, CCNOmode)"
7624 "test{b}\t{%1, %h0|%h0, %1}"
7625 [(set_attr "type" "test")
7626 (set_attr "mode" "QI")
7627 (set_attr "length_immediate" "1")
7628 (set_attr "modrm" "1")
7629 (set_attr "pent_pair" "np")])
7630
7631 (define_insn "*testqi_ext_1_rex64"
7632 [(set (reg FLAGS_REG)
7633 (compare
7634 (and:SI
7635 (zero_extract:SI
7636 (match_operand 0 "ext_register_operand" "Q")
7637 (const_int 8)
7638 (const_int 8))
7639 (zero_extend:SI
7640 (match_operand:QI 1 "register_operand" "Q")))
7641 (const_int 0)))]
7642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7643 "test{b}\t{%1, %h0|%h0, %1}"
7644 [(set_attr "type" "test")
7645 (set_attr "mode" "QI")])
7646
7647 (define_insn "*testqi_ext_1"
7648 [(set (reg FLAGS_REG)
7649 (compare
7650 (and:SI
7651 (zero_extract:SI
7652 (match_operand 0 "ext_register_operand" "Q")
7653 (const_int 8)
7654 (const_int 8))
7655 (zero_extend:SI
7656 (match_operand:QI 1 "general_operand" "Qm")))
7657 (const_int 0)))]
7658 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7659 "test{b}\t{%1, %h0|%h0, %1}"
7660 [(set_attr "type" "test")
7661 (set_attr "mode" "QI")])
7662
7663 (define_insn "*testqi_ext_2"
7664 [(set (reg FLAGS_REG)
7665 (compare
7666 (and:SI
7667 (zero_extract:SI
7668 (match_operand 0 "ext_register_operand" "Q")
7669 (const_int 8)
7670 (const_int 8))
7671 (zero_extract:SI
7672 (match_operand 1 "ext_register_operand" "Q")
7673 (const_int 8)
7674 (const_int 8)))
7675 (const_int 0)))]
7676 "ix86_match_ccmode (insn, CCNOmode)"
7677 "test{b}\t{%h1, %h0|%h0, %h1}"
7678 [(set_attr "type" "test")
7679 (set_attr "mode" "QI")])
7680
7681 (define_insn "*testqi_ext_3_rex64"
7682 [(set (reg FLAGS_REG)
7683 (compare (zero_extract:DI
7684 (match_operand 0 "nonimmediate_operand" "rm")
7685 (match_operand:DI 1 "const_int_operand" "")
7686 (match_operand:DI 2 "const_int_operand" ""))
7687 (const_int 0)))]
7688 "TARGET_64BIT
7689 && ix86_match_ccmode (insn, CCNOmode)
7690 && INTVAL (operands[1]) > 0
7691 && INTVAL (operands[2]) >= 0
7692 /* Ensure that resulting mask is zero or sign extended operand. */
7693 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7694 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7695 && INTVAL (operands[1]) > 32))
7696 && (GET_MODE (operands[0]) == SImode
7697 || GET_MODE (operands[0]) == DImode
7698 || GET_MODE (operands[0]) == HImode
7699 || GET_MODE (operands[0]) == QImode)"
7700 "#")
7701
7702 ;; Combine likes to form bit extractions for some tests. Humor it.
7703 (define_insn "*testqi_ext_3"
7704 [(set (reg FLAGS_REG)
7705 (compare (zero_extract:SI
7706 (match_operand 0 "nonimmediate_operand" "rm")
7707 (match_operand:SI 1 "const_int_operand" "")
7708 (match_operand:SI 2 "const_int_operand" ""))
7709 (const_int 0)))]
7710 "ix86_match_ccmode (insn, CCNOmode)
7711 && INTVAL (operands[1]) > 0
7712 && INTVAL (operands[2]) >= 0
7713 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7714 && (GET_MODE (operands[0]) == SImode
7715 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7716 || GET_MODE (operands[0]) == HImode
7717 || GET_MODE (operands[0]) == QImode)"
7718 "#")
7719
7720 (define_split
7721 [(set (match_operand 0 "flags_reg_operand" "")
7722 (match_operator 1 "compare_operator"
7723 [(zero_extract
7724 (match_operand 2 "nonimmediate_operand" "")
7725 (match_operand 3 "const_int_operand" "")
7726 (match_operand 4 "const_int_operand" ""))
7727 (const_int 0)]))]
7728 "ix86_match_ccmode (insn, CCNOmode)"
7729 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7730 {
7731 rtx val = operands[2];
7732 HOST_WIDE_INT len = INTVAL (operands[3]);
7733 HOST_WIDE_INT pos = INTVAL (operands[4]);
7734 HOST_WIDE_INT mask;
7735 enum machine_mode mode, submode;
7736
7737 mode = GET_MODE (val);
7738 if (MEM_P (val))
7739 {
7740 /* ??? Combine likes to put non-volatile mem extractions in QImode
7741 no matter the size of the test. So find a mode that works. */
7742 if (! MEM_VOLATILE_P (val))
7743 {
7744 mode = smallest_mode_for_size (pos + len, MODE_INT);
7745 val = adjust_address (val, mode, 0);
7746 }
7747 }
7748 else if (GET_CODE (val) == SUBREG
7749 && (submode = GET_MODE (SUBREG_REG (val)),
7750 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7751 && pos + len <= GET_MODE_BITSIZE (submode)
7752 && GET_MODE_CLASS (submode) == MODE_INT)
7753 {
7754 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7755 mode = submode;
7756 val = SUBREG_REG (val);
7757 }
7758 else if (mode == HImode && pos + len <= 8)
7759 {
7760 /* Small HImode tests can be converted to QImode. */
7761 mode = QImode;
7762 val = gen_lowpart (QImode, val);
7763 }
7764
7765 if (len == HOST_BITS_PER_WIDE_INT)
7766 mask = -1;
7767 else
7768 mask = ((HOST_WIDE_INT)1 << len) - 1;
7769 mask <<= pos;
7770
7771 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7772 })
7773
7774 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7775 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7776 ;; this is relatively important trick.
7777 ;; Do the conversion only post-reload to avoid limiting of the register class
7778 ;; to QI regs.
7779 (define_split
7780 [(set (match_operand 0 "flags_reg_operand" "")
7781 (match_operator 1 "compare_operator"
7782 [(and (match_operand 2 "register_operand" "")
7783 (match_operand 3 "const_int_operand" ""))
7784 (const_int 0)]))]
7785 "reload_completed
7786 && QI_REG_P (operands[2])
7787 && GET_MODE (operands[2]) != QImode
7788 && ((ix86_match_ccmode (insn, CCZmode)
7789 && !(INTVAL (operands[3]) & ~(255 << 8)))
7790 || (ix86_match_ccmode (insn, CCNOmode)
7791 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7792 [(set (match_dup 0)
7793 (match_op_dup 1
7794 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7795 (match_dup 3))
7796 (const_int 0)]))]
7797 "operands[2] = gen_lowpart (SImode, operands[2]);
7798 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7799
7800 (define_split
7801 [(set (match_operand 0 "flags_reg_operand" "")
7802 (match_operator 1 "compare_operator"
7803 [(and (match_operand 2 "nonimmediate_operand" "")
7804 (match_operand 3 "const_int_operand" ""))
7805 (const_int 0)]))]
7806 "reload_completed
7807 && GET_MODE (operands[2]) != QImode
7808 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7809 && ((ix86_match_ccmode (insn, CCZmode)
7810 && !(INTVAL (operands[3]) & ~255))
7811 || (ix86_match_ccmode (insn, CCNOmode)
7812 && !(INTVAL (operands[3]) & ~127)))"
7813 [(set (match_dup 0)
7814 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7815 (const_int 0)]))]
7816 "operands[2] = gen_lowpart (QImode, operands[2]);
7817 operands[3] = gen_lowpart (QImode, operands[3]);")
7818
7819 ;; %%% This used to optimize known byte-wide and operations to memory,
7820 ;; and sometimes to QImode registers. If this is considered useful,
7821 ;; it should be done with splitters.
7822
7823 (define_expand "and<mode>3"
7824 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7825 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7826 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7827 ""
7828 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7829
7830 (define_insn "*anddi_1"
7831 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7832 (and:DI
7833 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7834 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7837 {
7838 switch (get_attr_type (insn))
7839 {
7840 case TYPE_IMOVX:
7841 {
7842 enum machine_mode mode;
7843
7844 gcc_assert (CONST_INT_P (operands[2]));
7845 if (INTVAL (operands[2]) == 0xff)
7846 mode = QImode;
7847 else
7848 {
7849 gcc_assert (INTVAL (operands[2]) == 0xffff);
7850 mode = HImode;
7851 }
7852
7853 operands[1] = gen_lowpart (mode, operands[1]);
7854 if (mode == QImode)
7855 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7856 else
7857 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7858 }
7859
7860 default:
7861 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7862 if (get_attr_mode (insn) == MODE_SI)
7863 return "and{l}\t{%k2, %k0|%k0, %k2}";
7864 else
7865 return "and{q}\t{%2, %0|%0, %2}";
7866 }
7867 }
7868 [(set_attr "type" "alu,alu,alu,imovx")
7869 (set_attr "length_immediate" "*,*,*,0")
7870 (set (attr "prefix_rex")
7871 (if_then_else
7872 (and (eq_attr "type" "imovx")
7873 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7874 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7875 (const_string "1")
7876 (const_string "*")))
7877 (set_attr "mode" "SI,DI,DI,SI")])
7878
7879 (define_insn "*andsi_1"
7880 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7881 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7882 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7883 (clobber (reg:CC FLAGS_REG))]
7884 "ix86_binary_operator_ok (AND, SImode, operands)"
7885 {
7886 switch (get_attr_type (insn))
7887 {
7888 case TYPE_IMOVX:
7889 {
7890 enum machine_mode mode;
7891
7892 gcc_assert (CONST_INT_P (operands[2]));
7893 if (INTVAL (operands[2]) == 0xff)
7894 mode = QImode;
7895 else
7896 {
7897 gcc_assert (INTVAL (operands[2]) == 0xffff);
7898 mode = HImode;
7899 }
7900
7901 operands[1] = gen_lowpart (mode, operands[1]);
7902 if (mode == QImode)
7903 return "movz{bl|x}\t{%1, %0|%0, %1}";
7904 else
7905 return "movz{wl|x}\t{%1, %0|%0, %1}";
7906 }
7907
7908 default:
7909 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7910 return "and{l}\t{%2, %0|%0, %2}";
7911 }
7912 }
7913 [(set_attr "type" "alu,alu,imovx")
7914 (set (attr "prefix_rex")
7915 (if_then_else
7916 (and (eq_attr "type" "imovx")
7917 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7918 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7919 (const_string "1")
7920 (const_string "*")))
7921 (set_attr "length_immediate" "*,*,0")
7922 (set_attr "mode" "SI")])
7923
7924 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7925 (define_insn "*andsi_1_zext"
7926 [(set (match_operand:DI 0 "register_operand" "=r")
7927 (zero_extend:DI
7928 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7929 (match_operand:SI 2 "general_operand" "g"))))
7930 (clobber (reg:CC FLAGS_REG))]
7931 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7932 "and{l}\t{%2, %k0|%k0, %2}"
7933 [(set_attr "type" "alu")
7934 (set_attr "mode" "SI")])
7935
7936 (define_insn "*andhi_1"
7937 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7938 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7939 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7940 (clobber (reg:CC FLAGS_REG))]
7941 "ix86_binary_operator_ok (AND, HImode, operands)"
7942 {
7943 switch (get_attr_type (insn))
7944 {
7945 case TYPE_IMOVX:
7946 gcc_assert (CONST_INT_P (operands[2]));
7947 gcc_assert (INTVAL (operands[2]) == 0xff);
7948 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7949
7950 default:
7951 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7952
7953 return "and{w}\t{%2, %0|%0, %2}";
7954 }
7955 }
7956 [(set_attr "type" "alu,alu,imovx")
7957 (set_attr "length_immediate" "*,*,0")
7958 (set (attr "prefix_rex")
7959 (if_then_else
7960 (and (eq_attr "type" "imovx")
7961 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7962 (const_string "1")
7963 (const_string "*")))
7964 (set_attr "mode" "HI,HI,SI")])
7965
7966 ;; %%% Potential partial reg stall on alternative 2. What to do?
7967 (define_insn "*andqi_1"
7968 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7969 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7970 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7971 (clobber (reg:CC FLAGS_REG))]
7972 "ix86_binary_operator_ok (AND, QImode, operands)"
7973 "@
7974 and{b}\t{%2, %0|%0, %2}
7975 and{b}\t{%2, %0|%0, %2}
7976 and{l}\t{%k2, %k0|%k0, %k2}"
7977 [(set_attr "type" "alu")
7978 (set_attr "mode" "QI,QI,SI")])
7979
7980 (define_insn "*andqi_1_slp"
7981 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7982 (and:QI (match_dup 0)
7983 (match_operand:QI 1 "general_operand" "qn,qmn")))
7984 (clobber (reg:CC FLAGS_REG))]
7985 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7986 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7987 "and{b}\t{%1, %0|%0, %1}"
7988 [(set_attr "type" "alu1")
7989 (set_attr "mode" "QI")])
7990
7991 (define_split
7992 [(set (match_operand 0 "register_operand" "")
7993 (and (match_dup 0)
7994 (const_int -65536)))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7997 || optimize_function_for_size_p (cfun)"
7998 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7999 "operands[1] = gen_lowpart (HImode, operands[0]);")
8000
8001 (define_split
8002 [(set (match_operand 0 "ext_register_operand" "")
8003 (and (match_dup 0)
8004 (const_int -256)))
8005 (clobber (reg:CC FLAGS_REG))]
8006 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && reload_completed"
8008 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8009 "operands[1] = gen_lowpart (QImode, operands[0]);")
8010
8011 (define_split
8012 [(set (match_operand 0 "ext_register_operand" "")
8013 (and (match_dup 0)
8014 (const_int -65281)))
8015 (clobber (reg:CC FLAGS_REG))]
8016 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8017 && reload_completed"
8018 [(parallel [(set (zero_extract:SI (match_dup 0)
8019 (const_int 8)
8020 (const_int 8))
8021 (xor:SI
8022 (zero_extract:SI (match_dup 0)
8023 (const_int 8)
8024 (const_int 8))
8025 (zero_extract:SI (match_dup 0)
8026 (const_int 8)
8027 (const_int 8))))
8028 (clobber (reg:CC FLAGS_REG))])]
8029 "operands[0] = gen_lowpart (SImode, operands[0]);")
8030
8031 (define_insn "*anddi_2"
8032 [(set (reg FLAGS_REG)
8033 (compare
8034 (and:DI
8035 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8036 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8037 (const_int 0)))
8038 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8039 (and:DI (match_dup 1) (match_dup 2)))]
8040 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8041 && ix86_binary_operator_ok (AND, DImode, operands)"
8042 "@
8043 and{l}\t{%k2, %k0|%k0, %k2}
8044 and{q}\t{%2, %0|%0, %2}
8045 and{q}\t{%2, %0|%0, %2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "mode" "SI,DI,DI")])
8048
8049 (define_insn "*andqi_2_maybe_si"
8050 [(set (reg FLAGS_REG)
8051 (compare (and:QI
8052 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8054 (const_int 0)))
8055 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8056 (and:QI (match_dup 1) (match_dup 2)))]
8057 "ix86_binary_operator_ok (AND, QImode, operands)
8058 && ix86_match_ccmode (insn,
8059 CONST_INT_P (operands[2])
8060 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8061 {
8062 if (which_alternative == 2)
8063 {
8064 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8065 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8066 return "and{l}\t{%2, %k0|%k0, %2}";
8067 }
8068 return "and{b}\t{%2, %0|%0, %2}";
8069 }
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "QI,QI,SI")])
8072
8073 (define_insn "*and<mode>_2"
8074 [(set (reg FLAGS_REG)
8075 (compare (and:SWI124
8076 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8077 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8078 (const_int 0)))
8079 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8080 (and:SWI124 (match_dup 1) (match_dup 2)))]
8081 "ix86_match_ccmode (insn, CCNOmode)
8082 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8083 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "<MODE>")])
8086
8087 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8088 (define_insn "*andsi_2_zext"
8089 [(set (reg FLAGS_REG)
8090 (compare (and:SI
8091 (match_operand:SI 1 "nonimmediate_operand" "%0")
8092 (match_operand:SI 2 "general_operand" "g"))
8093 (const_int 0)))
8094 (set (match_operand:DI 0 "register_operand" "=r")
8095 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, SImode, operands)"
8098 "and{l}\t{%2, %k0|%k0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "mode" "SI")])
8101
8102 (define_insn "*andqi_2_slp"
8103 [(set (reg FLAGS_REG)
8104 (compare (and:QI
8105 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8106 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8107 (const_int 0)))
8108 (set (strict_low_part (match_dup 0))
8109 (and:QI (match_dup 0) (match_dup 1)))]
8110 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8111 && ix86_match_ccmode (insn, CCNOmode)
8112 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8113 "and{b}\t{%1, %0|%0, %1}"
8114 [(set_attr "type" "alu1")
8115 (set_attr "mode" "QI")])
8116
8117 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8118 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8119 ;; for a QImode operand, which of course failed.
8120 (define_insn "andqi_ext_0"
8121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8122 (const_int 8)
8123 (const_int 8))
8124 (and:SI
8125 (zero_extract:SI
8126 (match_operand 1 "ext_register_operand" "0")
8127 (const_int 8)
8128 (const_int 8))
8129 (match_operand 2 "const_int_operand" "n")))
8130 (clobber (reg:CC FLAGS_REG))]
8131 ""
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8137
8138 ;; Generated by peephole translating test to and. This shows up
8139 ;; often in fp comparisons.
8140 (define_insn "*andqi_ext_0_cc"
8141 [(set (reg FLAGS_REG)
8142 (compare
8143 (and:SI
8144 (zero_extract:SI
8145 (match_operand 1 "ext_register_operand" "0")
8146 (const_int 8)
8147 (const_int 8))
8148 (match_operand 2 "const_int_operand" "n"))
8149 (const_int 0)))
8150 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8151 (const_int 8)
8152 (const_int 8))
8153 (and:SI
8154 (zero_extract:SI
8155 (match_dup 1)
8156 (const_int 8)
8157 (const_int 8))
8158 (match_dup 2)))]
8159 "ix86_match_ccmode (insn, CCNOmode)"
8160 "and{b}\t{%2, %h0|%h0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "length_immediate" "1")
8163 (set_attr "modrm" "1")
8164 (set_attr "mode" "QI")])
8165
8166 (define_insn "*andqi_ext_1_rex64"
8167 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8168 (const_int 8)
8169 (const_int 8))
8170 (and:SI
8171 (zero_extract:SI
8172 (match_operand 1 "ext_register_operand" "0")
8173 (const_int 8)
8174 (const_int 8))
8175 (zero_extend:SI
8176 (match_operand 2 "ext_register_operand" "Q"))))
8177 (clobber (reg:CC FLAGS_REG))]
8178 "TARGET_64BIT"
8179 "and{b}\t{%2, %h0|%h0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8183
8184 (define_insn "*andqi_ext_1"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8186 (const_int 8)
8187 (const_int 8))
8188 (and:SI
8189 (zero_extract:SI
8190 (match_operand 1 "ext_register_operand" "0")
8191 (const_int 8)
8192 (const_int 8))
8193 (zero_extend:SI
8194 (match_operand:QI 2 "general_operand" "Qm"))))
8195 (clobber (reg:CC FLAGS_REG))]
8196 "!TARGET_64BIT"
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "0")
8200 (set_attr "mode" "QI")])
8201
8202 (define_insn "*andqi_ext_2"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204 (const_int 8)
8205 (const_int 8))
8206 (and:SI
8207 (zero_extract:SI
8208 (match_operand 1 "ext_register_operand" "%0")
8209 (const_int 8)
8210 (const_int 8))
8211 (zero_extract:SI
8212 (match_operand 2 "ext_register_operand" "Q")
8213 (const_int 8)
8214 (const_int 8))))
8215 (clobber (reg:CC FLAGS_REG))]
8216 ""
8217 "and{b}\t{%h2, %h0|%h0, %h2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8221
8222 ;; Convert wide AND instructions with immediate operand to shorter QImode
8223 ;; equivalents when possible.
8224 ;; Don't do the splitting with memory operands, since it introduces risk
8225 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8226 ;; for size, but that can (should?) be handled by generic code instead.
8227 (define_split
8228 [(set (match_operand 0 "register_operand" "")
8229 (and (match_operand 1 "register_operand" "")
8230 (match_operand 2 "const_int_operand" "")))
8231 (clobber (reg:CC FLAGS_REG))]
8232 "reload_completed
8233 && QI_REG_P (operands[0])
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(~INTVAL (operands[2]) & ~(255 << 8))
8236 && GET_MODE (operands[0]) != QImode"
8237 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8238 (and:SI (zero_extract:SI (match_dup 1)
8239 (const_int 8) (const_int 8))
8240 (match_dup 2)))
8241 (clobber (reg:CC FLAGS_REG))])]
8242 "operands[0] = gen_lowpart (SImode, operands[0]);
8243 operands[1] = gen_lowpart (SImode, operands[1]);
8244 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8245
8246 ;; Since AND can be encoded with sign extended immediate, this is only
8247 ;; profitable when 7th bit is not set.
8248 (define_split
8249 [(set (match_operand 0 "register_operand" "")
8250 (and (match_operand 1 "general_operand" "")
8251 (match_operand 2 "const_int_operand" "")))
8252 (clobber (reg:CC FLAGS_REG))]
8253 "reload_completed
8254 && ANY_QI_REG_P (operands[0])
8255 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8256 && !(~INTVAL (operands[2]) & ~255)
8257 && !(INTVAL (operands[2]) & 128)
8258 && GET_MODE (operands[0]) != QImode"
8259 [(parallel [(set (strict_low_part (match_dup 0))
8260 (and:QI (match_dup 1)
8261 (match_dup 2)))
8262 (clobber (reg:CC FLAGS_REG))])]
8263 "operands[0] = gen_lowpart (QImode, operands[0]);
8264 operands[1] = gen_lowpart (QImode, operands[1]);
8265 operands[2] = gen_lowpart (QImode, operands[2]);")
8266 \f
8267 ;; Logical inclusive and exclusive OR instructions
8268
8269 ;; %%% This used to optimize known byte-wide and operations to memory.
8270 ;; If this is considered useful, it should be done with splitters.
8271
8272 (define_expand "<code><mode>3"
8273 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8274 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8275 (match_operand:SWIM 2 "<general_operand>" "")))]
8276 ""
8277 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8278
8279 (define_insn "*<code><mode>_1"
8280 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8281 (any_or:SWI248
8282 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8283 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8286 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "<MODE>")])
8289
8290 ;; %%% Potential partial reg stall on alternative 2. What to do?
8291 (define_insn "*<code>qi_1"
8292 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8293 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8294 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8297 "@
8298 <logic>{b}\t{%2, %0|%0, %2}
8299 <logic>{b}\t{%2, %0|%0, %2}
8300 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "QI,QI,SI")])
8303
8304 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8305 (define_insn "*<code>si_1_zext"
8306 [(set (match_operand:DI 0 "register_operand" "=r")
8307 (zero_extend:DI
8308 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8309 (match_operand:SI 2 "general_operand" "g"))))
8310 (clobber (reg:CC FLAGS_REG))]
8311 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8312 "<logic>{l}\t{%2, %k0|%k0, %2}"
8313 [(set_attr "type" "alu")
8314 (set_attr "mode" "SI")])
8315
8316 (define_insn "*<code>si_1_zext_imm"
8317 [(set (match_operand:DI 0 "register_operand" "=r")
8318 (any_or:DI
8319 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8320 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8321 (clobber (reg:CC FLAGS_REG))]
8322 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8323 "<logic>{l}\t{%2, %k0|%k0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "SI")])
8326
8327 (define_insn "*<code>qi_1_slp"
8328 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8329 (any_or:QI (match_dup 0)
8330 (match_operand:QI 1 "general_operand" "qmn,qn")))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8333 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8334 "<logic>{b}\t{%1, %0|%0, %1}"
8335 [(set_attr "type" "alu1")
8336 (set_attr "mode" "QI")])
8337
8338 (define_insn "*<code><mode>_2"
8339 [(set (reg FLAGS_REG)
8340 (compare (any_or:SWI
8341 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8342 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8343 (const_int 0)))
8344 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8345 (any_or:SWI (match_dup 1) (match_dup 2)))]
8346 "ix86_match_ccmode (insn, CCNOmode)
8347 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8348 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "mode" "<MODE>")])
8351
8352 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8353 ;; ??? Special case for immediate operand is missing - it is tricky.
8354 (define_insn "*<code>si_2_zext"
8355 [(set (reg FLAGS_REG)
8356 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8357 (match_operand:SI 2 "general_operand" "g"))
8358 (const_int 0)))
8359 (set (match_operand:DI 0 "register_operand" "=r")
8360 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8361 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8363 "<logic>{l}\t{%2, %k0|%k0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "SI")])
8366
8367 (define_insn "*<code>si_2_zext_imm"
8368 [(set (reg FLAGS_REG)
8369 (compare (any_or:SI
8370 (match_operand:SI 1 "nonimmediate_operand" "%0")
8371 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8372 (const_int 0)))
8373 (set (match_operand:DI 0 "register_operand" "=r")
8374 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8375 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8376 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8377 "<logic>{l}\t{%2, %k0|%k0, %2}"
8378 [(set_attr "type" "alu")
8379 (set_attr "mode" "SI")])
8380
8381 (define_insn "*<code>qi_2_slp"
8382 [(set (reg FLAGS_REG)
8383 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8384 (match_operand:QI 1 "general_operand" "qmn,qn"))
8385 (const_int 0)))
8386 (set (strict_low_part (match_dup 0))
8387 (any_or:QI (match_dup 0) (match_dup 1)))]
8388 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8389 && ix86_match_ccmode (insn, CCNOmode)
8390 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8391 "<logic>{b}\t{%1, %0|%0, %1}"
8392 [(set_attr "type" "alu1")
8393 (set_attr "mode" "QI")])
8394
8395 (define_insn "*<code><mode>_3"
8396 [(set (reg FLAGS_REG)
8397 (compare (any_or:SWI
8398 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8399 (match_operand:SWI 2 "<general_operand>" "<g>"))
8400 (const_int 0)))
8401 (clobber (match_scratch:SWI 0 "=<r>"))]
8402 "ix86_match_ccmode (insn, CCNOmode)
8403 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8404 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8405 [(set_attr "type" "alu")
8406 (set_attr "mode" "<MODE>")])
8407
8408 (define_insn "*<code>qi_ext_0"
8409 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8410 (const_int 8)
8411 (const_int 8))
8412 (any_or:SI
8413 (zero_extract:SI
8414 (match_operand 1 "ext_register_operand" "0")
8415 (const_int 8)
8416 (const_int 8))
8417 (match_operand 2 "const_int_operand" "n")))
8418 (clobber (reg:CC FLAGS_REG))]
8419 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8420 "<logic>{b}\t{%2, %h0|%h0, %2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "length_immediate" "1")
8423 (set_attr "modrm" "1")
8424 (set_attr "mode" "QI")])
8425
8426 (define_insn "*<code>qi_ext_1_rex64"
8427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8428 (const_int 8)
8429 (const_int 8))
8430 (any_or:SI
8431 (zero_extract:SI
8432 (match_operand 1 "ext_register_operand" "0")
8433 (const_int 8)
8434 (const_int 8))
8435 (zero_extend:SI
8436 (match_operand 2 "ext_register_operand" "Q"))))
8437 (clobber (reg:CC FLAGS_REG))]
8438 "TARGET_64BIT
8439 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8440 "<logic>{b}\t{%2, %h0|%h0, %2}"
8441 [(set_attr "type" "alu")
8442 (set_attr "length_immediate" "0")
8443 (set_attr "mode" "QI")])
8444
8445 (define_insn "*<code>qi_ext_1"
8446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8447 (const_int 8)
8448 (const_int 8))
8449 (any_or:SI
8450 (zero_extract:SI
8451 (match_operand 1 "ext_register_operand" "0")
8452 (const_int 8)
8453 (const_int 8))
8454 (zero_extend:SI
8455 (match_operand:QI 2 "general_operand" "Qm"))))
8456 (clobber (reg:CC FLAGS_REG))]
8457 "!TARGET_64BIT
8458 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8459 "<logic>{b}\t{%2, %h0|%h0, %2}"
8460 [(set_attr "type" "alu")
8461 (set_attr "length_immediate" "0")
8462 (set_attr "mode" "QI")])
8463
8464 (define_insn "*<code>qi_ext_2"
8465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8466 (const_int 8)
8467 (const_int 8))
8468 (any_or:SI
8469 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8470 (const_int 8)
8471 (const_int 8))
8472 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8473 (const_int 8)
8474 (const_int 8))))
8475 (clobber (reg:CC FLAGS_REG))]
8476 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8477 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8478 [(set_attr "type" "alu")
8479 (set_attr "length_immediate" "0")
8480 (set_attr "mode" "QI")])
8481
8482 (define_split
8483 [(set (match_operand 0 "register_operand" "")
8484 (any_or (match_operand 1 "register_operand" "")
8485 (match_operand 2 "const_int_operand" "")))
8486 (clobber (reg:CC FLAGS_REG))]
8487 "reload_completed
8488 && QI_REG_P (operands[0])
8489 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8490 && !(INTVAL (operands[2]) & ~(255 << 8))
8491 && GET_MODE (operands[0]) != QImode"
8492 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8493 (any_or:SI (zero_extract:SI (match_dup 1)
8494 (const_int 8) (const_int 8))
8495 (match_dup 2)))
8496 (clobber (reg:CC FLAGS_REG))])]
8497 "operands[0] = gen_lowpart (SImode, operands[0]);
8498 operands[1] = gen_lowpart (SImode, operands[1]);
8499 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8500
8501 ;; Since OR can be encoded with sign extended immediate, this is only
8502 ;; profitable when 7th bit is set.
8503 (define_split
8504 [(set (match_operand 0 "register_operand" "")
8505 (any_or (match_operand 1 "general_operand" "")
8506 (match_operand 2 "const_int_operand" "")))
8507 (clobber (reg:CC FLAGS_REG))]
8508 "reload_completed
8509 && ANY_QI_REG_P (operands[0])
8510 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8511 && !(INTVAL (operands[2]) & ~255)
8512 && (INTVAL (operands[2]) & 128)
8513 && GET_MODE (operands[0]) != QImode"
8514 [(parallel [(set (strict_low_part (match_dup 0))
8515 (any_or:QI (match_dup 1)
8516 (match_dup 2)))
8517 (clobber (reg:CC FLAGS_REG))])]
8518 "operands[0] = gen_lowpart (QImode, operands[0]);
8519 operands[1] = gen_lowpart (QImode, operands[1]);
8520 operands[2] = gen_lowpart (QImode, operands[2]);")
8521
8522 (define_expand "xorqi_cc_ext_1"
8523 [(parallel [
8524 (set (reg:CCNO FLAGS_REG)
8525 (compare:CCNO
8526 (xor:SI
8527 (zero_extract:SI
8528 (match_operand 1 "ext_register_operand" "")
8529 (const_int 8)
8530 (const_int 8))
8531 (match_operand:QI 2 "general_operand" ""))
8532 (const_int 0)))
8533 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8534 (const_int 8)
8535 (const_int 8))
8536 (xor:SI
8537 (zero_extract:SI
8538 (match_dup 1)
8539 (const_int 8)
8540 (const_int 8))
8541 (match_dup 2)))])]
8542 ""
8543 "")
8544
8545 (define_insn "*xorqi_cc_ext_1_rex64"
8546 [(set (reg FLAGS_REG)
8547 (compare
8548 (xor:SI
8549 (zero_extract:SI
8550 (match_operand 1 "ext_register_operand" "0")
8551 (const_int 8)
8552 (const_int 8))
8553 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8554 (const_int 0)))
8555 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8556 (const_int 8)
8557 (const_int 8))
8558 (xor:SI
8559 (zero_extract:SI
8560 (match_dup 1)
8561 (const_int 8)
8562 (const_int 8))
8563 (match_dup 2)))]
8564 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8565 "xor{b}\t{%2, %h0|%h0, %2}"
8566 [(set_attr "type" "alu")
8567 (set_attr "modrm" "1")
8568 (set_attr "mode" "QI")])
8569
8570 (define_insn "*xorqi_cc_ext_1"
8571 [(set (reg FLAGS_REG)
8572 (compare
8573 (xor:SI
8574 (zero_extract:SI
8575 (match_operand 1 "ext_register_operand" "0")
8576 (const_int 8)
8577 (const_int 8))
8578 (match_operand:QI 2 "general_operand" "qmn"))
8579 (const_int 0)))
8580 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8581 (const_int 8)
8582 (const_int 8))
8583 (xor:SI
8584 (zero_extract:SI
8585 (match_dup 1)
8586 (const_int 8)
8587 (const_int 8))
8588 (match_dup 2)))]
8589 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8590 "xor{b}\t{%2, %h0|%h0, %2}"
8591 [(set_attr "type" "alu")
8592 (set_attr "modrm" "1")
8593 (set_attr "mode" "QI")])
8594 \f
8595 ;; Negation instructions
8596
8597 (define_expand "neg<mode>2"
8598 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8599 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8600 ""
8601 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8602
8603 (define_insn_and_split "*neg<dwi>2_doubleword"
8604 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8605 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8608 "#"
8609 "reload_completed"
8610 [(parallel
8611 [(set (reg:CCZ FLAGS_REG)
8612 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8613 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8614 (parallel
8615 [(set (match_dup 2)
8616 (plus:DWIH (match_dup 3)
8617 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8618 (const_int 0))))
8619 (clobber (reg:CC FLAGS_REG))])
8620 (parallel
8621 [(set (match_dup 2)
8622 (neg:DWIH (match_dup 2)))
8623 (clobber (reg:CC FLAGS_REG))])]
8624 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8625
8626 (define_insn "*neg<mode>2_1"
8627 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8628 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8629 (clobber (reg:CC FLAGS_REG))]
8630 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8631 "neg{<imodesuffix>}\t%0"
8632 [(set_attr "type" "negnot")
8633 (set_attr "mode" "<MODE>")])
8634
8635 ;; Combine is quite creative about this pattern.
8636 (define_insn "*negsi2_1_zext"
8637 [(set (match_operand:DI 0 "register_operand" "=r")
8638 (lshiftrt:DI
8639 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8640 (const_int 32)))
8641 (const_int 32)))
8642 (clobber (reg:CC FLAGS_REG))]
8643 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8644 "neg{l}\t%k0"
8645 [(set_attr "type" "negnot")
8646 (set_attr "mode" "SI")])
8647
8648 ;; The problem with neg is that it does not perform (compare x 0),
8649 ;; it really performs (compare 0 x), which leaves us with the zero
8650 ;; flag being the only useful item.
8651
8652 (define_insn "*neg<mode>2_cmpz"
8653 [(set (reg:CCZ FLAGS_REG)
8654 (compare:CCZ
8655 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8656 (const_int 0)))
8657 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8658 (neg:SWI (match_dup 1)))]
8659 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8660 "neg{<imodesuffix>}\t%0"
8661 [(set_attr "type" "negnot")
8662 (set_attr "mode" "<MODE>")])
8663
8664 (define_insn "*negsi2_cmpz_zext"
8665 [(set (reg:CCZ FLAGS_REG)
8666 (compare:CCZ
8667 (lshiftrt:DI
8668 (neg:DI (ashift:DI
8669 (match_operand:DI 1 "register_operand" "0")
8670 (const_int 32)))
8671 (const_int 32))
8672 (const_int 0)))
8673 (set (match_operand:DI 0 "register_operand" "=r")
8674 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8675 (const_int 32)))
8676 (const_int 32)))]
8677 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8678 "neg{l}\t%k0"
8679 [(set_attr "type" "negnot")
8680 (set_attr "mode" "SI")])
8681
8682 ;; Changing of sign for FP values is doable using integer unit too.
8683
8684 (define_expand "<code><mode>2"
8685 [(set (match_operand:X87MODEF 0 "register_operand" "")
8686 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8687 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8688 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8689
8690 (define_insn "*absneg<mode>2_mixed"
8691 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8692 (match_operator:MODEF 3 "absneg_operator"
8693 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8694 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8695 (clobber (reg:CC FLAGS_REG))]
8696 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8697 "#")
8698
8699 (define_insn "*absneg<mode>2_sse"
8700 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8701 (match_operator:MODEF 3 "absneg_operator"
8702 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8703 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8704 (clobber (reg:CC FLAGS_REG))]
8705 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8706 "#")
8707
8708 (define_insn "*absneg<mode>2_i387"
8709 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8710 (match_operator:X87MODEF 3 "absneg_operator"
8711 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8712 (use (match_operand 2 "" ""))
8713 (clobber (reg:CC FLAGS_REG))]
8714 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8715 "#")
8716
8717 (define_expand "<code>tf2"
8718 [(set (match_operand:TF 0 "register_operand" "")
8719 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8720 "TARGET_SSE2"
8721 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8722
8723 (define_insn "*absnegtf2_sse"
8724 [(set (match_operand:TF 0 "register_operand" "=x,x")
8725 (match_operator:TF 3 "absneg_operator"
8726 [(match_operand:TF 1 "register_operand" "0,x")]))
8727 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8728 (clobber (reg:CC FLAGS_REG))]
8729 "TARGET_SSE2"
8730 "#")
8731
8732 ;; Splitters for fp abs and neg.
8733
8734 (define_split
8735 [(set (match_operand 0 "fp_register_operand" "")
8736 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8737 (use (match_operand 2 "" ""))
8738 (clobber (reg:CC FLAGS_REG))]
8739 "reload_completed"
8740 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8741
8742 (define_split
8743 [(set (match_operand 0 "register_operand" "")
8744 (match_operator 3 "absneg_operator"
8745 [(match_operand 1 "register_operand" "")]))
8746 (use (match_operand 2 "nonimmediate_operand" ""))
8747 (clobber (reg:CC FLAGS_REG))]
8748 "reload_completed && SSE_REG_P (operands[0])"
8749 [(set (match_dup 0) (match_dup 3))]
8750 {
8751 enum machine_mode mode = GET_MODE (operands[0]);
8752 enum machine_mode vmode = GET_MODE (operands[2]);
8753 rtx tmp;
8754
8755 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8756 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8757 if (operands_match_p (operands[0], operands[2]))
8758 {
8759 tmp = operands[1];
8760 operands[1] = operands[2];
8761 operands[2] = tmp;
8762 }
8763 if (GET_CODE (operands[3]) == ABS)
8764 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8765 else
8766 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8767 operands[3] = tmp;
8768 })
8769
8770 (define_split
8771 [(set (match_operand:SF 0 "register_operand" "")
8772 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8773 (use (match_operand:V4SF 2 "" ""))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "reload_completed"
8776 [(parallel [(set (match_dup 0) (match_dup 1))
8777 (clobber (reg:CC FLAGS_REG))])]
8778 {
8779 rtx tmp;
8780 operands[0] = gen_lowpart (SImode, operands[0]);
8781 if (GET_CODE (operands[1]) == ABS)
8782 {
8783 tmp = gen_int_mode (0x7fffffff, SImode);
8784 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8785 }
8786 else
8787 {
8788 tmp = gen_int_mode (0x80000000, SImode);
8789 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8790 }
8791 operands[1] = tmp;
8792 })
8793
8794 (define_split
8795 [(set (match_operand:DF 0 "register_operand" "")
8796 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8797 (use (match_operand 2 "" ""))
8798 (clobber (reg:CC FLAGS_REG))]
8799 "reload_completed"
8800 [(parallel [(set (match_dup 0) (match_dup 1))
8801 (clobber (reg:CC FLAGS_REG))])]
8802 {
8803 rtx tmp;
8804 if (TARGET_64BIT)
8805 {
8806 tmp = gen_lowpart (DImode, operands[0]);
8807 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8808 operands[0] = tmp;
8809
8810 if (GET_CODE (operands[1]) == ABS)
8811 tmp = const0_rtx;
8812 else
8813 tmp = gen_rtx_NOT (DImode, tmp);
8814 }
8815 else
8816 {
8817 operands[0] = gen_highpart (SImode, operands[0]);
8818 if (GET_CODE (operands[1]) == ABS)
8819 {
8820 tmp = gen_int_mode (0x7fffffff, SImode);
8821 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822 }
8823 else
8824 {
8825 tmp = gen_int_mode (0x80000000, SImode);
8826 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827 }
8828 }
8829 operands[1] = tmp;
8830 })
8831
8832 (define_split
8833 [(set (match_operand:XF 0 "register_operand" "")
8834 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8835 (use (match_operand 2 "" ""))
8836 (clobber (reg:CC FLAGS_REG))]
8837 "reload_completed"
8838 [(parallel [(set (match_dup 0) (match_dup 1))
8839 (clobber (reg:CC FLAGS_REG))])]
8840 {
8841 rtx tmp;
8842 operands[0] = gen_rtx_REG (SImode,
8843 true_regnum (operands[0])
8844 + (TARGET_64BIT ? 1 : 2));
8845 if (GET_CODE (operands[1]) == ABS)
8846 {
8847 tmp = GEN_INT (0x7fff);
8848 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8849 }
8850 else
8851 {
8852 tmp = GEN_INT (0x8000);
8853 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8854 }
8855 operands[1] = tmp;
8856 })
8857
8858 ;; Conditionalize these after reload. If they match before reload, we
8859 ;; lose the clobber and ability to use integer instructions.
8860
8861 (define_insn "*<code><mode>2_1"
8862 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8863 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8864 "TARGET_80387
8865 && (reload_completed
8866 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8867 "f<absneg_mnemonic>"
8868 [(set_attr "type" "fsgn")
8869 (set_attr "mode" "<MODE>")])
8870
8871 (define_insn "*<code>extendsfdf2"
8872 [(set (match_operand:DF 0 "register_operand" "=f")
8873 (absneg:DF (float_extend:DF
8874 (match_operand:SF 1 "register_operand" "0"))))]
8875 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8876 "f<absneg_mnemonic>"
8877 [(set_attr "type" "fsgn")
8878 (set_attr "mode" "DF")])
8879
8880 (define_insn "*<code>extendsfxf2"
8881 [(set (match_operand:XF 0 "register_operand" "=f")
8882 (absneg:XF (float_extend:XF
8883 (match_operand:SF 1 "register_operand" "0"))))]
8884 "TARGET_80387"
8885 "f<absneg_mnemonic>"
8886 [(set_attr "type" "fsgn")
8887 (set_attr "mode" "XF")])
8888
8889 (define_insn "*<code>extenddfxf2"
8890 [(set (match_operand:XF 0 "register_operand" "=f")
8891 (absneg:XF (float_extend:XF
8892 (match_operand:DF 1 "register_operand" "0"))))]
8893 "TARGET_80387"
8894 "f<absneg_mnemonic>"
8895 [(set_attr "type" "fsgn")
8896 (set_attr "mode" "XF")])
8897
8898 ;; Copysign instructions
8899
8900 (define_mode_iterator CSGNMODE [SF DF TF])
8901 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8902
8903 (define_expand "copysign<mode>3"
8904 [(match_operand:CSGNMODE 0 "register_operand" "")
8905 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8906 (match_operand:CSGNMODE 2 "register_operand" "")]
8907 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8909 {
8910 ix86_expand_copysign (operands);
8911 DONE;
8912 })
8913
8914 (define_insn_and_split "copysign<mode>3_const"
8915 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8916 (unspec:CSGNMODE
8917 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8918 (match_operand:CSGNMODE 2 "register_operand" "0")
8919 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8920 UNSPEC_COPYSIGN))]
8921 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8922 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8923 "#"
8924 "&& reload_completed"
8925 [(const_int 0)]
8926 {
8927 ix86_split_copysign_const (operands);
8928 DONE;
8929 })
8930
8931 (define_insn "copysign<mode>3_var"
8932 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8933 (unspec:CSGNMODE
8934 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8935 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8936 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8937 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8938 UNSPEC_COPYSIGN))
8939 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8942 "#")
8943
8944 (define_split
8945 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8946 (unspec:CSGNMODE
8947 [(match_operand:CSGNMODE 2 "register_operand" "")
8948 (match_operand:CSGNMODE 3 "register_operand" "")
8949 (match_operand:<CSGNVMODE> 4 "" "")
8950 (match_operand:<CSGNVMODE> 5 "" "")]
8951 UNSPEC_COPYSIGN))
8952 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8953 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8954 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8955 && reload_completed"
8956 [(const_int 0)]
8957 {
8958 ix86_split_copysign_var (operands);
8959 DONE;
8960 })
8961 \f
8962 ;; One complement instructions
8963
8964 (define_expand "one_cmpl<mode>2"
8965 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8966 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8967 ""
8968 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8969
8970 (define_insn "*one_cmpl<mode>2_1"
8971 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8972 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8973 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8974 "not{<imodesuffix>}\t%0"
8975 [(set_attr "type" "negnot")
8976 (set_attr "mode" "<MODE>")])
8977
8978 ;; %%% Potential partial reg stall on alternative 1. What to do?
8979 (define_insn "*one_cmplqi2_1"
8980 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8981 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8982 "ix86_unary_operator_ok (NOT, QImode, operands)"
8983 "@
8984 not{b}\t%0
8985 not{l}\t%k0"
8986 [(set_attr "type" "negnot")
8987 (set_attr "mode" "QI,SI")])
8988
8989 ;; ??? Currently never generated - xor is used instead.
8990 (define_insn "*one_cmplsi2_1_zext"
8991 [(set (match_operand:DI 0 "register_operand" "=r")
8992 (zero_extend:DI
8993 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8994 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8995 "not{l}\t%k0"
8996 [(set_attr "type" "negnot")
8997 (set_attr "mode" "SI")])
8998
8999 (define_insn "*one_cmpl<mode>2_2"
9000 [(set (reg FLAGS_REG)
9001 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9002 (const_int 0)))
9003 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9004 (not:SWI (match_dup 1)))]
9005 "ix86_match_ccmode (insn, CCNOmode)
9006 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9007 "#"
9008 [(set_attr "type" "alu1")
9009 (set_attr "mode" "<MODE>")])
9010
9011 (define_split
9012 [(set (match_operand 0 "flags_reg_operand" "")
9013 (match_operator 2 "compare_operator"
9014 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9015 (const_int 0)]))
9016 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9017 (not:SWI (match_dup 3)))]
9018 "ix86_match_ccmode (insn, CCNOmode)"
9019 [(parallel [(set (match_dup 0)
9020 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9021 (const_int 0)]))
9022 (set (match_dup 1)
9023 (xor:SWI (match_dup 3) (const_int -1)))])]
9024 "")
9025
9026 ;; ??? Currently never generated - xor is used instead.
9027 (define_insn "*one_cmplsi2_2_zext"
9028 [(set (reg FLAGS_REG)
9029 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9030 (const_int 0)))
9031 (set (match_operand:DI 0 "register_operand" "=r")
9032 (zero_extend:DI (not:SI (match_dup 1))))]
9033 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9034 && ix86_unary_operator_ok (NOT, SImode, operands)"
9035 "#"
9036 [(set_attr "type" "alu1")
9037 (set_attr "mode" "SI")])
9038
9039 (define_split
9040 [(set (match_operand 0 "flags_reg_operand" "")
9041 (match_operator 2 "compare_operator"
9042 [(not:SI (match_operand:SI 3 "register_operand" ""))
9043 (const_int 0)]))
9044 (set (match_operand:DI 1 "register_operand" "")
9045 (zero_extend:DI (not:SI (match_dup 3))))]
9046 "ix86_match_ccmode (insn, CCNOmode)"
9047 [(parallel [(set (match_dup 0)
9048 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9049 (const_int 0)]))
9050 (set (match_dup 1)
9051 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9052 "")
9053 \f
9054 ;; Shift instructions
9055
9056 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9057 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9058 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9059 ;; from the assembler input.
9060 ;;
9061 ;; This instruction shifts the target reg/mem as usual, but instead of
9062 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9063 ;; is a left shift double, bits are taken from the high order bits of
9064 ;; reg, else if the insn is a shift right double, bits are taken from the
9065 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9066 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9067 ;;
9068 ;; Since sh[lr]d does not change the `reg' operand, that is done
9069 ;; separately, making all shifts emit pairs of shift double and normal
9070 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9071 ;; support a 63 bit shift, each shift where the count is in a reg expands
9072 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9073 ;;
9074 ;; If the shift count is a constant, we need never emit more than one
9075 ;; shift pair, instead using moves and sign extension for counts greater
9076 ;; than 31.
9077
9078 (define_expand "ashl<mode>3"
9079 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9080 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9081 (match_operand:QI 2 "nonmemory_operand" "")))]
9082 ""
9083 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9084
9085 (define_insn "*ashl<mode>3_doubleword"
9086 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9087 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9088 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9089 (clobber (reg:CC FLAGS_REG))]
9090 ""
9091 "#"
9092 [(set_attr "type" "multi")])
9093
9094 (define_split
9095 [(set (match_operand:DWI 0 "register_operand" "")
9096 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9097 (match_operand:QI 2 "nonmemory_operand" "")))
9098 (clobber (reg:CC FLAGS_REG))]
9099 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9100 [(const_int 0)]
9101 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9102
9103 ;; By default we don't ask for a scratch register, because when DWImode
9104 ;; values are manipulated, registers are already at a premium. But if
9105 ;; we have one handy, we won't turn it away.
9106
9107 (define_peephole2
9108 [(match_scratch:DWIH 3 "r")
9109 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9110 (ashift:<DWI>
9111 (match_operand:<DWI> 1 "nonmemory_operand" "")
9112 (match_operand:QI 2 "nonmemory_operand" "")))
9113 (clobber (reg:CC FLAGS_REG))])
9114 (match_dup 3)]
9115 "TARGET_CMOVE"
9116 [(const_int 0)]
9117 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9118
9119 (define_insn "x86_64_shld"
9120 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9121 (ior:DI (ashift:DI (match_dup 0)
9122 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9123 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9124 (minus:QI (const_int 64) (match_dup 2)))))
9125 (clobber (reg:CC FLAGS_REG))]
9126 "TARGET_64BIT"
9127 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9128 [(set_attr "type" "ishift")
9129 (set_attr "prefix_0f" "1")
9130 (set_attr "mode" "DI")
9131 (set_attr "athlon_decode" "vector")
9132 (set_attr "amdfam10_decode" "vector")])
9133
9134 (define_insn "x86_shld"
9135 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9136 (ior:SI (ashift:SI (match_dup 0)
9137 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9138 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9139 (minus:QI (const_int 32) (match_dup 2)))))
9140 (clobber (reg:CC FLAGS_REG))]
9141 ""
9142 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9143 [(set_attr "type" "ishift")
9144 (set_attr "prefix_0f" "1")
9145 (set_attr "mode" "SI")
9146 (set_attr "pent_pair" "np")
9147 (set_attr "athlon_decode" "vector")
9148 (set_attr "amdfam10_decode" "vector")])
9149
9150 (define_expand "x86_shift<mode>_adj_1"
9151 [(set (reg:CCZ FLAGS_REG)
9152 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9153 (match_dup 4))
9154 (const_int 0)))
9155 (set (match_operand:SWI48 0 "register_operand" "")
9156 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9157 (match_operand:SWI48 1 "register_operand" "")
9158 (match_dup 0)))
9159 (set (match_dup 1)
9160 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9161 (match_operand:SWI48 3 "register_operand" "r")
9162 (match_dup 1)))]
9163 "TARGET_CMOVE"
9164 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9165
9166 (define_expand "x86_shift<mode>_adj_2"
9167 [(use (match_operand:SWI48 0 "register_operand" ""))
9168 (use (match_operand:SWI48 1 "register_operand" ""))
9169 (use (match_operand:QI 2 "register_operand" ""))]
9170 ""
9171 {
9172 rtx label = gen_label_rtx ();
9173 rtx tmp;
9174
9175 emit_insn (gen_testqi_ccz_1 (operands[2],
9176 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9177
9178 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9179 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9180 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9181 gen_rtx_LABEL_REF (VOIDmode, label),
9182 pc_rtx);
9183 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9184 JUMP_LABEL (tmp) = label;
9185
9186 emit_move_insn (operands[0], operands[1]);
9187 ix86_expand_clear (operands[1]);
9188
9189 emit_label (label);
9190 LABEL_NUSES (label) = 1;
9191
9192 DONE;
9193 })
9194
9195 (define_insn "*ashl<mode>3_1"
9196 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9197 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9198 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9201 {
9202 switch (get_attr_type (insn))
9203 {
9204 case TYPE_LEA:
9205 return "#";
9206
9207 case TYPE_ALU:
9208 gcc_assert (operands[2] == const1_rtx);
9209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9210 return "add{<imodesuffix>}\t%0, %0";
9211
9212 default:
9213 if (operands[2] == const1_rtx
9214 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9215 return "sal{<imodesuffix>}\t%0";
9216 else
9217 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9218 }
9219 }
9220 [(set (attr "type")
9221 (cond [(eq_attr "alternative" "1")
9222 (const_string "lea")
9223 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9224 (const_int 0))
9225 (match_operand 0 "register_operand" ""))
9226 (match_operand 2 "const1_operand" ""))
9227 (const_string "alu")
9228 ]
9229 (const_string "ishift")))
9230 (set (attr "length_immediate")
9231 (if_then_else
9232 (ior (eq_attr "type" "alu")
9233 (and (eq_attr "type" "ishift")
9234 (and (match_operand 2 "const1_operand" "")
9235 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9236 (const_int 0)))))
9237 (const_string "0")
9238 (const_string "*")))
9239 (set_attr "mode" "<MODE>")])
9240
9241 (define_insn "*ashlsi3_1_zext"
9242 [(set (match_operand:DI 0 "register_operand" "=r,r")
9243 (zero_extend:DI
9244 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9245 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9248 {
9249 switch (get_attr_type (insn))
9250 {
9251 case TYPE_LEA:
9252 return "#";
9253
9254 case TYPE_ALU:
9255 gcc_assert (operands[2] == const1_rtx);
9256 return "add{l}\t%k0, %k0";
9257
9258 default:
9259 if (operands[2] == const1_rtx
9260 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9261 return "sal{l}\t%k0";
9262 else
9263 return "sal{l}\t{%2, %k0|%k0, %2}";
9264 }
9265 }
9266 [(set (attr "type")
9267 (cond [(eq_attr "alternative" "1")
9268 (const_string "lea")
9269 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9270 (const_int 0))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9273 ]
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9276 (if_then_else
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9281 (const_int 0)))))
9282 (const_string "0")
9283 (const_string "*")))
9284 (set_attr "mode" "SI")])
9285
9286 (define_insn "*ashlhi3_1"
9287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9288 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9289 (match_operand:QI 2 "nonmemory_operand" "cI")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "TARGET_PARTIAL_REG_STALL
9292 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9293 {
9294 switch (get_attr_type (insn))
9295 {
9296 case TYPE_ALU:
9297 gcc_assert (operands[2] == const1_rtx);
9298 return "add{w}\t%0, %0";
9299
9300 default:
9301 if (operands[2] == const1_rtx
9302 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9303 return "sal{w}\t%0";
9304 else
9305 return "sal{w}\t{%2, %0|%0, %2}";
9306 }
9307 }
9308 [(set (attr "type")
9309 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9310 (const_int 0))
9311 (match_operand 0 "register_operand" ""))
9312 (match_operand 2 "const1_operand" ""))
9313 (const_string "alu")
9314 ]
9315 (const_string "ishift")))
9316 (set (attr "length_immediate")
9317 (if_then_else
9318 (ior (eq_attr "type" "alu")
9319 (and (eq_attr "type" "ishift")
9320 (and (match_operand 2 "const1_operand" "")
9321 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9322 (const_int 0)))))
9323 (const_string "0")
9324 (const_string "*")))
9325 (set_attr "mode" "HI")])
9326
9327 (define_insn "*ashlhi3_1_lea"
9328 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9329 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9330 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9331 (clobber (reg:CC FLAGS_REG))]
9332 "!TARGET_PARTIAL_REG_STALL
9333 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9334 {
9335 switch (get_attr_type (insn))
9336 {
9337 case TYPE_LEA:
9338 return "#";
9339
9340 case TYPE_ALU:
9341 gcc_assert (operands[2] == const1_rtx);
9342 return "add{w}\t%0, %0";
9343
9344 default:
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9347 return "sal{w}\t%0";
9348 else
9349 return "sal{w}\t{%2, %0|%0, %2}";
9350 }
9351 }
9352 [(set (attr "type")
9353 (cond [(eq_attr "alternative" "1")
9354 (const_string "lea")
9355 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9356 (const_int 0))
9357 (match_operand 0 "register_operand" ""))
9358 (match_operand 2 "const1_operand" ""))
9359 (const_string "alu")
9360 ]
9361 (const_string "ishift")))
9362 (set (attr "length_immediate")
9363 (if_then_else
9364 (ior (eq_attr "type" "alu")
9365 (and (eq_attr "type" "ishift")
9366 (and (match_operand 2 "const1_operand" "")
9367 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9368 (const_int 0)))))
9369 (const_string "0")
9370 (const_string "*")))
9371 (set_attr "mode" "HI,SI")])
9372
9373 (define_insn "*ashlqi3_1"
9374 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9375 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9376 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9377 (clobber (reg:CC FLAGS_REG))]
9378 "TARGET_PARTIAL_REG_STALL
9379 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9380 {
9381 switch (get_attr_type (insn))
9382 {
9383 case TYPE_ALU:
9384 gcc_assert (operands[2] == const1_rtx);
9385 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9386 return "add{l}\t%k0, %k0";
9387 else
9388 return "add{b}\t%0, %0";
9389
9390 default:
9391 if (operands[2] == const1_rtx
9392 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9393 {
9394 if (get_attr_mode (insn) == MODE_SI)
9395 return "sal{l}\t%k0";
9396 else
9397 return "sal{b}\t%0";
9398 }
9399 else
9400 {
9401 if (get_attr_mode (insn) == MODE_SI)
9402 return "sal{l}\t{%2, %k0|%k0, %2}";
9403 else
9404 return "sal{b}\t{%2, %0|%0, %2}";
9405 }
9406 }
9407 }
9408 [(set (attr "type")
9409 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9410 (const_int 0))
9411 (match_operand 0 "register_operand" ""))
9412 (match_operand 2 "const1_operand" ""))
9413 (const_string "alu")
9414 ]
9415 (const_string "ishift")))
9416 (set (attr "length_immediate")
9417 (if_then_else
9418 (ior (eq_attr "type" "alu")
9419 (and (eq_attr "type" "ishift")
9420 (and (match_operand 2 "const1_operand" "")
9421 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9422 (const_int 0)))))
9423 (const_string "0")
9424 (const_string "*")))
9425 (set_attr "mode" "QI,SI")])
9426
9427 ;; %%% Potential partial reg stall on alternative 2. What to do?
9428 (define_insn "*ashlqi3_1_lea"
9429 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9430 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9431 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9432 (clobber (reg:CC FLAGS_REG))]
9433 "!TARGET_PARTIAL_REG_STALL
9434 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9435 {
9436 switch (get_attr_type (insn))
9437 {
9438 case TYPE_LEA:
9439 return "#";
9440
9441 case TYPE_ALU:
9442 gcc_assert (operands[2] == const1_rtx);
9443 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9444 return "add{l}\t%k0, %k0";
9445 else
9446 return "add{b}\t%0, %0";
9447
9448 default:
9449 if (operands[2] == const1_rtx
9450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9451 {
9452 if (get_attr_mode (insn) == MODE_SI)
9453 return "sal{l}\t%k0";
9454 else
9455 return "sal{b}\t%0";
9456 }
9457 else
9458 {
9459 if (get_attr_mode (insn) == MODE_SI)
9460 return "sal{l}\t{%2, %k0|%k0, %2}";
9461 else
9462 return "sal{b}\t{%2, %0|%0, %2}";
9463 }
9464 }
9465 }
9466 [(set (attr "type")
9467 (cond [(eq_attr "alternative" "2")
9468 (const_string "lea")
9469 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9470 (const_int 0))
9471 (match_operand 0 "register_operand" ""))
9472 (match_operand 2 "const1_operand" ""))
9473 (const_string "alu")
9474 ]
9475 (const_string "ishift")))
9476 (set (attr "length_immediate")
9477 (if_then_else
9478 (ior (eq_attr "type" "alu")
9479 (and (eq_attr "type" "ishift")
9480 (and (match_operand 2 "const1_operand" "")
9481 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9482 (const_int 0)))))
9483 (const_string "0")
9484 (const_string "*")))
9485 (set_attr "mode" "QI,SI,SI")])
9486
9487 (define_insn "*ashlqi3_1_slp"
9488 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9489 (ashift:QI (match_dup 0)
9490 (match_operand:QI 1 "nonmemory_operand" "cI")))
9491 (clobber (reg:CC FLAGS_REG))]
9492 "(optimize_function_for_size_p (cfun)
9493 || !TARGET_PARTIAL_FLAG_REG_STALL
9494 || (operands[1] == const1_rtx
9495 && (TARGET_SHIFT1
9496 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9497 {
9498 switch (get_attr_type (insn))
9499 {
9500 case TYPE_ALU:
9501 gcc_assert (operands[1] == const1_rtx);
9502 return "add{b}\t%0, %0";
9503
9504 default:
9505 if (operands[1] == const1_rtx
9506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9507 return "sal{b}\t%0";
9508 else
9509 return "sal{b}\t{%1, %0|%0, %1}";
9510 }
9511 }
9512 [(set (attr "type")
9513 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9514 (const_int 0))
9515 (match_operand 0 "register_operand" ""))
9516 (match_operand 1 "const1_operand" ""))
9517 (const_string "alu")
9518 ]
9519 (const_string "ishift1")))
9520 (set (attr "length_immediate")
9521 (if_then_else
9522 (ior (eq_attr "type" "alu")
9523 (and (eq_attr "type" "ishift1")
9524 (and (match_operand 1 "const1_operand" "")
9525 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9526 (const_int 0)))))
9527 (const_string "0")
9528 (const_string "*")))
9529 (set_attr "mode" "QI")])
9530
9531 ;; Convert lea to the lea pattern to avoid flags dependency.
9532 (define_split
9533 [(set (match_operand:DI 0 "register_operand" "")
9534 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9535 (match_operand:QI 2 "const_int_operand" "")))
9536 (clobber (reg:CC FLAGS_REG))]
9537 "TARGET_64BIT && reload_completed
9538 && true_regnum (operands[0]) != true_regnum (operands[1])"
9539 [(set (match_dup 0)
9540 (mult:DI (match_dup 1)
9541 (match_dup 2)))]
9542 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9543
9544 ;; Convert lea to the lea pattern to avoid flags dependency.
9545 (define_split
9546 [(set (match_operand 0 "register_operand" "")
9547 (ashift (match_operand 1 "index_register_operand" "")
9548 (match_operand:QI 2 "const_int_operand" "")))
9549 (clobber (reg:CC FLAGS_REG))]
9550 "reload_completed
9551 && true_regnum (operands[0]) != true_regnum (operands[1])
9552 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9553 [(const_int 0)]
9554 {
9555 rtx pat;
9556 enum machine_mode mode = GET_MODE (operands[0]);
9557
9558 if (GET_MODE_SIZE (mode) < 4)
9559 operands[0] = gen_lowpart (SImode, operands[0]);
9560 if (mode != Pmode)
9561 operands[1] = gen_lowpart (Pmode, operands[1]);
9562 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9563
9564 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9565 if (Pmode != SImode)
9566 pat = gen_rtx_SUBREG (SImode, pat, 0);
9567 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9568 DONE;
9569 })
9570
9571 ;; Rare case of shifting RSP is handled by generating move and shift
9572 (define_split
9573 [(set (match_operand 0 "register_operand" "")
9574 (ashift (match_operand 1 "register_operand" "")
9575 (match_operand:QI 2 "const_int_operand" "")))
9576 (clobber (reg:CC FLAGS_REG))]
9577 "reload_completed
9578 && true_regnum (operands[0]) != true_regnum (operands[1])"
9579 [(const_int 0)]
9580 {
9581 rtx pat, clob;
9582 emit_move_insn (operands[0], operands[1]);
9583 pat = gen_rtx_SET (VOIDmode, operands[0],
9584 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9585 operands[0], operands[2]));
9586 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9587 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9588 DONE;
9589 })
9590
9591 ;; Convert lea to the lea pattern to avoid flags dependency.
9592 (define_split
9593 [(set (match_operand:DI 0 "register_operand" "")
9594 (zero_extend:DI
9595 (ashift:SI (match_operand:SI 1 "register_operand" "")
9596 (match_operand:QI 2 "const_int_operand" ""))))
9597 (clobber (reg:CC FLAGS_REG))]
9598 "TARGET_64BIT && reload_completed
9599 && true_regnum (operands[0]) != true_regnum (operands[1])"
9600 [(set (match_dup 0)
9601 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9602 {
9603 operands[1] = gen_lowpart (Pmode, operands[1]);
9604 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9605 })
9606
9607 ;; This pattern can't accept a variable shift count, since shifts by
9608 ;; zero don't affect the flags. We assume that shifts by constant
9609 ;; zero are optimized away.
9610 (define_insn "*ashl<mode>3_cmp"
9611 [(set (reg FLAGS_REG)
9612 (compare
9613 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9614 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9615 (const_int 0)))
9616 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9617 (ashift:SWI (match_dup 1) (match_dup 2)))]
9618 "(optimize_function_for_size_p (cfun)
9619 || !TARGET_PARTIAL_FLAG_REG_STALL
9620 || (operands[2] == const1_rtx
9621 && (TARGET_SHIFT1
9622 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9623 && ix86_match_ccmode (insn, CCGOCmode)
9624 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9625 {
9626 switch (get_attr_type (insn))
9627 {
9628 case TYPE_ALU:
9629 gcc_assert (operands[2] == const1_rtx);
9630 return "add{<imodesuffix>}\t%0, %0";
9631
9632 default:
9633 if (operands[2] == const1_rtx
9634 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9635 return "sal{<imodesuffix>}\t%0";
9636 else
9637 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9638 }
9639 }
9640 [(set (attr "type")
9641 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9642 (const_int 0))
9643 (match_operand 0 "register_operand" ""))
9644 (match_operand 2 "const1_operand" ""))
9645 (const_string "alu")
9646 ]
9647 (const_string "ishift")))
9648 (set (attr "length_immediate")
9649 (if_then_else
9650 (ior (eq_attr "type" "alu")
9651 (and (eq_attr "type" "ishift")
9652 (and (match_operand 2 "const1_operand" "")
9653 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9654 (const_int 0)))))
9655 (const_string "0")
9656 (const_string "*")))
9657 (set_attr "mode" "<MODE>")])
9658
9659 (define_insn "*ashlsi3_cmp_zext"
9660 [(set (reg FLAGS_REG)
9661 (compare
9662 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9664 (const_int 0)))
9665 (set (match_operand:DI 0 "register_operand" "=r")
9666 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9667 "TARGET_64BIT
9668 && (optimize_function_for_size_p (cfun)
9669 || !TARGET_PARTIAL_FLAG_REG_STALL
9670 || (operands[2] == const1_rtx
9671 && (TARGET_SHIFT1
9672 || TARGET_DOUBLE_WITH_ADD)))
9673 && ix86_match_ccmode (insn, CCGOCmode)
9674 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9675 {
9676 switch (get_attr_type (insn))
9677 {
9678 case TYPE_ALU:
9679 gcc_assert (operands[2] == const1_rtx);
9680 return "add{l}\t%k0, %k0";
9681
9682 default:
9683 if (operands[2] == const1_rtx
9684 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9685 return "sal{l}\t%k0";
9686 else
9687 return "sal{l}\t{%2, %k0|%k0, %2}";
9688 }
9689 }
9690 [(set (attr "type")
9691 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9692 (const_int 0))
9693 (match_operand 2 "const1_operand" ""))
9694 (const_string "alu")
9695 ]
9696 (const_string "ishift")))
9697 (set (attr "length_immediate")
9698 (if_then_else
9699 (ior (eq_attr "type" "alu")
9700 (and (eq_attr "type" "ishift")
9701 (and (match_operand 2 "const1_operand" "")
9702 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9703 (const_int 0)))))
9704 (const_string "0")
9705 (const_string "*")))
9706 (set_attr "mode" "SI")])
9707
9708 (define_insn "*ashl<mode>3_cconly"
9709 [(set (reg FLAGS_REG)
9710 (compare
9711 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9712 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9713 (const_int 0)))
9714 (clobber (match_scratch:SWI 0 "=<r>"))]
9715 "(optimize_function_for_size_p (cfun)
9716 || !TARGET_PARTIAL_FLAG_REG_STALL
9717 || (operands[2] == const1_rtx
9718 && (TARGET_SHIFT1
9719 || TARGET_DOUBLE_WITH_ADD)))
9720 && ix86_match_ccmode (insn, CCGOCmode)
9721 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9722 {
9723 switch (get_attr_type (insn))
9724 {
9725 case TYPE_ALU:
9726 gcc_assert (operands[2] == const1_rtx);
9727 return "add{<imodesuffix>}\t%0, %0";
9728
9729 default:
9730 if (operands[2] == const1_rtx
9731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9732 return "sal{<imodesuffix>}\t%0";
9733 else
9734 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9735 }
9736 }
9737 [(set (attr "type")
9738 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9739 (const_int 0))
9740 (match_operand 0 "register_operand" ""))
9741 (match_operand 2 "const1_operand" ""))
9742 (const_string "alu")
9743 ]
9744 (const_string "ishift")))
9745 (set (attr "length_immediate")
9746 (if_then_else
9747 (ior (eq_attr "type" "alu")
9748 (and (eq_attr "type" "ishift")
9749 (and (match_operand 2 "const1_operand" "")
9750 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9751 (const_int 0)))))
9752 (const_string "0")
9753 (const_string "*")))
9754 (set_attr "mode" "<MODE>")])
9755
9756 ;; See comment above `ashl<mode>3' about how this works.
9757
9758 (define_expand "<shiftrt_insn><mode>3"
9759 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9760 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9761 (match_operand:QI 2 "nonmemory_operand" "")))]
9762 ""
9763 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9764
9765 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9766 [(set (match_operand:DWI 0 "register_operand" "=r")
9767 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9768 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9769 (clobber (reg:CC FLAGS_REG))]
9770 ""
9771 "#"
9772 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9773 [(const_int 0)]
9774 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9775 [(set_attr "type" "multi")])
9776
9777 ;; By default we don't ask for a scratch register, because when DWImode
9778 ;; values are manipulated, registers are already at a premium. But if
9779 ;; we have one handy, we won't turn it away.
9780
9781 (define_peephole2
9782 [(match_scratch:DWIH 3 "r")
9783 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9784 (any_shiftrt:<DWI>
9785 (match_operand:<DWI> 1 "register_operand" "")
9786 (match_operand:QI 2 "nonmemory_operand" "")))
9787 (clobber (reg:CC FLAGS_REG))])
9788 (match_dup 3)]
9789 "TARGET_CMOVE"
9790 [(const_int 0)]
9791 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9792
9793 (define_insn "x86_64_shrd"
9794 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9795 (ior:DI (ashiftrt:DI (match_dup 0)
9796 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9797 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9798 (minus:QI (const_int 64) (match_dup 2)))))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_64BIT"
9801 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9802 [(set_attr "type" "ishift")
9803 (set_attr "prefix_0f" "1")
9804 (set_attr "mode" "DI")
9805 (set_attr "athlon_decode" "vector")
9806 (set_attr "amdfam10_decode" "vector")])
9807
9808 (define_insn "x86_shrd"
9809 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9810 (ior:SI (ashiftrt:SI (match_dup 0)
9811 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9812 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9813 (minus:QI (const_int 32) (match_dup 2)))))
9814 (clobber (reg:CC FLAGS_REG))]
9815 ""
9816 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9817 [(set_attr "type" "ishift")
9818 (set_attr "prefix_0f" "1")
9819 (set_attr "mode" "SI")
9820 (set_attr "pent_pair" "np")
9821 (set_attr "athlon_decode" "vector")
9822 (set_attr "amdfam10_decode" "vector")])
9823
9824 (define_insn "ashrdi3_cvt"
9825 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9826 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9827 (match_operand:QI 2 "const_int_operand" "")))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "TARGET_64BIT && INTVAL (operands[2]) == 63
9830 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9831 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9832 "@
9833 {cqto|cqo}
9834 sar{q}\t{%2, %0|%0, %2}"
9835 [(set_attr "type" "imovx,ishift")
9836 (set_attr "prefix_0f" "0,*")
9837 (set_attr "length_immediate" "0,*")
9838 (set_attr "modrm" "0,1")
9839 (set_attr "mode" "DI")])
9840
9841 (define_insn "ashrsi3_cvt"
9842 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9843 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9844 (match_operand:QI 2 "const_int_operand" "")))
9845 (clobber (reg:CC FLAGS_REG))]
9846 "INTVAL (operands[2]) == 31
9847 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9848 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9849 "@
9850 {cltd|cdq}
9851 sar{l}\t{%2, %0|%0, %2}"
9852 [(set_attr "type" "imovx,ishift")
9853 (set_attr "prefix_0f" "0,*")
9854 (set_attr "length_immediate" "0,*")
9855 (set_attr "modrm" "0,1")
9856 (set_attr "mode" "SI")])
9857
9858 (define_insn "*ashrsi3_cvt_zext"
9859 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9860 (zero_extend:DI
9861 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9862 (match_operand:QI 2 "const_int_operand" ""))))
9863 (clobber (reg:CC FLAGS_REG))]
9864 "TARGET_64BIT && INTVAL (operands[2]) == 31
9865 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9866 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9867 "@
9868 {cltd|cdq}
9869 sar{l}\t{%2, %k0|%k0, %2}"
9870 [(set_attr "type" "imovx,ishift")
9871 (set_attr "prefix_0f" "0,*")
9872 (set_attr "length_immediate" "0,*")
9873 (set_attr "modrm" "0,1")
9874 (set_attr "mode" "SI")])
9875
9876 (define_expand "x86_shift<mode>_adj_3"
9877 [(use (match_operand:SWI48 0 "register_operand" ""))
9878 (use (match_operand:SWI48 1 "register_operand" ""))
9879 (use (match_operand:QI 2 "register_operand" ""))]
9880 ""
9881 {
9882 rtx label = gen_label_rtx ();
9883 rtx tmp;
9884
9885 emit_insn (gen_testqi_ccz_1 (operands[2],
9886 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9887
9888 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9889 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9890 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9891 gen_rtx_LABEL_REF (VOIDmode, label),
9892 pc_rtx);
9893 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9894 JUMP_LABEL (tmp) = label;
9895
9896 emit_move_insn (operands[0], operands[1]);
9897 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9898 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9899 emit_label (label);
9900 LABEL_NUSES (label) = 1;
9901
9902 DONE;
9903 })
9904
9905 (define_insn "*<shiftrt_insn><mode>3_1"
9906 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9907 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9908 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9909 (clobber (reg:CC FLAGS_REG))]
9910 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9911 {
9912 if (operands[2] == const1_rtx
9913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9914 return "<shiftrt>{<imodesuffix>}\t%0";
9915 else
9916 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9917 }
9918 [(set_attr "type" "ishift")
9919 (set (attr "length_immediate")
9920 (if_then_else
9921 (and (match_operand 2 "const1_operand" "")
9922 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9923 (const_int 0)))
9924 (const_string "0")
9925 (const_string "*")))
9926 (set_attr "mode" "<MODE>")])
9927
9928 (define_insn "*<shiftrt_insn>si3_1_zext"
9929 [(set (match_operand:DI 0 "register_operand" "=r")
9930 (zero_extend:DI
9931 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9932 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9935 {
9936 if (operands[2] == const1_rtx
9937 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9938 return "<shiftrt>{l}\t%k0";
9939 else
9940 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9941 }
9942 [(set_attr "type" "ishift")
9943 (set (attr "length_immediate")
9944 (if_then_else
9945 (and (match_operand 2 "const1_operand" "")
9946 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9947 (const_int 0)))
9948 (const_string "0")
9949 (const_string "*")))
9950 (set_attr "mode" "SI")])
9951
9952 (define_insn "*<shiftrt_insn>qi3_1_slp"
9953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9954 (any_shiftrt:QI (match_dup 0)
9955 (match_operand:QI 1 "nonmemory_operand" "cI")))
9956 (clobber (reg:CC FLAGS_REG))]
9957 "(optimize_function_for_size_p (cfun)
9958 || !TARGET_PARTIAL_REG_STALL
9959 || (operands[1] == const1_rtx
9960 && TARGET_SHIFT1))"
9961 {
9962 if (operands[1] == const1_rtx
9963 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9964 return "<shiftrt>{b}\t%0";
9965 else
9966 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9967 }
9968 [(set_attr "type" "ishift1")
9969 (set (attr "length_immediate")
9970 (if_then_else
9971 (and (match_operand 1 "const1_operand" "")
9972 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9973 (const_int 0)))
9974 (const_string "0")
9975 (const_string "*")))
9976 (set_attr "mode" "QI")])
9977
9978 ;; This pattern can't accept a variable shift count, since shifts by
9979 ;; zero don't affect the flags. We assume that shifts by constant
9980 ;; zero are optimized away.
9981 (define_insn "*<shiftrt_insn><mode>3_cmp"
9982 [(set (reg FLAGS_REG)
9983 (compare
9984 (any_shiftrt:SWI
9985 (match_operand:SWI 1 "nonimmediate_operand" "0")
9986 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9987 (const_int 0)))
9988 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9989 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9990 "(optimize_function_for_size_p (cfun)
9991 || !TARGET_PARTIAL_FLAG_REG_STALL
9992 || (operands[2] == const1_rtx
9993 && TARGET_SHIFT1))
9994 && ix86_match_ccmode (insn, CCGOCmode)
9995 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9996 {
9997 if (operands[2] == const1_rtx
9998 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9999 return "<shiftrt>{<imodesuffix>}\t%0";
10000 else
10001 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10002 }
10003 [(set_attr "type" "ishift")
10004 (set (attr "length_immediate")
10005 (if_then_else
10006 (and (match_operand 2 "const1_operand" "")
10007 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10008 (const_int 0)))
10009 (const_string "0")
10010 (const_string "*")))
10011 (set_attr "mode" "<MODE>")])
10012
10013 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10014 [(set (reg FLAGS_REG)
10015 (compare
10016 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10017 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10018 (const_int 0)))
10019 (set (match_operand:DI 0 "register_operand" "=r")
10020 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10021 "TARGET_64BIT
10022 && (optimize_function_for_size_p (cfun)
10023 || !TARGET_PARTIAL_FLAG_REG_STALL
10024 || (operands[2] == const1_rtx
10025 && TARGET_SHIFT1))
10026 && ix86_match_ccmode (insn, CCGOCmode)
10027 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10028 {
10029 if (operands[2] == const1_rtx
10030 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10031 return "<shiftrt>{l}\t%k0";
10032 else
10033 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10034 }
10035 [(set_attr "type" "ishift")
10036 (set (attr "length_immediate")
10037 (if_then_else
10038 (and (match_operand 2 "const1_operand" "")
10039 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10040 (const_int 0)))
10041 (const_string "0")
10042 (const_string "*")))
10043 (set_attr "mode" "SI")])
10044
10045 (define_insn "*<shiftrt_insn><mode>3_cconly"
10046 [(set (reg FLAGS_REG)
10047 (compare
10048 (any_shiftrt:SWI
10049 (match_operand:SWI 1 "nonimmediate_operand" "0")
10050 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10051 (const_int 0)))
10052 (clobber (match_scratch:SWI 0 "=<r>"))]
10053 "(optimize_function_for_size_p (cfun)
10054 || !TARGET_PARTIAL_FLAG_REG_STALL
10055 || (operands[2] == const1_rtx
10056 && TARGET_SHIFT1))
10057 && ix86_match_ccmode (insn, CCGOCmode)
10058 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10059 {
10060 if (operands[2] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<shiftrt>{<imodesuffix>}\t%0";
10063 else
10064 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10065 }
10066 [(set_attr "type" "ishift")
10067 (set (attr "length_immediate")
10068 (if_then_else
10069 (and (match_operand 2 "const1_operand" "")
10070 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10071 (const_int 0)))
10072 (const_string "0")
10073 (const_string "*")))
10074 (set_attr "mode" "<MODE>")])
10075 \f
10076 ;; Rotate instructions
10077
10078 (define_expand "<rotate_insn>ti3"
10079 [(set (match_operand:TI 0 "register_operand" "")
10080 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10081 (match_operand:QI 2 "nonmemory_operand" "")))]
10082 "TARGET_64BIT"
10083 {
10084 if (const_1_to_63_operand (operands[2], VOIDmode))
10085 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10086 (operands[0], operands[1], operands[2]));
10087 else
10088 FAIL;
10089
10090 DONE;
10091 })
10092
10093 (define_expand "<rotate_insn>di3"
10094 [(set (match_operand:DI 0 "shiftdi_operand" "")
10095 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10096 (match_operand:QI 2 "nonmemory_operand" "")))]
10097 ""
10098 {
10099 if (TARGET_64BIT)
10100 ix86_expand_binary_operator (<CODE>, DImode, operands);
10101 else if (const_1_to_31_operand (operands[2], VOIDmode))
10102 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10103 (operands[0], operands[1], operands[2]));
10104 else
10105 FAIL;
10106
10107 DONE;
10108 })
10109
10110 (define_expand "<rotate_insn><mode>3"
10111 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10112 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10113 (match_operand:QI 2 "nonmemory_operand" "")))]
10114 ""
10115 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10116
10117 ;; Implement rotation using two double-precision
10118 ;; shift instructions and a scratch register.
10119
10120 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10121 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10122 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10123 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10124 (clobber (reg:CC FLAGS_REG))
10125 (clobber (match_scratch:DWIH 3 "=&r"))]
10126 ""
10127 "#"
10128 "reload_completed"
10129 [(set (match_dup 3) (match_dup 4))
10130 (parallel
10131 [(set (match_dup 4)
10132 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10133 (lshiftrt:DWIH (match_dup 5)
10134 (minus:QI (match_dup 6) (match_dup 2)))))
10135 (clobber (reg:CC FLAGS_REG))])
10136 (parallel
10137 [(set (match_dup 5)
10138 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10139 (lshiftrt:DWIH (match_dup 3)
10140 (minus:QI (match_dup 6) (match_dup 2)))))
10141 (clobber (reg:CC FLAGS_REG))])]
10142 {
10143 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10144
10145 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10146 })
10147
10148 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10149 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10150 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10151 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10152 (clobber (reg:CC FLAGS_REG))
10153 (clobber (match_scratch:DWIH 3 "=&r"))]
10154 ""
10155 "#"
10156 "reload_completed"
10157 [(set (match_dup 3) (match_dup 4))
10158 (parallel
10159 [(set (match_dup 4)
10160 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10161 (ashift:DWIH (match_dup 5)
10162 (minus:QI (match_dup 6) (match_dup 2)))))
10163 (clobber (reg:CC FLAGS_REG))])
10164 (parallel
10165 [(set (match_dup 5)
10166 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10167 (ashift:DWIH (match_dup 3)
10168 (minus:QI (match_dup 6) (match_dup 2)))))
10169 (clobber (reg:CC FLAGS_REG))])]
10170 {
10171 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10172
10173 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10174 })
10175
10176 (define_insn "*<rotate_insn><mode>3_1"
10177 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10178 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10179 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10182 {
10183 if (operands[2] == const1_rtx
10184 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10185 return "<rotate>{<imodesuffix>}\t%0";
10186 else
10187 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10188 }
10189 [(set_attr "type" "rotate")
10190 (set (attr "length_immediate")
10191 (if_then_else
10192 (and (match_operand 2 "const1_operand" "")
10193 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10194 (const_int 0)))
10195 (const_string "0")
10196 (const_string "*")))
10197 (set_attr "mode" "<MODE>")])
10198
10199 (define_insn "*<rotate_insn>si3_1_zext"
10200 [(set (match_operand:DI 0 "register_operand" "=r")
10201 (zero_extend:DI
10202 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10203 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10204 (clobber (reg:CC FLAGS_REG))]
10205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10206 {
10207 if (operands[2] == const1_rtx
10208 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10209 return "<rotate>{l}\t%k0";
10210 else
10211 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10212 }
10213 [(set_attr "type" "rotate")
10214 (set (attr "length_immediate")
10215 (if_then_else
10216 (and (match_operand 2 "const1_operand" "")
10217 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10218 (const_int 0)))
10219 (const_string "0")
10220 (const_string "*")))
10221 (set_attr "mode" "SI")])
10222
10223 (define_insn "*<rotate_insn>qi3_1_slp"
10224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10225 (any_rotate:QI (match_dup 0)
10226 (match_operand:QI 1 "nonmemory_operand" "cI")))
10227 (clobber (reg:CC FLAGS_REG))]
10228 "(optimize_function_for_size_p (cfun)
10229 || !TARGET_PARTIAL_REG_STALL
10230 || (operands[1] == const1_rtx
10231 && TARGET_SHIFT1))"
10232 {
10233 if (operands[1] == const1_rtx
10234 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10235 return "<rotate>{b}\t%0";
10236 else
10237 return "<rotate>{b}\t{%1, %0|%0, %1}";
10238 }
10239 [(set_attr "type" "rotate1")
10240 (set (attr "length_immediate")
10241 (if_then_else
10242 (and (match_operand 1 "const1_operand" "")
10243 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10244 (const_int 0)))
10245 (const_string "0")
10246 (const_string "*")))
10247 (set_attr "mode" "QI")])
10248
10249 (define_split
10250 [(set (match_operand:HI 0 "register_operand" "")
10251 (any_rotate:HI (match_dup 0) (const_int 8)))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "reload_completed
10254 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10255 [(parallel [(set (strict_low_part (match_dup 0))
10256 (bswap:HI (match_dup 0)))
10257 (clobber (reg:CC FLAGS_REG))])]
10258 "")
10259 \f
10260 ;; Bit set / bit test instructions
10261
10262 (define_expand "extv"
10263 [(set (match_operand:SI 0 "register_operand" "")
10264 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10265 (match_operand:SI 2 "const8_operand" "")
10266 (match_operand:SI 3 "const8_operand" "")))]
10267 ""
10268 {
10269 /* Handle extractions from %ah et al. */
10270 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10271 FAIL;
10272
10273 /* From mips.md: extract_bit_field doesn't verify that our source
10274 matches the predicate, so check it again here. */
10275 if (! ext_register_operand (operands[1], VOIDmode))
10276 FAIL;
10277 })
10278
10279 (define_expand "extzv"
10280 [(set (match_operand:SI 0 "register_operand" "")
10281 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10282 (match_operand:SI 2 "const8_operand" "")
10283 (match_operand:SI 3 "const8_operand" "")))]
10284 ""
10285 {
10286 /* Handle extractions from %ah et al. */
10287 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10288 FAIL;
10289
10290 /* From mips.md: extract_bit_field doesn't verify that our source
10291 matches the predicate, so check it again here. */
10292 if (! ext_register_operand (operands[1], VOIDmode))
10293 FAIL;
10294 })
10295
10296 (define_expand "insv"
10297 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10298 (match_operand 1 "const8_operand" "")
10299 (match_operand 2 "const8_operand" ""))
10300 (match_operand 3 "register_operand" ""))]
10301 ""
10302 {
10303 /* Handle insertions to %ah et al. */
10304 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10305 FAIL;
10306
10307 /* From mips.md: insert_bit_field doesn't verify that our source
10308 matches the predicate, so check it again here. */
10309 if (! ext_register_operand (operands[0], VOIDmode))
10310 FAIL;
10311
10312 if (TARGET_64BIT)
10313 emit_insn (gen_movdi_insv_1 (operands[0], operands[3]));
10314 else
10315 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10316
10317 DONE;
10318 })
10319
10320 ;; %%% bts, btr, btc, bt.
10321 ;; In general these instructions are *slow* when applied to memory,
10322 ;; since they enforce atomic operation. When applied to registers,
10323 ;; it depends on the cpu implementation. They're never faster than
10324 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10325 ;; no point. But in 64-bit, we can't hold the relevant immediates
10326 ;; within the instruction itself, so operating on bits in the high
10327 ;; 32-bits of a register becomes easier.
10328 ;;
10329 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10330 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10331 ;; negdf respectively, so they can never be disabled entirely.
10332
10333 (define_insn "*btsq"
10334 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10335 (const_int 1)
10336 (match_operand:DI 1 "const_0_to_63_operand" ""))
10337 (const_int 1))
10338 (clobber (reg:CC FLAGS_REG))]
10339 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10340 "bts{q}\t{%1, %0|%0, %1}"
10341 [(set_attr "type" "alu1")
10342 (set_attr "prefix_0f" "1")
10343 (set_attr "mode" "DI")])
10344
10345 (define_insn "*btrq"
10346 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10347 (const_int 1)
10348 (match_operand:DI 1 "const_0_to_63_operand" ""))
10349 (const_int 0))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10352 "btr{q}\t{%1, %0|%0, %1}"
10353 [(set_attr "type" "alu1")
10354 (set_attr "prefix_0f" "1")
10355 (set_attr "mode" "DI")])
10356
10357 (define_insn "*btcq"
10358 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10359 (const_int 1)
10360 (match_operand:DI 1 "const_0_to_63_operand" ""))
10361 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10362 (clobber (reg:CC FLAGS_REG))]
10363 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10364 "btc{q}\t{%1, %0|%0, %1}"
10365 [(set_attr "type" "alu1")
10366 (set_attr "prefix_0f" "1")
10367 (set_attr "mode" "DI")])
10368
10369 ;; Allow Nocona to avoid these instructions if a register is available.
10370
10371 (define_peephole2
10372 [(match_scratch:DI 2 "r")
10373 (parallel [(set (zero_extract:DI
10374 (match_operand:DI 0 "register_operand" "")
10375 (const_int 1)
10376 (match_operand:DI 1 "const_0_to_63_operand" ""))
10377 (const_int 1))
10378 (clobber (reg:CC FLAGS_REG))])]
10379 "TARGET_64BIT && !TARGET_USE_BT"
10380 [(const_int 0)]
10381 {
10382 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10383 rtx op1;
10384
10385 if (HOST_BITS_PER_WIDE_INT >= 64)
10386 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10387 else if (i < HOST_BITS_PER_WIDE_INT)
10388 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10389 else
10390 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10391
10392 op1 = immed_double_const (lo, hi, DImode);
10393 if (i >= 31)
10394 {
10395 emit_move_insn (operands[2], op1);
10396 op1 = operands[2];
10397 }
10398
10399 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10400 DONE;
10401 })
10402
10403 (define_peephole2
10404 [(match_scratch:DI 2 "r")
10405 (parallel [(set (zero_extract:DI
10406 (match_operand:DI 0 "register_operand" "")
10407 (const_int 1)
10408 (match_operand:DI 1 "const_0_to_63_operand" ""))
10409 (const_int 0))
10410 (clobber (reg:CC FLAGS_REG))])]
10411 "TARGET_64BIT && !TARGET_USE_BT"
10412 [(const_int 0)]
10413 {
10414 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10415 rtx op1;
10416
10417 if (HOST_BITS_PER_WIDE_INT >= 64)
10418 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10419 else if (i < HOST_BITS_PER_WIDE_INT)
10420 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10421 else
10422 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10423
10424 op1 = immed_double_const (~lo, ~hi, DImode);
10425 if (i >= 32)
10426 {
10427 emit_move_insn (operands[2], op1);
10428 op1 = operands[2];
10429 }
10430
10431 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10432 DONE;
10433 })
10434
10435 (define_peephole2
10436 [(match_scratch:DI 2 "r")
10437 (parallel [(set (zero_extract:DI
10438 (match_operand:DI 0 "register_operand" "")
10439 (const_int 1)
10440 (match_operand:DI 1 "const_0_to_63_operand" ""))
10441 (not:DI (zero_extract:DI
10442 (match_dup 0) (const_int 1) (match_dup 1))))
10443 (clobber (reg:CC FLAGS_REG))])]
10444 "TARGET_64BIT && !TARGET_USE_BT"
10445 [(const_int 0)]
10446 {
10447 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10448 rtx op1;
10449
10450 if (HOST_BITS_PER_WIDE_INT >= 64)
10451 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10452 else if (i < HOST_BITS_PER_WIDE_INT)
10453 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10454 else
10455 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10456
10457 op1 = immed_double_const (lo, hi, DImode);
10458 if (i >= 31)
10459 {
10460 emit_move_insn (operands[2], op1);
10461 op1 = operands[2];
10462 }
10463
10464 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10465 DONE;
10466 })
10467
10468 (define_insn "*bt<mode>"
10469 [(set (reg:CCC FLAGS_REG)
10470 (compare:CCC
10471 (zero_extract:SWI48
10472 (match_operand:SWI48 0 "register_operand" "r")
10473 (const_int 1)
10474 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10475 (const_int 0)))]
10476 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10477 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10478 [(set_attr "type" "alu1")
10479 (set_attr "prefix_0f" "1")
10480 (set_attr "mode" "<MODE>")])
10481 \f
10482 ;; Store-flag instructions.
10483
10484 ;; For all sCOND expanders, also expand the compare or test insn that
10485 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10486
10487 (define_insn_and_split "*setcc_di_1"
10488 [(set (match_operand:DI 0 "register_operand" "=q")
10489 (match_operator:DI 1 "ix86_comparison_operator"
10490 [(reg FLAGS_REG) (const_int 0)]))]
10491 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10492 "#"
10493 "&& reload_completed"
10494 [(set (match_dup 2) (match_dup 1))
10495 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10496 {
10497 PUT_MODE (operands[1], QImode);
10498 operands[2] = gen_lowpart (QImode, operands[0]);
10499 })
10500
10501 (define_insn_and_split "*setcc_si_1_and"
10502 [(set (match_operand:SI 0 "register_operand" "=q")
10503 (match_operator:SI 1 "ix86_comparison_operator"
10504 [(reg FLAGS_REG) (const_int 0)]))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "!TARGET_PARTIAL_REG_STALL
10507 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10508 "#"
10509 "&& reload_completed"
10510 [(set (match_dup 2) (match_dup 1))
10511 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10512 (clobber (reg:CC FLAGS_REG))])]
10513 {
10514 PUT_MODE (operands[1], QImode);
10515 operands[2] = gen_lowpart (QImode, operands[0]);
10516 })
10517
10518 (define_insn_and_split "*setcc_si_1_movzbl"
10519 [(set (match_operand:SI 0 "register_operand" "=q")
10520 (match_operator:SI 1 "ix86_comparison_operator"
10521 [(reg FLAGS_REG) (const_int 0)]))]
10522 "!TARGET_PARTIAL_REG_STALL
10523 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10524 "#"
10525 "&& reload_completed"
10526 [(set (match_dup 2) (match_dup 1))
10527 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10528 {
10529 PUT_MODE (operands[1], QImode);
10530 operands[2] = gen_lowpart (QImode, operands[0]);
10531 })
10532
10533 (define_insn "*setcc_qi"
10534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10535 (match_operator:QI 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)]))]
10537 ""
10538 "set%C1\t%0"
10539 [(set_attr "type" "setcc")
10540 (set_attr "mode" "QI")])
10541
10542 (define_insn "*setcc_qi_slp"
10543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10544 (match_operator:QI 1 "ix86_comparison_operator"
10545 [(reg FLAGS_REG) (const_int 0)]))]
10546 ""
10547 "set%C1\t%0"
10548 [(set_attr "type" "setcc")
10549 (set_attr "mode" "QI")])
10550
10551 ;; In general it is not safe to assume too much about CCmode registers,
10552 ;; so simplify-rtx stops when it sees a second one. Under certain
10553 ;; conditions this is safe on x86, so help combine not create
10554 ;;
10555 ;; seta %al
10556 ;; testb %al, %al
10557 ;; sete %al
10558
10559 (define_split
10560 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10561 (ne:QI (match_operator 1 "ix86_comparison_operator"
10562 [(reg FLAGS_REG) (const_int 0)])
10563 (const_int 0)))]
10564 ""
10565 [(set (match_dup 0) (match_dup 1))]
10566 {
10567 PUT_MODE (operands[1], QImode);
10568 })
10569
10570 (define_split
10571 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10572 (ne:QI (match_operator 1 "ix86_comparison_operator"
10573 [(reg FLAGS_REG) (const_int 0)])
10574 (const_int 0)))]
10575 ""
10576 [(set (match_dup 0) (match_dup 1))]
10577 {
10578 PUT_MODE (operands[1], QImode);
10579 })
10580
10581 (define_split
10582 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10583 (eq:QI (match_operator 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)])
10585 (const_int 0)))]
10586 ""
10587 [(set (match_dup 0) (match_dup 1))]
10588 {
10589 rtx new_op1 = copy_rtx (operands[1]);
10590 operands[1] = new_op1;
10591 PUT_MODE (new_op1, QImode);
10592 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10593 GET_MODE (XEXP (new_op1, 0))));
10594
10595 /* Make sure that (a) the CCmode we have for the flags is strong
10596 enough for the reversed compare or (b) we have a valid FP compare. */
10597 if (! ix86_comparison_operator (new_op1, VOIDmode))
10598 FAIL;
10599 })
10600
10601 (define_split
10602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10603 (eq:QI (match_operator 1 "ix86_comparison_operator"
10604 [(reg FLAGS_REG) (const_int 0)])
10605 (const_int 0)))]
10606 ""
10607 [(set (match_dup 0) (match_dup 1))]
10608 {
10609 rtx new_op1 = copy_rtx (operands[1]);
10610 operands[1] = new_op1;
10611 PUT_MODE (new_op1, QImode);
10612 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10613 GET_MODE (XEXP (new_op1, 0))));
10614
10615 /* Make sure that (a) the CCmode we have for the flags is strong
10616 enough for the reversed compare or (b) we have a valid FP compare. */
10617 if (! ix86_comparison_operator (new_op1, VOIDmode))
10618 FAIL;
10619 })
10620
10621 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10622 ;; subsequent logical operations are used to imitate conditional moves.
10623 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10624 ;; it directly.
10625
10626 (define_insn "*avx_setcc<mode>"
10627 [(set (match_operand:MODEF 0 "register_operand" "=x")
10628 (match_operator:MODEF 1 "avx_comparison_float_operator"
10629 [(match_operand:MODEF 2 "register_operand" "x")
10630 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10631 "TARGET_AVX"
10632 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10633 [(set_attr "type" "ssecmp")
10634 (set_attr "prefix" "vex")
10635 (set_attr "length_immediate" "1")
10636 (set_attr "mode" "<MODE>")])
10637
10638 (define_insn "*sse_setcc<mode>"
10639 [(set (match_operand:MODEF 0 "register_operand" "=x")
10640 (match_operator:MODEF 1 "sse_comparison_operator"
10641 [(match_operand:MODEF 2 "register_operand" "0")
10642 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10643 "SSE_FLOAT_MODE_P (<MODE>mode)"
10644 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10645 [(set_attr "type" "ssecmp")
10646 (set_attr "length_immediate" "1")
10647 (set_attr "mode" "<MODE>")])
10648 \f
10649 ;; Basic conditional jump instructions.
10650 ;; We ignore the overflow flag for signed branch instructions.
10651
10652 (define_insn "*jcc_1"
10653 [(set (pc)
10654 (if_then_else (match_operator 1 "ix86_comparison_operator"
10655 [(reg FLAGS_REG) (const_int 0)])
10656 (label_ref (match_operand 0 "" ""))
10657 (pc)))]
10658 ""
10659 "%+j%C1\t%l0"
10660 [(set_attr "type" "ibr")
10661 (set_attr "modrm" "0")
10662 (set (attr "length")
10663 (if_then_else (and (ge (minus (match_dup 0) (pc))
10664 (const_int -126))
10665 (lt (minus (match_dup 0) (pc))
10666 (const_int 128)))
10667 (const_int 2)
10668 (const_int 6)))])
10669
10670 (define_insn "*jcc_2"
10671 [(set (pc)
10672 (if_then_else (match_operator 1 "ix86_comparison_operator"
10673 [(reg FLAGS_REG) (const_int 0)])
10674 (pc)
10675 (label_ref (match_operand 0 "" ""))))]
10676 ""
10677 "%+j%c1\t%l0"
10678 [(set_attr "type" "ibr")
10679 (set_attr "modrm" "0")
10680 (set (attr "length")
10681 (if_then_else (and (ge (minus (match_dup 0) (pc))
10682 (const_int -126))
10683 (lt (minus (match_dup 0) (pc))
10684 (const_int 128)))
10685 (const_int 2)
10686 (const_int 6)))])
10687
10688 ;; In general it is not safe to assume too much about CCmode registers,
10689 ;; so simplify-rtx stops when it sees a second one. Under certain
10690 ;; conditions this is safe on x86, so help combine not create
10691 ;;
10692 ;; seta %al
10693 ;; testb %al, %al
10694 ;; je Lfoo
10695
10696 (define_split
10697 [(set (pc)
10698 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10699 [(reg FLAGS_REG) (const_int 0)])
10700 (const_int 0))
10701 (label_ref (match_operand 1 "" ""))
10702 (pc)))]
10703 ""
10704 [(set (pc)
10705 (if_then_else (match_dup 0)
10706 (label_ref (match_dup 1))
10707 (pc)))]
10708 {
10709 PUT_MODE (operands[0], VOIDmode);
10710 })
10711
10712 (define_split
10713 [(set (pc)
10714 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10715 [(reg FLAGS_REG) (const_int 0)])
10716 (const_int 0))
10717 (label_ref (match_operand 1 "" ""))
10718 (pc)))]
10719 ""
10720 [(set (pc)
10721 (if_then_else (match_dup 0)
10722 (label_ref (match_dup 1))
10723 (pc)))]
10724 {
10725 rtx new_op0 = copy_rtx (operands[0]);
10726 operands[0] = new_op0;
10727 PUT_MODE (new_op0, VOIDmode);
10728 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10729 GET_MODE (XEXP (new_op0, 0))));
10730
10731 /* Make sure that (a) the CCmode we have for the flags is strong
10732 enough for the reversed compare or (b) we have a valid FP compare. */
10733 if (! ix86_comparison_operator (new_op0, VOIDmode))
10734 FAIL;
10735 })
10736
10737 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10738 ;; pass generates from shift insn with QImode operand. Actually, the mode
10739 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10740 ;; appropriate modulo of the bit offset value.
10741
10742 (define_insn_and_split "*jcc_bt<mode>"
10743 [(set (pc)
10744 (if_then_else (match_operator 0 "bt_comparison_operator"
10745 [(zero_extract:SWI48
10746 (match_operand:SWI48 1 "register_operand" "r")
10747 (const_int 1)
10748 (zero_extend:SI
10749 (match_operand:QI 2 "register_operand" "r")))
10750 (const_int 0)])
10751 (label_ref (match_operand 3 "" ""))
10752 (pc)))
10753 (clobber (reg:CC FLAGS_REG))]
10754 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10755 "#"
10756 "&& 1"
10757 [(set (reg:CCC FLAGS_REG)
10758 (compare:CCC
10759 (zero_extract:SWI48
10760 (match_dup 1)
10761 (const_int 1)
10762 (match_dup 2))
10763 (const_int 0)))
10764 (set (pc)
10765 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10766 (label_ref (match_dup 3))
10767 (pc)))]
10768 {
10769 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10770
10771 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10772 })
10773
10774 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10775 ;; also for DImode, this is what combine produces.
10776 (define_insn_and_split "*jcc_bt<mode>_mask"
10777 [(set (pc)
10778 (if_then_else (match_operator 0 "bt_comparison_operator"
10779 [(zero_extract:SWI48
10780 (match_operand:SWI48 1 "register_operand" "r")
10781 (const_int 1)
10782 (and:SI
10783 (match_operand:SI 2 "register_operand" "r")
10784 (match_operand:SI 3 "const_int_operand" "n")))])
10785 (label_ref (match_operand 4 "" ""))
10786 (pc)))
10787 (clobber (reg:CC FLAGS_REG))]
10788 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10789 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10790 == GET_MODE_BITSIZE (<MODE>mode)-1"
10791 "#"
10792 "&& 1"
10793 [(set (reg:CCC FLAGS_REG)
10794 (compare:CCC
10795 (zero_extract:SWI48
10796 (match_dup 1)
10797 (const_int 1)
10798 (match_dup 2))
10799 (const_int 0)))
10800 (set (pc)
10801 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10802 (label_ref (match_dup 4))
10803 (pc)))]
10804 {
10805 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10806
10807 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10808 })
10809
10810 (define_insn_and_split "*jcc_btsi_1"
10811 [(set (pc)
10812 (if_then_else (match_operator 0 "bt_comparison_operator"
10813 [(and:SI
10814 (lshiftrt:SI
10815 (match_operand:SI 1 "register_operand" "r")
10816 (match_operand:QI 2 "register_operand" "r"))
10817 (const_int 1))
10818 (const_int 0)])
10819 (label_ref (match_operand 3 "" ""))
10820 (pc)))
10821 (clobber (reg:CC FLAGS_REG))]
10822 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10823 "#"
10824 "&& 1"
10825 [(set (reg:CCC FLAGS_REG)
10826 (compare:CCC
10827 (zero_extract:SI
10828 (match_dup 1)
10829 (const_int 1)
10830 (match_dup 2))
10831 (const_int 0)))
10832 (set (pc)
10833 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10834 (label_ref (match_dup 3))
10835 (pc)))]
10836 {
10837 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10838
10839 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10840 })
10841
10842 ;; avoid useless masking of bit offset operand
10843 (define_insn_and_split "*jcc_btsi_mask_1"
10844 [(set (pc)
10845 (if_then_else
10846 (match_operator 0 "bt_comparison_operator"
10847 [(and:SI
10848 (lshiftrt:SI
10849 (match_operand:SI 1 "register_operand" "r")
10850 (subreg:QI
10851 (and:SI
10852 (match_operand:SI 2 "register_operand" "r")
10853 (match_operand:SI 3 "const_int_operand" "n")) 0))
10854 (const_int 1))
10855 (const_int 0)])
10856 (label_ref (match_operand 4 "" ""))
10857 (pc)))
10858 (clobber (reg:CC FLAGS_REG))]
10859 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10860 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10861 "#"
10862 "&& 1"
10863 [(set (reg:CCC FLAGS_REG)
10864 (compare:CCC
10865 (zero_extract:SI
10866 (match_dup 1)
10867 (const_int 1)
10868 (match_dup 2))
10869 (const_int 0)))
10870 (set (pc)
10871 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10872 (label_ref (match_dup 4))
10873 (pc)))]
10874 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10875
10876 ;; Define combination compare-and-branch fp compare instructions to help
10877 ;; combine.
10878
10879 (define_insn "*fp_jcc_1_387"
10880 [(set (pc)
10881 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10882 [(match_operand 1 "register_operand" "f")
10883 (match_operand 2 "nonimmediate_operand" "fm")])
10884 (label_ref (match_operand 3 "" ""))
10885 (pc)))
10886 (clobber (reg:CCFP FPSR_REG))
10887 (clobber (reg:CCFP FLAGS_REG))
10888 (clobber (match_scratch:HI 4 "=a"))]
10889 "TARGET_80387
10890 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10891 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10892 && SELECT_CC_MODE (GET_CODE (operands[0]),
10893 operands[1], operands[2]) == CCFPmode
10894 && !TARGET_CMOVE"
10895 "#")
10896
10897 (define_insn "*fp_jcc_1r_387"
10898 [(set (pc)
10899 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10900 [(match_operand 1 "register_operand" "f")
10901 (match_operand 2 "nonimmediate_operand" "fm")])
10902 (pc)
10903 (label_ref (match_operand 3 "" ""))))
10904 (clobber (reg:CCFP FPSR_REG))
10905 (clobber (reg:CCFP FLAGS_REG))
10906 (clobber (match_scratch:HI 4 "=a"))]
10907 "TARGET_80387
10908 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10909 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10910 && SELECT_CC_MODE (GET_CODE (operands[0]),
10911 operands[1], operands[2]) == CCFPmode
10912 && !TARGET_CMOVE"
10913 "#")
10914
10915 (define_insn "*fp_jcc_2_387"
10916 [(set (pc)
10917 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10918 [(match_operand 1 "register_operand" "f")
10919 (match_operand 2 "register_operand" "f")])
10920 (label_ref (match_operand 3 "" ""))
10921 (pc)))
10922 (clobber (reg:CCFP FPSR_REG))
10923 (clobber (reg:CCFP FLAGS_REG))
10924 (clobber (match_scratch:HI 4 "=a"))]
10925 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10926 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10927 && !TARGET_CMOVE"
10928 "#")
10929
10930 (define_insn "*fp_jcc_2r_387"
10931 [(set (pc)
10932 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10933 [(match_operand 1 "register_operand" "f")
10934 (match_operand 2 "register_operand" "f")])
10935 (pc)
10936 (label_ref (match_operand 3 "" ""))))
10937 (clobber (reg:CCFP FPSR_REG))
10938 (clobber (reg:CCFP FLAGS_REG))
10939 (clobber (match_scratch:HI 4 "=a"))]
10940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10941 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10942 && !TARGET_CMOVE"
10943 "#")
10944
10945 (define_insn "*fp_jcc_3_387"
10946 [(set (pc)
10947 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10948 [(match_operand 1 "register_operand" "f")
10949 (match_operand 2 "const0_operand" "")])
10950 (label_ref (match_operand 3 "" ""))
10951 (pc)))
10952 (clobber (reg:CCFP FPSR_REG))
10953 (clobber (reg:CCFP FLAGS_REG))
10954 (clobber (match_scratch:HI 4 "=a"))]
10955 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10956 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10957 && SELECT_CC_MODE (GET_CODE (operands[0]),
10958 operands[1], operands[2]) == CCFPmode
10959 && !TARGET_CMOVE"
10960 "#")
10961
10962 (define_split
10963 [(set (pc)
10964 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10965 [(match_operand 1 "register_operand" "")
10966 (match_operand 2 "nonimmediate_operand" "")])
10967 (match_operand 3 "" "")
10968 (match_operand 4 "" "")))
10969 (clobber (reg:CCFP FPSR_REG))
10970 (clobber (reg:CCFP FLAGS_REG))]
10971 "reload_completed"
10972 [(const_int 0)]
10973 {
10974 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10975 operands[3], operands[4], NULL_RTX, NULL_RTX);
10976 DONE;
10977 })
10978
10979 (define_split
10980 [(set (pc)
10981 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10982 [(match_operand 1 "register_operand" "")
10983 (match_operand 2 "general_operand" "")])
10984 (match_operand 3 "" "")
10985 (match_operand 4 "" "")))
10986 (clobber (reg:CCFP FPSR_REG))
10987 (clobber (reg:CCFP FLAGS_REG))
10988 (clobber (match_scratch:HI 5 "=a"))]
10989 "reload_completed"
10990 [(const_int 0)]
10991 {
10992 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10993 operands[3], operands[4], operands[5], NULL_RTX);
10994 DONE;
10995 })
10996
10997 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10998 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10999 ;; with a precedence over other operators and is always put in the first
11000 ;; place. Swap condition and operands to match ficom instruction.
11001
11002 (define_insn "*fp_jcc_4_<mode>_387"
11003 [(set (pc)
11004 (if_then_else
11005 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11006 [(match_operator 1 "float_operator"
11007 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11008 (match_operand 3 "register_operand" "f,f")])
11009 (label_ref (match_operand 4 "" ""))
11010 (pc)))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))
11013 (clobber (match_scratch:HI 5 "=a,a"))]
11014 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11015 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11016 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11017 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11018 && !TARGET_CMOVE"
11019 "#")
11020
11021 (define_split
11022 [(set (pc)
11023 (if_then_else
11024 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11025 [(match_operator 1 "float_operator"
11026 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11027 (match_operand 3 "register_operand" "")])
11028 (match_operand 4 "" "")
11029 (match_operand 5 "" "")))
11030 (clobber (reg:CCFP FPSR_REG))
11031 (clobber (reg:CCFP FLAGS_REG))
11032 (clobber (match_scratch:HI 6 "=a"))]
11033 "reload_completed"
11034 [(const_int 0)]
11035 {
11036 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11037
11038 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11039 operands[3], operands[7],
11040 operands[4], operands[5], operands[6], NULL_RTX);
11041 DONE;
11042 })
11043
11044 ;; %%% Kill this when reload knows how to do it.
11045 (define_split
11046 [(set (pc)
11047 (if_then_else
11048 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11049 [(match_operator 1 "float_operator"
11050 [(match_operand:X87MODEI12 2 "register_operand" "")])
11051 (match_operand 3 "register_operand" "")])
11052 (match_operand 4 "" "")
11053 (match_operand 5 "" "")))
11054 (clobber (reg:CCFP FPSR_REG))
11055 (clobber (reg:CCFP FLAGS_REG))
11056 (clobber (match_scratch:HI 6 "=a"))]
11057 "reload_completed"
11058 [(const_int 0)]
11059 {
11060 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11061 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11062
11063 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11064 operands[3], operands[7],
11065 operands[4], operands[5], operands[6], operands[2]);
11066 DONE;
11067 })
11068 \f
11069 ;; Unconditional and other jump instructions
11070
11071 (define_insn "jump"
11072 [(set (pc)
11073 (label_ref (match_operand 0 "" "")))]
11074 ""
11075 "jmp\t%l0"
11076 [(set_attr "type" "ibr")
11077 (set (attr "length")
11078 (if_then_else (and (ge (minus (match_dup 0) (pc))
11079 (const_int -126))
11080 (lt (minus (match_dup 0) (pc))
11081 (const_int 128)))
11082 (const_int 2)
11083 (const_int 5)))
11084 (set_attr "modrm" "0")])
11085
11086 (define_expand "indirect_jump"
11087 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11088 ""
11089 "")
11090
11091 (define_insn "*indirect_jump"
11092 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11093 ""
11094 "jmp\t%A0"
11095 [(set_attr "type" "ibr")
11096 (set_attr "length_immediate" "0")])
11097
11098 (define_expand "tablejump"
11099 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11100 (use (label_ref (match_operand 1 "" "")))])]
11101 ""
11102 {
11103 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11104 relative. Convert the relative address to an absolute address. */
11105 if (flag_pic)
11106 {
11107 rtx op0, op1;
11108 enum rtx_code code;
11109
11110 /* We can't use @GOTOFF for text labels on VxWorks;
11111 see gotoff_operand. */
11112 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11113 {
11114 code = PLUS;
11115 op0 = operands[0];
11116 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11117 }
11118 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11119 {
11120 code = PLUS;
11121 op0 = operands[0];
11122 op1 = pic_offset_table_rtx;
11123 }
11124 else
11125 {
11126 code = MINUS;
11127 op0 = pic_offset_table_rtx;
11128 op1 = operands[0];
11129 }
11130
11131 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11132 OPTAB_DIRECT);
11133 }
11134 })
11135
11136 (define_insn "*tablejump_1"
11137 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11138 (use (label_ref (match_operand 1 "" "")))]
11139 ""
11140 "jmp\t%A0"
11141 [(set_attr "type" "ibr")
11142 (set_attr "length_immediate" "0")])
11143 \f
11144 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11145
11146 (define_peephole2
11147 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11148 (set (match_operand:QI 1 "register_operand" "")
11149 (match_operator:QI 2 "ix86_comparison_operator"
11150 [(reg FLAGS_REG) (const_int 0)]))
11151 (set (match_operand 3 "q_regs_operand" "")
11152 (zero_extend (match_dup 1)))]
11153 "(peep2_reg_dead_p (3, operands[1])
11154 || operands_match_p (operands[1], operands[3]))
11155 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11156 [(set (match_dup 4) (match_dup 0))
11157 (set (strict_low_part (match_dup 5))
11158 (match_dup 2))]
11159 {
11160 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11161 operands[5] = gen_lowpart (QImode, operands[3]);
11162 ix86_expand_clear (operands[3]);
11163 })
11164
11165 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11166
11167 (define_peephole2
11168 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11169 (set (match_operand:QI 1 "register_operand" "")
11170 (match_operator:QI 2 "ix86_comparison_operator"
11171 [(reg FLAGS_REG) (const_int 0)]))
11172 (parallel [(set (match_operand 3 "q_regs_operand" "")
11173 (zero_extend (match_dup 1)))
11174 (clobber (reg:CC FLAGS_REG))])]
11175 "(peep2_reg_dead_p (3, operands[1])
11176 || operands_match_p (operands[1], operands[3]))
11177 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11178 [(set (match_dup 4) (match_dup 0))
11179 (set (strict_low_part (match_dup 5))
11180 (match_dup 2))]
11181 {
11182 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11183 operands[5] = gen_lowpart (QImode, operands[3]);
11184 ix86_expand_clear (operands[3]);
11185 })
11186 \f
11187 ;; Call instructions.
11188
11189 ;; The predicates normally associated with named expanders are not properly
11190 ;; checked for calls. This is a bug in the generic code, but it isn't that
11191 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11192
11193 ;; P6 processors will jump to the address after the decrement when %esp
11194 ;; is used as a call operand, so they will execute return address as a code.
11195 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11196
11197 ;; Call subroutine returning no value.
11198
11199 (define_expand "call_pop"
11200 [(parallel [(call (match_operand:QI 0 "" "")
11201 (match_operand:SI 1 "" ""))
11202 (set (reg:SI SP_REG)
11203 (plus:SI (reg:SI SP_REG)
11204 (match_operand:SI 3 "" "")))])]
11205 "!TARGET_64BIT"
11206 {
11207 ix86_expand_call (NULL, operands[0], operands[1],
11208 operands[2], operands[3], 0);
11209 DONE;
11210 })
11211
11212 (define_insn "*call_pop_0"
11213 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11214 (match_operand:SI 1 "" ""))
11215 (set (reg:SI SP_REG)
11216 (plus:SI (reg:SI SP_REG)
11217 (match_operand:SI 2 "immediate_operand" "")))]
11218 "!TARGET_64BIT"
11219 {
11220 if (SIBLING_CALL_P (insn))
11221 return "jmp\t%P0";
11222 else
11223 return "call\t%P0";
11224 }
11225 [(set_attr "type" "call")])
11226
11227 (define_insn "*call_pop_1"
11228 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11229 (match_operand:SI 1 "" ""))
11230 (set (reg:SI SP_REG)
11231 (plus:SI (reg:SI SP_REG)
11232 (match_operand:SI 2 "immediate_operand" "i")))]
11233 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11234 {
11235 if (constant_call_address_operand (operands[0], Pmode))
11236 return "call\t%P0";
11237 return "call\t%A0";
11238 }
11239 [(set_attr "type" "call")])
11240
11241 (define_insn "*sibcall_pop_1"
11242 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11243 (match_operand:SI 1 "" ""))
11244 (set (reg:SI SP_REG)
11245 (plus:SI (reg:SI SP_REG)
11246 (match_operand:SI 2 "immediate_operand" "i,i")))]
11247 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11248 "@
11249 jmp\t%P0
11250 jmp\t%A0"
11251 [(set_attr "type" "call")])
11252
11253 (define_expand "call"
11254 [(call (match_operand:QI 0 "" "")
11255 (match_operand 1 "" ""))
11256 (use (match_operand 2 "" ""))]
11257 ""
11258 {
11259 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11260 DONE;
11261 })
11262
11263 (define_expand "sibcall"
11264 [(call (match_operand:QI 0 "" "")
11265 (match_operand 1 "" ""))
11266 (use (match_operand 2 "" ""))]
11267 ""
11268 {
11269 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11270 DONE;
11271 })
11272
11273 (define_insn "*call_0"
11274 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11275 (match_operand 1 "" ""))]
11276 ""
11277 {
11278 if (SIBLING_CALL_P (insn))
11279 return "jmp\t%P0";
11280 else
11281 return "call\t%P0";
11282 }
11283 [(set_attr "type" "call")])
11284
11285 (define_insn "*call_1"
11286 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11287 (match_operand 1 "" ""))]
11288 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11289 {
11290 if (constant_call_address_operand (operands[0], Pmode))
11291 return "call\t%P0";
11292 return "call\t%A0";
11293 }
11294 [(set_attr "type" "call")])
11295
11296 (define_insn "*sibcall_1"
11297 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11298 (match_operand 1 "" ""))]
11299 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11300 "@
11301 jmp\t%P0
11302 jmp\t%A0"
11303 [(set_attr "type" "call")])
11304
11305 (define_insn "*call_1_rex64"
11306 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11307 (match_operand 1 "" ""))]
11308 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11309 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11310 {
11311 if (constant_call_address_operand (operands[0], Pmode))
11312 return "call\t%P0";
11313 return "call\t%A0";
11314 }
11315 [(set_attr "type" "call")])
11316
11317 (define_insn "*call_1_rex64_ms_sysv"
11318 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11319 (match_operand 1 "" ""))
11320 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11321 (clobber (reg:TI XMM6_REG))
11322 (clobber (reg:TI XMM7_REG))
11323 (clobber (reg:TI XMM8_REG))
11324 (clobber (reg:TI XMM9_REG))
11325 (clobber (reg:TI XMM10_REG))
11326 (clobber (reg:TI XMM11_REG))
11327 (clobber (reg:TI XMM12_REG))
11328 (clobber (reg:TI XMM13_REG))
11329 (clobber (reg:TI XMM14_REG))
11330 (clobber (reg:TI XMM15_REG))
11331 (clobber (reg:DI SI_REG))
11332 (clobber (reg:DI DI_REG))]
11333 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11334 {
11335 if (constant_call_address_operand (operands[0], Pmode))
11336 return "call\t%P0";
11337 return "call\t%A0";
11338 }
11339 [(set_attr "type" "call")])
11340
11341 (define_insn "*call_1_rex64_large"
11342 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11343 (match_operand 1 "" ""))]
11344 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11345 "call\t%A0"
11346 [(set_attr "type" "call")])
11347
11348 (define_insn "*sibcall_1_rex64"
11349 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11350 (match_operand 1 "" ""))]
11351 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11352 "@
11353 jmp\t%P0
11354 jmp\t%A0"
11355 [(set_attr "type" "call")])
11356
11357 ;; Call subroutine, returning value in operand 0
11358 (define_expand "call_value_pop"
11359 [(parallel [(set (match_operand 0 "" "")
11360 (call (match_operand:QI 1 "" "")
11361 (match_operand:SI 2 "" "")))
11362 (set (reg:SI SP_REG)
11363 (plus:SI (reg:SI SP_REG)
11364 (match_operand:SI 4 "" "")))])]
11365 "!TARGET_64BIT"
11366 {
11367 ix86_expand_call (operands[0], operands[1], operands[2],
11368 operands[3], operands[4], 0);
11369 DONE;
11370 })
11371
11372 (define_expand "call_value"
11373 [(set (match_operand 0 "" "")
11374 (call (match_operand:QI 1 "" "")
11375 (match_operand:SI 2 "" "")))
11376 (use (match_operand:SI 3 "" ""))]
11377 ;; Operand 3 is not used on the i386.
11378 ""
11379 {
11380 ix86_expand_call (operands[0], operands[1], operands[2],
11381 operands[3], NULL, 0);
11382 DONE;
11383 })
11384
11385 (define_expand "sibcall_value"
11386 [(set (match_operand 0 "" "")
11387 (call (match_operand:QI 1 "" "")
11388 (match_operand:SI 2 "" "")))
11389 (use (match_operand:SI 3 "" ""))]
11390 ;; Operand 3 is not used on the i386.
11391 ""
11392 {
11393 ix86_expand_call (operands[0], operands[1], operands[2],
11394 operands[3], NULL, 1);
11395 DONE;
11396 })
11397
11398 ;; Call subroutine returning any type.
11399
11400 (define_expand "untyped_call"
11401 [(parallel [(call (match_operand 0 "" "")
11402 (const_int 0))
11403 (match_operand 1 "" "")
11404 (match_operand 2 "" "")])]
11405 ""
11406 {
11407 int i;
11408
11409 /* In order to give reg-stack an easier job in validating two
11410 coprocessor registers as containing a possible return value,
11411 simply pretend the untyped call returns a complex long double
11412 value.
11413
11414 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11415 and should have the default ABI. */
11416
11417 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11418 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11419 operands[0], const0_rtx,
11420 GEN_INT ((TARGET_64BIT
11421 ? (ix86_abi == SYSV_ABI
11422 ? X86_64_SSE_REGPARM_MAX
11423 : X86_64_MS_SSE_REGPARM_MAX)
11424 : X86_32_SSE_REGPARM_MAX)
11425 - 1),
11426 NULL, 0);
11427
11428 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11429 {
11430 rtx set = XVECEXP (operands[2], 0, i);
11431 emit_move_insn (SET_DEST (set), SET_SRC (set));
11432 }
11433
11434 /* The optimizer does not know that the call sets the function value
11435 registers we stored in the result block. We avoid problems by
11436 claiming that all hard registers are used and clobbered at this
11437 point. */
11438 emit_insn (gen_blockage ());
11439
11440 DONE;
11441 })
11442 \f
11443 ;; Prologue and epilogue instructions
11444
11445 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11446 ;; all of memory. This blocks insns from being moved across this point.
11447
11448 (define_insn "blockage"
11449 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11450 ""
11451 ""
11452 [(set_attr "length" "0")])
11453
11454 ;; Do not schedule instructions accessing memory across this point.
11455
11456 (define_expand "memory_blockage"
11457 [(set (match_dup 0)
11458 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11459 ""
11460 {
11461 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11462 MEM_VOLATILE_P (operands[0]) = 1;
11463 })
11464
11465 (define_insn "*memory_blockage"
11466 [(set (match_operand:BLK 0 "" "")
11467 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11468 ""
11469 ""
11470 [(set_attr "length" "0")])
11471
11472 ;; As USE insns aren't meaningful after reload, this is used instead
11473 ;; to prevent deleting instructions setting registers for PIC code
11474 (define_insn "prologue_use"
11475 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11476 ""
11477 ""
11478 [(set_attr "length" "0")])
11479
11480 ;; Insn emitted into the body of a function to return from a function.
11481 ;; This is only done if the function's epilogue is known to be simple.
11482 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11483
11484 (define_expand "return"
11485 [(return)]
11486 "ix86_can_use_return_insn_p ()"
11487 {
11488 if (crtl->args.pops_args)
11489 {
11490 rtx popc = GEN_INT (crtl->args.pops_args);
11491 emit_jump_insn (gen_return_pop_internal (popc));
11492 DONE;
11493 }
11494 })
11495
11496 (define_insn "return_internal"
11497 [(return)]
11498 "reload_completed"
11499 "ret"
11500 [(set_attr "length" "1")
11501 (set_attr "atom_unit" "jeu")
11502 (set_attr "length_immediate" "0")
11503 (set_attr "modrm" "0")])
11504
11505 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11506 ;; instruction Athlon and K8 have.
11507
11508 (define_insn "return_internal_long"
11509 [(return)
11510 (unspec [(const_int 0)] UNSPEC_REP)]
11511 "reload_completed"
11512 "rep\;ret"
11513 [(set_attr "length" "2")
11514 (set_attr "atom_unit" "jeu")
11515 (set_attr "length_immediate" "0")
11516 (set_attr "prefix_rep" "1")
11517 (set_attr "modrm" "0")])
11518
11519 (define_insn "return_pop_internal"
11520 [(return)
11521 (use (match_operand:SI 0 "const_int_operand" ""))]
11522 "reload_completed"
11523 "ret\t%0"
11524 [(set_attr "length" "3")
11525 (set_attr "atom_unit" "jeu")
11526 (set_attr "length_immediate" "2")
11527 (set_attr "modrm" "0")])
11528
11529 (define_insn "return_indirect_internal"
11530 [(return)
11531 (use (match_operand:SI 0 "register_operand" "r"))]
11532 "reload_completed"
11533 "jmp\t%A0"
11534 [(set_attr "type" "ibr")
11535 (set_attr "length_immediate" "0")])
11536
11537 (define_insn "nop"
11538 [(const_int 0)]
11539 ""
11540 "nop"
11541 [(set_attr "length" "1")
11542 (set_attr "length_immediate" "0")
11543 (set_attr "modrm" "0")])
11544
11545 (define_insn "vswapmov"
11546 [(set (match_operand:SI 0 "register_operand" "=r")
11547 (match_operand:SI 1 "register_operand" "r"))
11548 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
11549 ""
11550 "movl.s\t{%1, %0|%0, %1}"
11551 [(set_attr "length" "2")
11552 (set_attr "length_immediate" "0")
11553 (set_attr "modrm" "0")])
11554
11555 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11556 ;; branch prediction penalty for the third jump in a 16-byte
11557 ;; block on K8.
11558
11559 (define_insn "pad"
11560 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11561 ""
11562 {
11563 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11564 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11565 #else
11566 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11567 The align insn is used to avoid 3 jump instructions in the row to improve
11568 branch prediction and the benefits hardly outweigh the cost of extra 8
11569 nops on the average inserted by full alignment pseudo operation. */
11570 #endif
11571 return "";
11572 }
11573 [(set_attr "length" "16")])
11574
11575 (define_expand "prologue"
11576 [(const_int 0)]
11577 ""
11578 "ix86_expand_prologue (); DONE;")
11579
11580 (define_insn "set_got"
11581 [(set (match_operand:SI 0 "register_operand" "=r")
11582 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11583 (clobber (reg:CC FLAGS_REG))]
11584 "!TARGET_64BIT"
11585 { return output_set_got (operands[0], NULL_RTX); }
11586 [(set_attr "type" "multi")
11587 (set_attr "length" "12")])
11588
11589 (define_insn "set_got_labelled"
11590 [(set (match_operand:SI 0 "register_operand" "=r")
11591 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11592 UNSPEC_SET_GOT))
11593 (clobber (reg:CC FLAGS_REG))]
11594 "!TARGET_64BIT"
11595 { return output_set_got (operands[0], operands[1]); }
11596 [(set_attr "type" "multi")
11597 (set_attr "length" "12")])
11598
11599 (define_insn "set_got_rex64"
11600 [(set (match_operand:DI 0 "register_operand" "=r")
11601 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11602 "TARGET_64BIT"
11603 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11604 [(set_attr "type" "lea")
11605 (set_attr "length_address" "4")
11606 (set_attr "mode" "DI")])
11607
11608 (define_insn "set_rip_rex64"
11609 [(set (match_operand:DI 0 "register_operand" "=r")
11610 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11611 "TARGET_64BIT"
11612 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11613 [(set_attr "type" "lea")
11614 (set_attr "length_address" "4")
11615 (set_attr "mode" "DI")])
11616
11617 (define_insn "set_got_offset_rex64"
11618 [(set (match_operand:DI 0 "register_operand" "=r")
11619 (unspec:DI
11620 [(label_ref (match_operand 1 "" ""))]
11621 UNSPEC_SET_GOT_OFFSET))]
11622 "TARGET_64BIT"
11623 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11624 [(set_attr "type" "imov")
11625 (set_attr "length_immediate" "0")
11626 (set_attr "length_address" "8")
11627 (set_attr "mode" "DI")])
11628
11629 (define_expand "epilogue"
11630 [(const_int 0)]
11631 ""
11632 "ix86_expand_epilogue (1); DONE;")
11633
11634 (define_expand "sibcall_epilogue"
11635 [(const_int 0)]
11636 ""
11637 "ix86_expand_epilogue (0); DONE;")
11638
11639 (define_expand "eh_return"
11640 [(use (match_operand 0 "register_operand" ""))]
11641 ""
11642 {
11643 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11644
11645 /* Tricky bit: we write the address of the handler to which we will
11646 be returning into someone else's stack frame, one word below the
11647 stack address we wish to restore. */
11648 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11649 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11650 tmp = gen_rtx_MEM (Pmode, tmp);
11651 emit_move_insn (tmp, ra);
11652
11653 emit_jump_insn (gen_eh_return_internal ());
11654 emit_barrier ();
11655 DONE;
11656 })
11657
11658 (define_insn_and_split "eh_return_internal"
11659 [(eh_return)]
11660 ""
11661 "#"
11662 "epilogue_completed"
11663 [(const_int 0)]
11664 "ix86_expand_epilogue (2); DONE;")
11665
11666 (define_insn "leave"
11667 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11668 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11669 (clobber (mem:BLK (scratch)))]
11670 "!TARGET_64BIT"
11671 "leave"
11672 [(set_attr "type" "leave")])
11673
11674 (define_insn "leave_rex64"
11675 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11676 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11677 (clobber (mem:BLK (scratch)))]
11678 "TARGET_64BIT"
11679 "leave"
11680 [(set_attr "type" "leave")])
11681 \f
11682 ;; Bit manipulation instructions.
11683
11684 (define_expand "ffs<mode>2"
11685 [(set (match_dup 2) (const_int -1))
11686 (parallel [(set (reg:CCZ FLAGS_REG)
11687 (compare:CCZ
11688 (match_operand:SWI48 1 "nonimmediate_operand" "")
11689 (const_int 0)))
11690 (set (match_operand:SWI48 0 "register_operand" "")
11691 (ctz:SWI48 (match_dup 1)))])
11692 (set (match_dup 0) (if_then_else:SWI48
11693 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11694 (match_dup 2)
11695 (match_dup 0)))
11696 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11697 (clobber (reg:CC FLAGS_REG))])]
11698 ""
11699 {
11700 if (<MODE>mode == SImode && !TARGET_CMOVE)
11701 {
11702 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11703 DONE;
11704 }
11705 operands[2] = gen_reg_rtx (<MODE>mode);
11706 })
11707
11708 (define_insn_and_split "ffssi2_no_cmove"
11709 [(set (match_operand:SI 0 "register_operand" "=r")
11710 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11711 (clobber (match_scratch:SI 2 "=&q"))
11712 (clobber (reg:CC FLAGS_REG))]
11713 "!TARGET_CMOVE"
11714 "#"
11715 "&& reload_completed"
11716 [(parallel [(set (reg:CCZ FLAGS_REG)
11717 (compare:CCZ (match_dup 1) (const_int 0)))
11718 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11719 (set (strict_low_part (match_dup 3))
11720 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11721 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11722 (clobber (reg:CC FLAGS_REG))])
11723 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11724 (clobber (reg:CC FLAGS_REG))])
11725 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11726 (clobber (reg:CC FLAGS_REG))])]
11727 {
11728 operands[3] = gen_lowpart (QImode, operands[2]);
11729 ix86_expand_clear (operands[2]);
11730 })
11731
11732 (define_insn "*ffs<mode>_1"
11733 [(set (reg:CCZ FLAGS_REG)
11734 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11735 (const_int 0)))
11736 (set (match_operand:SWI48 0 "register_operand" "=r")
11737 (ctz:SWI48 (match_dup 1)))]
11738 ""
11739 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11740 [(set_attr "type" "alu1")
11741 (set_attr "prefix_0f" "1")
11742 (set_attr "mode" "<MODE>")])
11743
11744 (define_insn "ctz<mode>2"
11745 [(set (match_operand:SWI48 0 "register_operand" "=r")
11746 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11747 (clobber (reg:CC FLAGS_REG))]
11748 ""
11749 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11750 [(set_attr "type" "alu1")
11751 (set_attr "prefix_0f" "1")
11752 (set_attr "mode" "<MODE>")])
11753
11754 (define_expand "clz<mode>2"
11755 [(parallel
11756 [(set (match_operand:SWI248 0 "register_operand" "")
11757 (minus:SWI248
11758 (match_dup 2)
11759 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11760 (clobber (reg:CC FLAGS_REG))])
11761 (parallel
11762 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11763 (clobber (reg:CC FLAGS_REG))])]
11764 ""
11765 {
11766 if (TARGET_ABM)
11767 {
11768 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11769 DONE;
11770 }
11771 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11772 })
11773
11774 (define_insn "clz<mode>2_abm"
11775 [(set (match_operand:SWI248 0 "register_operand" "=r")
11776 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "TARGET_ABM"
11779 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11780 [(set_attr "prefix_rep" "1")
11781 (set_attr "type" "bitmanip")
11782 (set_attr "mode" "<MODE>")])
11783
11784 (define_insn "bsr_rex64"
11785 [(set (match_operand:DI 0 "register_operand" "=r")
11786 (minus:DI (const_int 63)
11787 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11788 (clobber (reg:CC FLAGS_REG))]
11789 "TARGET_64BIT"
11790 "bsr{q}\t{%1, %0|%0, %1}"
11791 [(set_attr "type" "alu1")
11792 (set_attr "prefix_0f" "1")
11793 (set_attr "mode" "DI")])
11794
11795 (define_insn "bsr"
11796 [(set (match_operand:SI 0 "register_operand" "=r")
11797 (minus:SI (const_int 31)
11798 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11799 (clobber (reg:CC FLAGS_REG))]
11800 ""
11801 "bsr{l}\t{%1, %0|%0, %1}"
11802 [(set_attr "type" "alu1")
11803 (set_attr "prefix_0f" "1")
11804 (set_attr "mode" "SI")])
11805
11806 (define_insn "*bsrhi"
11807 [(set (match_operand:HI 0 "register_operand" "=r")
11808 (minus:HI (const_int 15)
11809 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11810 (clobber (reg:CC FLAGS_REG))]
11811 ""
11812 "bsr{w}\t{%1, %0|%0, %1}"
11813 [(set_attr "type" "alu1")
11814 (set_attr "prefix_0f" "1")
11815 (set_attr "mode" "HI")])
11816
11817 (define_insn "popcount<mode>2"
11818 [(set (match_operand:SWI248 0 "register_operand" "=r")
11819 (popcount:SWI248
11820 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 "TARGET_POPCNT"
11823 {
11824 #if TARGET_MACHO
11825 return "popcnt\t{%1, %0|%0, %1}";
11826 #else
11827 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11828 #endif
11829 }
11830 [(set_attr "prefix_rep" "1")
11831 (set_attr "type" "bitmanip")
11832 (set_attr "mode" "<MODE>")])
11833
11834 (define_insn "*popcount<mode>2_cmp"
11835 [(set (reg FLAGS_REG)
11836 (compare
11837 (popcount:SWI248
11838 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11839 (const_int 0)))
11840 (set (match_operand:SWI248 0 "register_operand" "=r")
11841 (popcount:SWI248 (match_dup 1)))]
11842 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11843 {
11844 #if TARGET_MACHO
11845 return "popcnt\t{%1, %0|%0, %1}";
11846 #else
11847 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11848 #endif
11849 }
11850 [(set_attr "prefix_rep" "1")
11851 (set_attr "type" "bitmanip")
11852 (set_attr "mode" "<MODE>")])
11853
11854 (define_insn "*popcountsi2_cmp_zext"
11855 [(set (reg FLAGS_REG)
11856 (compare
11857 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11858 (const_int 0)))
11859 (set (match_operand:DI 0 "register_operand" "=r")
11860 (zero_extend:DI(popcount:SI (match_dup 1))))]
11861 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11862 {
11863 #if TARGET_MACHO
11864 return "popcnt\t{%1, %0|%0, %1}";
11865 #else
11866 return "popcnt{l}\t{%1, %0|%0, %1}";
11867 #endif
11868 }
11869 [(set_attr "prefix_rep" "1")
11870 (set_attr "type" "bitmanip")
11871 (set_attr "mode" "SI")])
11872
11873 (define_expand "bswap<mode>2"
11874 [(set (match_operand:SWI48 0 "register_operand" "")
11875 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11876 ""
11877 {
11878 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11879 {
11880 rtx x = operands[0];
11881
11882 emit_move_insn (x, operands[1]);
11883 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11884 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11885 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11886 DONE;
11887 }
11888 })
11889
11890 (define_insn "*bswap<mode>2_movbe"
11891 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11892 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11893 "TARGET_MOVBE
11894 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11895 "@
11896 bswap\t%0
11897 movbe\t{%1, %0|%0, %1}
11898 movbe\t{%1, %0|%0, %1}"
11899 [(set_attr "type" "bitmanip,imov,imov")
11900 (set_attr "modrm" "0,1,1")
11901 (set_attr "prefix_0f" "*,1,1")
11902 (set_attr "prefix_extra" "*,1,1")
11903 (set_attr "mode" "<MODE>")])
11904
11905 (define_insn "*bswap<mode>2_1"
11906 [(set (match_operand:SWI48 0 "register_operand" "=r")
11907 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11908 "TARGET_BSWAP"
11909 "bswap\t%0"
11910 [(set_attr "type" "bitmanip")
11911 (set_attr "modrm" "0")
11912 (set_attr "mode" "<MODE>")])
11913
11914 (define_insn "*bswaphi_lowpart_1"
11915 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11916 (bswap:HI (match_dup 0)))
11917 (clobber (reg:CC FLAGS_REG))]
11918 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11919 "@
11920 xchg{b}\t{%h0, %b0|%b0, %h0}
11921 rol{w}\t{$8, %0|%0, 8}"
11922 [(set_attr "length" "2,4")
11923 (set_attr "mode" "QI,HI")])
11924
11925 (define_insn "bswaphi_lowpart"
11926 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11927 (bswap:HI (match_dup 0)))
11928 (clobber (reg:CC FLAGS_REG))]
11929 ""
11930 "rol{w}\t{$8, %0|%0, 8}"
11931 [(set_attr "length" "4")
11932 (set_attr "mode" "HI")])
11933
11934 (define_expand "paritydi2"
11935 [(set (match_operand:DI 0 "register_operand" "")
11936 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11937 "! TARGET_POPCNT"
11938 {
11939 rtx scratch = gen_reg_rtx (QImode);
11940 rtx cond;
11941
11942 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11943 NULL_RTX, operands[1]));
11944
11945 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11946 gen_rtx_REG (CCmode, FLAGS_REG),
11947 const0_rtx);
11948 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11949
11950 if (TARGET_64BIT)
11951 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11952 else
11953 {
11954 rtx tmp = gen_reg_rtx (SImode);
11955
11956 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11957 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11958 }
11959 DONE;
11960 })
11961
11962 (define_expand "paritysi2"
11963 [(set (match_operand:SI 0 "register_operand" "")
11964 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11965 "! TARGET_POPCNT"
11966 {
11967 rtx scratch = gen_reg_rtx (QImode);
11968 rtx cond;
11969
11970 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11971
11972 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11973 gen_rtx_REG (CCmode, FLAGS_REG),
11974 const0_rtx);
11975 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11976
11977 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11978 DONE;
11979 })
11980
11981 (define_insn_and_split "paritydi2_cmp"
11982 [(set (reg:CC FLAGS_REG)
11983 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11984 UNSPEC_PARITY))
11985 (clobber (match_scratch:DI 0 "=r"))
11986 (clobber (match_scratch:SI 1 "=&r"))
11987 (clobber (match_scratch:HI 2 "=Q"))]
11988 "! TARGET_POPCNT"
11989 "#"
11990 "&& reload_completed"
11991 [(parallel
11992 [(set (match_dup 1)
11993 (xor:SI (match_dup 1) (match_dup 4)))
11994 (clobber (reg:CC FLAGS_REG))])
11995 (parallel
11996 [(set (reg:CC FLAGS_REG)
11997 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11998 (clobber (match_dup 1))
11999 (clobber (match_dup 2))])]
12000 {
12001 operands[4] = gen_lowpart (SImode, operands[3]);
12002
12003 if (TARGET_64BIT)
12004 {
12005 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12006 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12007 }
12008 else
12009 operands[1] = gen_highpart (SImode, operands[3]);
12010 })
12011
12012 (define_insn_and_split "paritysi2_cmp"
12013 [(set (reg:CC FLAGS_REG)
12014 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12015 UNSPEC_PARITY))
12016 (clobber (match_scratch:SI 0 "=r"))
12017 (clobber (match_scratch:HI 1 "=&Q"))]
12018 "! TARGET_POPCNT"
12019 "#"
12020 "&& reload_completed"
12021 [(parallel
12022 [(set (match_dup 1)
12023 (xor:HI (match_dup 1) (match_dup 3)))
12024 (clobber (reg:CC FLAGS_REG))])
12025 (parallel
12026 [(set (reg:CC FLAGS_REG)
12027 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12028 (clobber (match_dup 1))])]
12029 {
12030 operands[3] = gen_lowpart (HImode, operands[2]);
12031
12032 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12033 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12034 })
12035
12036 (define_insn "*parityhi2_cmp"
12037 [(set (reg:CC FLAGS_REG)
12038 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12039 UNSPEC_PARITY))
12040 (clobber (match_scratch:HI 0 "=Q"))]
12041 "! TARGET_POPCNT"
12042 "xor{b}\t{%h0, %b0|%b0, %h0}"
12043 [(set_attr "length" "2")
12044 (set_attr "mode" "HI")])
12045 \f
12046 ;; Thread-local storage patterns for ELF.
12047 ;;
12048 ;; Note that these code sequences must appear exactly as shown
12049 ;; in order to allow linker relaxation.
12050
12051 (define_insn "*tls_global_dynamic_32_gnu"
12052 [(set (match_operand:SI 0 "register_operand" "=a")
12053 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12054 (match_operand:SI 2 "tls_symbolic_operand" "")
12055 (match_operand:SI 3 "call_insn_operand" "")]
12056 UNSPEC_TLS_GD))
12057 (clobber (match_scratch:SI 4 "=d"))
12058 (clobber (match_scratch:SI 5 "=c"))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "!TARGET_64BIT && TARGET_GNU_TLS"
12061 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12062 [(set_attr "type" "multi")
12063 (set_attr "length" "12")])
12064
12065 (define_expand "tls_global_dynamic_32"
12066 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12067 (unspec:SI
12068 [(match_dup 2)
12069 (match_operand:SI 1 "tls_symbolic_operand" "")
12070 (match_dup 3)]
12071 UNSPEC_TLS_GD))
12072 (clobber (match_scratch:SI 4 ""))
12073 (clobber (match_scratch:SI 5 ""))
12074 (clobber (reg:CC FLAGS_REG))])]
12075 ""
12076 {
12077 if (flag_pic)
12078 operands[2] = pic_offset_table_rtx;
12079 else
12080 {
12081 operands[2] = gen_reg_rtx (Pmode);
12082 emit_insn (gen_set_got (operands[2]));
12083 }
12084 if (TARGET_GNU2_TLS)
12085 {
12086 emit_insn (gen_tls_dynamic_gnu2_32
12087 (operands[0], operands[1], operands[2]));
12088 DONE;
12089 }
12090 operands[3] = ix86_tls_get_addr ();
12091 })
12092
12093 (define_insn "*tls_global_dynamic_64"
12094 [(set (match_operand:DI 0 "register_operand" "=a")
12095 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12096 (match_operand:DI 3 "" "")))
12097 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12098 UNSPEC_TLS_GD)]
12099 "TARGET_64BIT"
12100 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
12101 [(set_attr "type" "multi")
12102 (set_attr "length" "16")])
12103
12104 (define_expand "tls_global_dynamic_64"
12105 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12106 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12107 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12108 UNSPEC_TLS_GD)])]
12109 ""
12110 {
12111 if (TARGET_GNU2_TLS)
12112 {
12113 emit_insn (gen_tls_dynamic_gnu2_64
12114 (operands[0], operands[1]));
12115 DONE;
12116 }
12117 operands[2] = ix86_tls_get_addr ();
12118 })
12119
12120 (define_insn "*tls_local_dynamic_base_32_gnu"
12121 [(set (match_operand:SI 0 "register_operand" "=a")
12122 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12123 (match_operand:SI 2 "call_insn_operand" "")]
12124 UNSPEC_TLS_LD_BASE))
12125 (clobber (match_scratch:SI 3 "=d"))
12126 (clobber (match_scratch:SI 4 "=c"))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "!TARGET_64BIT && TARGET_GNU_TLS"
12129 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12130 [(set_attr "type" "multi")
12131 (set_attr "length" "11")])
12132
12133 (define_expand "tls_local_dynamic_base_32"
12134 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12135 (unspec:SI [(match_dup 1) (match_dup 2)]
12136 UNSPEC_TLS_LD_BASE))
12137 (clobber (match_scratch:SI 3 ""))
12138 (clobber (match_scratch:SI 4 ""))
12139 (clobber (reg:CC FLAGS_REG))])]
12140 ""
12141 {
12142 if (flag_pic)
12143 operands[1] = pic_offset_table_rtx;
12144 else
12145 {
12146 operands[1] = gen_reg_rtx (Pmode);
12147 emit_insn (gen_set_got (operands[1]));
12148 }
12149 if (TARGET_GNU2_TLS)
12150 {
12151 emit_insn (gen_tls_dynamic_gnu2_32
12152 (operands[0], ix86_tls_module_base (), operands[1]));
12153 DONE;
12154 }
12155 operands[2] = ix86_tls_get_addr ();
12156 })
12157
12158 (define_insn "*tls_local_dynamic_base_64"
12159 [(set (match_operand:DI 0 "register_operand" "=a")
12160 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12161 (match_operand:DI 2 "" "")))
12162 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12163 "TARGET_64BIT"
12164 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12165 [(set_attr "type" "multi")
12166 (set_attr "length" "12")])
12167
12168 (define_expand "tls_local_dynamic_base_64"
12169 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12170 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12171 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12172 ""
12173 {
12174 if (TARGET_GNU2_TLS)
12175 {
12176 emit_insn (gen_tls_dynamic_gnu2_64
12177 (operands[0], ix86_tls_module_base ()));
12178 DONE;
12179 }
12180 operands[1] = ix86_tls_get_addr ();
12181 })
12182
12183 ;; Local dynamic of a single variable is a lose. Show combine how
12184 ;; to convert that back to global dynamic.
12185
12186 (define_insn_and_split "*tls_local_dynamic_32_once"
12187 [(set (match_operand:SI 0 "register_operand" "=a")
12188 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12189 (match_operand:SI 2 "call_insn_operand" "")]
12190 UNSPEC_TLS_LD_BASE)
12191 (const:SI (unspec:SI
12192 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12193 UNSPEC_DTPOFF))))
12194 (clobber (match_scratch:SI 4 "=d"))
12195 (clobber (match_scratch:SI 5 "=c"))
12196 (clobber (reg:CC FLAGS_REG))]
12197 ""
12198 "#"
12199 ""
12200 [(parallel [(set (match_dup 0)
12201 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12202 UNSPEC_TLS_GD))
12203 (clobber (match_dup 4))
12204 (clobber (match_dup 5))
12205 (clobber (reg:CC FLAGS_REG))])]
12206 "")
12207
12208 ;; Load and add the thread base pointer from %gs:0.
12209
12210 (define_insn "*load_tp_si"
12211 [(set (match_operand:SI 0 "register_operand" "=r")
12212 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12213 "!TARGET_64BIT"
12214 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12215 [(set_attr "type" "imov")
12216 (set_attr "modrm" "0")
12217 (set_attr "length" "7")
12218 (set_attr "memory" "load")
12219 (set_attr "imm_disp" "false")])
12220
12221 (define_insn "*add_tp_si"
12222 [(set (match_operand:SI 0 "register_operand" "=r")
12223 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12224 (match_operand:SI 1 "register_operand" "0")))
12225 (clobber (reg:CC FLAGS_REG))]
12226 "!TARGET_64BIT"
12227 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12228 [(set_attr "type" "alu")
12229 (set_attr "modrm" "0")
12230 (set_attr "length" "7")
12231 (set_attr "memory" "load")
12232 (set_attr "imm_disp" "false")])
12233
12234 (define_insn "*load_tp_di"
12235 [(set (match_operand:DI 0 "register_operand" "=r")
12236 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12237 "TARGET_64BIT"
12238 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12239 [(set_attr "type" "imov")
12240 (set_attr "modrm" "0")
12241 (set_attr "length" "7")
12242 (set_attr "memory" "load")
12243 (set_attr "imm_disp" "false")])
12244
12245 (define_insn "*add_tp_di"
12246 [(set (match_operand:DI 0 "register_operand" "=r")
12247 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12248 (match_operand:DI 1 "register_operand" "0")))
12249 (clobber (reg:CC FLAGS_REG))]
12250 "TARGET_64BIT"
12251 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12252 [(set_attr "type" "alu")
12253 (set_attr "modrm" "0")
12254 (set_attr "length" "7")
12255 (set_attr "memory" "load")
12256 (set_attr "imm_disp" "false")])
12257
12258 ;; GNU2 TLS patterns can be split.
12259
12260 (define_expand "tls_dynamic_gnu2_32"
12261 [(set (match_dup 3)
12262 (plus:SI (match_operand:SI 2 "register_operand" "")
12263 (const:SI
12264 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12265 UNSPEC_TLSDESC))))
12266 (parallel
12267 [(set (match_operand:SI 0 "register_operand" "")
12268 (unspec:SI [(match_dup 1) (match_dup 3)
12269 (match_dup 2) (reg:SI SP_REG)]
12270 UNSPEC_TLSDESC))
12271 (clobber (reg:CC FLAGS_REG))])]
12272 "!TARGET_64BIT && TARGET_GNU2_TLS"
12273 {
12274 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12275 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12276 })
12277
12278 (define_insn "*tls_dynamic_lea_32"
12279 [(set (match_operand:SI 0 "register_operand" "=r")
12280 (plus:SI (match_operand:SI 1 "register_operand" "b")
12281 (const:SI
12282 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12283 UNSPEC_TLSDESC))))]
12284 "!TARGET_64BIT && TARGET_GNU2_TLS"
12285 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12286 [(set_attr "type" "lea")
12287 (set_attr "mode" "SI")
12288 (set_attr "length" "6")
12289 (set_attr "length_address" "4")])
12290
12291 (define_insn "*tls_dynamic_call_32"
12292 [(set (match_operand:SI 0 "register_operand" "=a")
12293 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12294 (match_operand:SI 2 "register_operand" "0")
12295 ;; we have to make sure %ebx still points to the GOT
12296 (match_operand:SI 3 "register_operand" "b")
12297 (reg:SI SP_REG)]
12298 UNSPEC_TLSDESC))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "!TARGET_64BIT && TARGET_GNU2_TLS"
12301 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12302 [(set_attr "type" "call")
12303 (set_attr "length" "2")
12304 (set_attr "length_address" "0")])
12305
12306 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12307 [(set (match_operand:SI 0 "register_operand" "=&a")
12308 (plus:SI
12309 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12310 (match_operand:SI 4 "" "")
12311 (match_operand:SI 2 "register_operand" "b")
12312 (reg:SI SP_REG)]
12313 UNSPEC_TLSDESC)
12314 (const:SI (unspec:SI
12315 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12316 UNSPEC_DTPOFF))))
12317 (clobber (reg:CC FLAGS_REG))]
12318 "!TARGET_64BIT && TARGET_GNU2_TLS"
12319 "#"
12320 ""
12321 [(set (match_dup 0) (match_dup 5))]
12322 {
12323 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12324 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12325 })
12326
12327 (define_expand "tls_dynamic_gnu2_64"
12328 [(set (match_dup 2)
12329 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12330 UNSPEC_TLSDESC))
12331 (parallel
12332 [(set (match_operand:DI 0 "register_operand" "")
12333 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12334 UNSPEC_TLSDESC))
12335 (clobber (reg:CC FLAGS_REG))])]
12336 "TARGET_64BIT && TARGET_GNU2_TLS"
12337 {
12338 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12339 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12340 })
12341
12342 (define_insn "*tls_dynamic_lea_64"
12343 [(set (match_operand:DI 0 "register_operand" "=r")
12344 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12345 UNSPEC_TLSDESC))]
12346 "TARGET_64BIT && TARGET_GNU2_TLS"
12347 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12348 [(set_attr "type" "lea")
12349 (set_attr "mode" "DI")
12350 (set_attr "length" "7")
12351 (set_attr "length_address" "4")])
12352
12353 (define_insn "*tls_dynamic_call_64"
12354 [(set (match_operand:DI 0 "register_operand" "=a")
12355 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12356 (match_operand:DI 2 "register_operand" "0")
12357 (reg:DI SP_REG)]
12358 UNSPEC_TLSDESC))
12359 (clobber (reg:CC FLAGS_REG))]
12360 "TARGET_64BIT && TARGET_GNU2_TLS"
12361 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12362 [(set_attr "type" "call")
12363 (set_attr "length" "2")
12364 (set_attr "length_address" "0")])
12365
12366 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12367 [(set (match_operand:DI 0 "register_operand" "=&a")
12368 (plus:DI
12369 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12370 (match_operand:DI 3 "" "")
12371 (reg:DI SP_REG)]
12372 UNSPEC_TLSDESC)
12373 (const:DI (unspec:DI
12374 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12375 UNSPEC_DTPOFF))))
12376 (clobber (reg:CC FLAGS_REG))]
12377 "TARGET_64BIT && TARGET_GNU2_TLS"
12378 "#"
12379 ""
12380 [(set (match_dup 0) (match_dup 4))]
12381 {
12382 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12383 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12384 })
12385
12386 ;;
12387 \f
12388 ;; These patterns match the binary 387 instructions for addM3, subM3,
12389 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12390 ;; SFmode. The first is the normal insn, the second the same insn but
12391 ;; with one operand a conversion, and the third the same insn but with
12392 ;; the other operand a conversion. The conversion may be SFmode or
12393 ;; SImode if the target mode DFmode, but only SImode if the target mode
12394 ;; is SFmode.
12395
12396 ;; Gcc is slightly more smart about handling normal two address instructions
12397 ;; so use special patterns for add and mull.
12398
12399 (define_insn "*fop_<mode>_comm_mixed_avx"
12400 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12401 (match_operator:MODEF 3 "binary_fp_operator"
12402 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12403 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12404 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12405 && COMMUTATIVE_ARITH_P (operands[3])
12406 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12407 "* return output_387_binary_op (insn, operands);"
12408 [(set (attr "type")
12409 (if_then_else (eq_attr "alternative" "1")
12410 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12411 (const_string "ssemul")
12412 (const_string "sseadd"))
12413 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12414 (const_string "fmul")
12415 (const_string "fop"))))
12416 (set_attr "prefix" "orig,maybe_vex")
12417 (set_attr "mode" "<MODE>")])
12418
12419 (define_insn "*fop_<mode>_comm_mixed"
12420 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12421 (match_operator:MODEF 3 "binary_fp_operator"
12422 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12423 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12424 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12425 && COMMUTATIVE_ARITH_P (operands[3])
12426 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12427 "* return output_387_binary_op (insn, operands);"
12428 [(set (attr "type")
12429 (if_then_else (eq_attr "alternative" "1")
12430 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12431 (const_string "ssemul")
12432 (const_string "sseadd"))
12433 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12434 (const_string "fmul")
12435 (const_string "fop"))))
12436 (set_attr "mode" "<MODE>")])
12437
12438 (define_insn "*fop_<mode>_comm_avx"
12439 [(set (match_operand:MODEF 0 "register_operand" "=x")
12440 (match_operator:MODEF 3 "binary_fp_operator"
12441 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12442 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12443 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12444 && COMMUTATIVE_ARITH_P (operands[3])
12445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12446 "* return output_387_binary_op (insn, operands);"
12447 [(set (attr "type")
12448 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12449 (const_string "ssemul")
12450 (const_string "sseadd")))
12451 (set_attr "prefix" "vex")
12452 (set_attr "mode" "<MODE>")])
12453
12454 (define_insn "*fop_<mode>_comm_sse"
12455 [(set (match_operand:MODEF 0 "register_operand" "=x")
12456 (match_operator:MODEF 3 "binary_fp_operator"
12457 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12458 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12459 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12460 && COMMUTATIVE_ARITH_P (operands[3])
12461 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12462 "* return output_387_binary_op (insn, operands);"
12463 [(set (attr "type")
12464 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12465 (const_string "ssemul")
12466 (const_string "sseadd")))
12467 (set_attr "mode" "<MODE>")])
12468
12469 (define_insn "*fop_<mode>_comm_i387"
12470 [(set (match_operand:MODEF 0 "register_operand" "=f")
12471 (match_operator:MODEF 3 "binary_fp_operator"
12472 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12473 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12474 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12475 && COMMUTATIVE_ARITH_P (operands[3])
12476 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12477 "* return output_387_binary_op (insn, operands);"
12478 [(set (attr "type")
12479 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12480 (const_string "fmul")
12481 (const_string "fop")))
12482 (set_attr "mode" "<MODE>")])
12483
12484 (define_insn "*fop_<mode>_1_mixed_avx"
12485 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12486 (match_operator:MODEF 3 "binary_fp_operator"
12487 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12488 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12489 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12490 && !COMMUTATIVE_ARITH_P (operands[3])
12491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12492 "* return output_387_binary_op (insn, operands);"
12493 [(set (attr "type")
12494 (cond [(and (eq_attr "alternative" "2")
12495 (match_operand:MODEF 3 "mult_operator" ""))
12496 (const_string "ssemul")
12497 (and (eq_attr "alternative" "2")
12498 (match_operand:MODEF 3 "div_operator" ""))
12499 (const_string "ssediv")
12500 (eq_attr "alternative" "2")
12501 (const_string "sseadd")
12502 (match_operand:MODEF 3 "mult_operator" "")
12503 (const_string "fmul")
12504 (match_operand:MODEF 3 "div_operator" "")
12505 (const_string "fdiv")
12506 ]
12507 (const_string "fop")))
12508 (set_attr "prefix" "orig,orig,maybe_vex")
12509 (set_attr "mode" "<MODE>")])
12510
12511 (define_insn "*fop_<mode>_1_mixed"
12512 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12513 (match_operator:MODEF 3 "binary_fp_operator"
12514 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12515 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12516 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12517 && !COMMUTATIVE_ARITH_P (operands[3])
12518 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12519 "* return output_387_binary_op (insn, operands);"
12520 [(set (attr "type")
12521 (cond [(and (eq_attr "alternative" "2")
12522 (match_operand:MODEF 3 "mult_operator" ""))
12523 (const_string "ssemul")
12524 (and (eq_attr "alternative" "2")
12525 (match_operand:MODEF 3 "div_operator" ""))
12526 (const_string "ssediv")
12527 (eq_attr "alternative" "2")
12528 (const_string "sseadd")
12529 (match_operand:MODEF 3 "mult_operator" "")
12530 (const_string "fmul")
12531 (match_operand:MODEF 3 "div_operator" "")
12532 (const_string "fdiv")
12533 ]
12534 (const_string "fop")))
12535 (set_attr "mode" "<MODE>")])
12536
12537 (define_insn "*rcpsf2_sse"
12538 [(set (match_operand:SF 0 "register_operand" "=x")
12539 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12540 UNSPEC_RCP))]
12541 "TARGET_SSE_MATH"
12542 "%vrcpss\t{%1, %d0|%d0, %1}"
12543 [(set_attr "type" "sse")
12544 (set_attr "atom_sse_attr" "rcp")
12545 (set_attr "prefix" "maybe_vex")
12546 (set_attr "mode" "SF")])
12547
12548 (define_insn "*fop_<mode>_1_avx"
12549 [(set (match_operand:MODEF 0 "register_operand" "=x")
12550 (match_operator:MODEF 3 "binary_fp_operator"
12551 [(match_operand:MODEF 1 "register_operand" "x")
12552 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12553 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12554 && !COMMUTATIVE_ARITH_P (operands[3])"
12555 "* return output_387_binary_op (insn, operands);"
12556 [(set (attr "type")
12557 (cond [(match_operand:MODEF 3 "mult_operator" "")
12558 (const_string "ssemul")
12559 (match_operand:MODEF 3 "div_operator" "")
12560 (const_string "ssediv")
12561 ]
12562 (const_string "sseadd")))
12563 (set_attr "prefix" "vex")
12564 (set_attr "mode" "<MODE>")])
12565
12566 (define_insn "*fop_<mode>_1_sse"
12567 [(set (match_operand:MODEF 0 "register_operand" "=x")
12568 (match_operator:MODEF 3 "binary_fp_operator"
12569 [(match_operand:MODEF 1 "register_operand" "0")
12570 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12572 && !COMMUTATIVE_ARITH_P (operands[3])"
12573 "* return output_387_binary_op (insn, operands);"
12574 [(set (attr "type")
12575 (cond [(match_operand:MODEF 3 "mult_operator" "")
12576 (const_string "ssemul")
12577 (match_operand:MODEF 3 "div_operator" "")
12578 (const_string "ssediv")
12579 ]
12580 (const_string "sseadd")))
12581 (set_attr "mode" "<MODE>")])
12582
12583 ;; This pattern is not fully shadowed by the pattern above.
12584 (define_insn "*fop_<mode>_1_i387"
12585 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12586 (match_operator:MODEF 3 "binary_fp_operator"
12587 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12588 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12589 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12590 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12591 && !COMMUTATIVE_ARITH_P (operands[3])
12592 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12593 "* return output_387_binary_op (insn, operands);"
12594 [(set (attr "type")
12595 (cond [(match_operand:MODEF 3 "mult_operator" "")
12596 (const_string "fmul")
12597 (match_operand:MODEF 3 "div_operator" "")
12598 (const_string "fdiv")
12599 ]
12600 (const_string "fop")))
12601 (set_attr "mode" "<MODE>")])
12602
12603 ;; ??? Add SSE splitters for these!
12604 (define_insn "*fop_<MODEF:mode>_2_i387"
12605 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12606 (match_operator:MODEF 3 "binary_fp_operator"
12607 [(float:MODEF
12608 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12609 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12610 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12611 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12612 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12613 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12614 [(set (attr "type")
12615 (cond [(match_operand:MODEF 3 "mult_operator" "")
12616 (const_string "fmul")
12617 (match_operand:MODEF 3 "div_operator" "")
12618 (const_string "fdiv")
12619 ]
12620 (const_string "fop")))
12621 (set_attr "fp_int_src" "true")
12622 (set_attr "mode" "<X87MODEI12:MODE>")])
12623
12624 (define_insn "*fop_<MODEF:mode>_3_i387"
12625 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12626 (match_operator:MODEF 3 "binary_fp_operator"
12627 [(match_operand:MODEF 1 "register_operand" "0,0")
12628 (float:MODEF
12629 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12630 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12631 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12632 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12633 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12634 [(set (attr "type")
12635 (cond [(match_operand:MODEF 3 "mult_operator" "")
12636 (const_string "fmul")
12637 (match_operand:MODEF 3 "div_operator" "")
12638 (const_string "fdiv")
12639 ]
12640 (const_string "fop")))
12641 (set_attr "fp_int_src" "true")
12642 (set_attr "mode" "<MODE>")])
12643
12644 (define_insn "*fop_df_4_i387"
12645 [(set (match_operand:DF 0 "register_operand" "=f,f")
12646 (match_operator:DF 3 "binary_fp_operator"
12647 [(float_extend:DF
12648 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12649 (match_operand:DF 2 "register_operand" "0,f")]))]
12650 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12651 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12653 "* return output_387_binary_op (insn, operands);"
12654 [(set (attr "type")
12655 (cond [(match_operand:DF 3 "mult_operator" "")
12656 (const_string "fmul")
12657 (match_operand:DF 3 "div_operator" "")
12658 (const_string "fdiv")
12659 ]
12660 (const_string "fop")))
12661 (set_attr "mode" "SF")])
12662
12663 (define_insn "*fop_df_5_i387"
12664 [(set (match_operand:DF 0 "register_operand" "=f,f")
12665 (match_operator:DF 3 "binary_fp_operator"
12666 [(match_operand:DF 1 "register_operand" "0,f")
12667 (float_extend:DF
12668 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12669 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12670 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12671 "* return output_387_binary_op (insn, operands);"
12672 [(set (attr "type")
12673 (cond [(match_operand:DF 3 "mult_operator" "")
12674 (const_string "fmul")
12675 (match_operand:DF 3 "div_operator" "")
12676 (const_string "fdiv")
12677 ]
12678 (const_string "fop")))
12679 (set_attr "mode" "SF")])
12680
12681 (define_insn "*fop_df_6_i387"
12682 [(set (match_operand:DF 0 "register_operand" "=f,f")
12683 (match_operator:DF 3 "binary_fp_operator"
12684 [(float_extend:DF
12685 (match_operand:SF 1 "register_operand" "0,f"))
12686 (float_extend:DF
12687 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12688 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12689 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12690 "* return output_387_binary_op (insn, operands);"
12691 [(set (attr "type")
12692 (cond [(match_operand:DF 3 "mult_operator" "")
12693 (const_string "fmul")
12694 (match_operand:DF 3 "div_operator" "")
12695 (const_string "fdiv")
12696 ]
12697 (const_string "fop")))
12698 (set_attr "mode" "SF")])
12699
12700 (define_insn "*fop_xf_comm_i387"
12701 [(set (match_operand:XF 0 "register_operand" "=f")
12702 (match_operator:XF 3 "binary_fp_operator"
12703 [(match_operand:XF 1 "register_operand" "%0")
12704 (match_operand:XF 2 "register_operand" "f")]))]
12705 "TARGET_80387
12706 && COMMUTATIVE_ARITH_P (operands[3])"
12707 "* return output_387_binary_op (insn, operands);"
12708 [(set (attr "type")
12709 (if_then_else (match_operand:XF 3 "mult_operator" "")
12710 (const_string "fmul")
12711 (const_string "fop")))
12712 (set_attr "mode" "XF")])
12713
12714 (define_insn "*fop_xf_1_i387"
12715 [(set (match_operand:XF 0 "register_operand" "=f,f")
12716 (match_operator:XF 3 "binary_fp_operator"
12717 [(match_operand:XF 1 "register_operand" "0,f")
12718 (match_operand:XF 2 "register_operand" "f,0")]))]
12719 "TARGET_80387
12720 && !COMMUTATIVE_ARITH_P (operands[3])"
12721 "* return output_387_binary_op (insn, operands);"
12722 [(set (attr "type")
12723 (cond [(match_operand:XF 3 "mult_operator" "")
12724 (const_string "fmul")
12725 (match_operand:XF 3 "div_operator" "")
12726 (const_string "fdiv")
12727 ]
12728 (const_string "fop")))
12729 (set_attr "mode" "XF")])
12730
12731 (define_insn "*fop_xf_2_i387"
12732 [(set (match_operand:XF 0 "register_operand" "=f,f")
12733 (match_operator:XF 3 "binary_fp_operator"
12734 [(float:XF
12735 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12736 (match_operand:XF 2 "register_operand" "0,0")]))]
12737 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12738 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12739 [(set (attr "type")
12740 (cond [(match_operand:XF 3 "mult_operator" "")
12741 (const_string "fmul")
12742 (match_operand:XF 3 "div_operator" "")
12743 (const_string "fdiv")
12744 ]
12745 (const_string "fop")))
12746 (set_attr "fp_int_src" "true")
12747 (set_attr "mode" "<MODE>")])
12748
12749 (define_insn "*fop_xf_3_i387"
12750 [(set (match_operand:XF 0 "register_operand" "=f,f")
12751 (match_operator:XF 3 "binary_fp_operator"
12752 [(match_operand:XF 1 "register_operand" "0,0")
12753 (float:XF
12754 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12755 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12756 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12757 [(set (attr "type")
12758 (cond [(match_operand:XF 3 "mult_operator" "")
12759 (const_string "fmul")
12760 (match_operand:XF 3 "div_operator" "")
12761 (const_string "fdiv")
12762 ]
12763 (const_string "fop")))
12764 (set_attr "fp_int_src" "true")
12765 (set_attr "mode" "<MODE>")])
12766
12767 (define_insn "*fop_xf_4_i387"
12768 [(set (match_operand:XF 0 "register_operand" "=f,f")
12769 (match_operator:XF 3 "binary_fp_operator"
12770 [(float_extend:XF
12771 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12772 (match_operand:XF 2 "register_operand" "0,f")]))]
12773 "TARGET_80387"
12774 "* return output_387_binary_op (insn, operands);"
12775 [(set (attr "type")
12776 (cond [(match_operand:XF 3 "mult_operator" "")
12777 (const_string "fmul")
12778 (match_operand:XF 3 "div_operator" "")
12779 (const_string "fdiv")
12780 ]
12781 (const_string "fop")))
12782 (set_attr "mode" "<MODE>")])
12783
12784 (define_insn "*fop_xf_5_i387"
12785 [(set (match_operand:XF 0 "register_operand" "=f,f")
12786 (match_operator:XF 3 "binary_fp_operator"
12787 [(match_operand:XF 1 "register_operand" "0,f")
12788 (float_extend:XF
12789 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12790 "TARGET_80387"
12791 "* return output_387_binary_op (insn, operands);"
12792 [(set (attr "type")
12793 (cond [(match_operand:XF 3 "mult_operator" "")
12794 (const_string "fmul")
12795 (match_operand:XF 3 "div_operator" "")
12796 (const_string "fdiv")
12797 ]
12798 (const_string "fop")))
12799 (set_attr "mode" "<MODE>")])
12800
12801 (define_insn "*fop_xf_6_i387"
12802 [(set (match_operand:XF 0 "register_operand" "=f,f")
12803 (match_operator:XF 3 "binary_fp_operator"
12804 [(float_extend:XF
12805 (match_operand:MODEF 1 "register_operand" "0,f"))
12806 (float_extend:XF
12807 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12808 "TARGET_80387"
12809 "* return output_387_binary_op (insn, operands);"
12810 [(set (attr "type")
12811 (cond [(match_operand:XF 3 "mult_operator" "")
12812 (const_string "fmul")
12813 (match_operand:XF 3 "div_operator" "")
12814 (const_string "fdiv")
12815 ]
12816 (const_string "fop")))
12817 (set_attr "mode" "<MODE>")])
12818
12819 (define_split
12820 [(set (match_operand 0 "register_operand" "")
12821 (match_operator 3 "binary_fp_operator"
12822 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12823 (match_operand 2 "register_operand" "")]))]
12824 "reload_completed
12825 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12826 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12827 [(const_int 0)]
12828 {
12829 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12830 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12831 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12832 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12833 GET_MODE (operands[3]),
12834 operands[4],
12835 operands[2])));
12836 ix86_free_from_memory (GET_MODE (operands[1]));
12837 DONE;
12838 })
12839
12840 (define_split
12841 [(set (match_operand 0 "register_operand" "")
12842 (match_operator 3 "binary_fp_operator"
12843 [(match_operand 1 "register_operand" "")
12844 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12845 "reload_completed
12846 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12847 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12848 [(const_int 0)]
12849 {
12850 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12851 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12852 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12853 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12854 GET_MODE (operands[3]),
12855 operands[1],
12856 operands[4])));
12857 ix86_free_from_memory (GET_MODE (operands[2]));
12858 DONE;
12859 })
12860 \f
12861 ;; FPU special functions.
12862
12863 ;; This pattern implements a no-op XFmode truncation for
12864 ;; all fancy i386 XFmode math functions.
12865
12866 (define_insn "truncxf<mode>2_i387_noop_unspec"
12867 [(set (match_operand:MODEF 0 "register_operand" "=f")
12868 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12869 UNSPEC_TRUNC_NOOP))]
12870 "TARGET_USE_FANCY_MATH_387"
12871 "* return output_387_reg_move (insn, operands);"
12872 [(set_attr "type" "fmov")
12873 (set_attr "mode" "<MODE>")])
12874
12875 (define_insn "sqrtxf2"
12876 [(set (match_operand:XF 0 "register_operand" "=f")
12877 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12878 "TARGET_USE_FANCY_MATH_387"
12879 "fsqrt"
12880 [(set_attr "type" "fpspc")
12881 (set_attr "mode" "XF")
12882 (set_attr "athlon_decode" "direct")
12883 (set_attr "amdfam10_decode" "direct")])
12884
12885 (define_insn "sqrt_extend<mode>xf2_i387"
12886 [(set (match_operand:XF 0 "register_operand" "=f")
12887 (sqrt:XF
12888 (float_extend:XF
12889 (match_operand:MODEF 1 "register_operand" "0"))))]
12890 "TARGET_USE_FANCY_MATH_387"
12891 "fsqrt"
12892 [(set_attr "type" "fpspc")
12893 (set_attr "mode" "XF")
12894 (set_attr "athlon_decode" "direct")
12895 (set_attr "amdfam10_decode" "direct")])
12896
12897 (define_insn "*rsqrtsf2_sse"
12898 [(set (match_operand:SF 0 "register_operand" "=x")
12899 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12900 UNSPEC_RSQRT))]
12901 "TARGET_SSE_MATH"
12902 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12903 [(set_attr "type" "sse")
12904 (set_attr "atom_sse_attr" "rcp")
12905 (set_attr "prefix" "maybe_vex")
12906 (set_attr "mode" "SF")])
12907
12908 (define_expand "rsqrtsf2"
12909 [(set (match_operand:SF 0 "register_operand" "")
12910 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12911 UNSPEC_RSQRT))]
12912 "TARGET_SSE_MATH"
12913 {
12914 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12915 DONE;
12916 })
12917
12918 (define_insn "*sqrt<mode>2_sse"
12919 [(set (match_operand:MODEF 0 "register_operand" "=x")
12920 (sqrt:MODEF
12921 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12923 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12924 [(set_attr "type" "sse")
12925 (set_attr "atom_sse_attr" "sqrt")
12926 (set_attr "prefix" "maybe_vex")
12927 (set_attr "mode" "<MODE>")
12928 (set_attr "athlon_decode" "*")
12929 (set_attr "amdfam10_decode" "*")])
12930
12931 (define_expand "sqrt<mode>2"
12932 [(set (match_operand:MODEF 0 "register_operand" "")
12933 (sqrt:MODEF
12934 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12935 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12936 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12937 {
12938 if (<MODE>mode == SFmode
12939 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12940 && flag_finite_math_only && !flag_trapping_math
12941 && flag_unsafe_math_optimizations)
12942 {
12943 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12944 DONE;
12945 }
12946
12947 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12948 {
12949 rtx op0 = gen_reg_rtx (XFmode);
12950 rtx op1 = force_reg (<MODE>mode, operands[1]);
12951
12952 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12953 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12954 DONE;
12955 }
12956 })
12957
12958 (define_insn "fpremxf4_i387"
12959 [(set (match_operand:XF 0 "register_operand" "=f")
12960 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12961 (match_operand:XF 3 "register_operand" "1")]
12962 UNSPEC_FPREM_F))
12963 (set (match_operand:XF 1 "register_operand" "=u")
12964 (unspec:XF [(match_dup 2) (match_dup 3)]
12965 UNSPEC_FPREM_U))
12966 (set (reg:CCFP FPSR_REG)
12967 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12968 UNSPEC_C2_FLAG))]
12969 "TARGET_USE_FANCY_MATH_387"
12970 "fprem"
12971 [(set_attr "type" "fpspc")
12972 (set_attr "mode" "XF")])
12973
12974 (define_expand "fmodxf3"
12975 [(use (match_operand:XF 0 "register_operand" ""))
12976 (use (match_operand:XF 1 "general_operand" ""))
12977 (use (match_operand:XF 2 "general_operand" ""))]
12978 "TARGET_USE_FANCY_MATH_387"
12979 {
12980 rtx label = gen_label_rtx ();
12981
12982 rtx op1 = gen_reg_rtx (XFmode);
12983 rtx op2 = gen_reg_rtx (XFmode);
12984
12985 emit_move_insn (op2, operands[2]);
12986 emit_move_insn (op1, operands[1]);
12987
12988 emit_label (label);
12989 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12990 ix86_emit_fp_unordered_jump (label);
12991 LABEL_NUSES (label) = 1;
12992
12993 emit_move_insn (operands[0], op1);
12994 DONE;
12995 })
12996
12997 (define_expand "fmod<mode>3"
12998 [(use (match_operand:MODEF 0 "register_operand" ""))
12999 (use (match_operand:MODEF 1 "general_operand" ""))
13000 (use (match_operand:MODEF 2 "general_operand" ""))]
13001 "TARGET_USE_FANCY_MATH_387"
13002 {
13003 rtx label = gen_label_rtx ();
13004
13005 rtx op1 = gen_reg_rtx (XFmode);
13006 rtx op2 = gen_reg_rtx (XFmode);
13007
13008 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13009 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13010
13011 emit_label (label);
13012 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13013 ix86_emit_fp_unordered_jump (label);
13014 LABEL_NUSES (label) = 1;
13015
13016 /* Truncate the result properly for strict SSE math. */
13017 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13018 && !TARGET_MIX_SSE_I387)
13019 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13020 else
13021 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13022
13023 DONE;
13024 })
13025
13026 (define_insn "fprem1xf4_i387"
13027 [(set (match_operand:XF 0 "register_operand" "=f")
13028 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13029 (match_operand:XF 3 "register_operand" "1")]
13030 UNSPEC_FPREM1_F))
13031 (set (match_operand:XF 1 "register_operand" "=u")
13032 (unspec:XF [(match_dup 2) (match_dup 3)]
13033 UNSPEC_FPREM1_U))
13034 (set (reg:CCFP FPSR_REG)
13035 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13036 UNSPEC_C2_FLAG))]
13037 "TARGET_USE_FANCY_MATH_387"
13038 "fprem1"
13039 [(set_attr "type" "fpspc")
13040 (set_attr "mode" "XF")])
13041
13042 (define_expand "remainderxf3"
13043 [(use (match_operand:XF 0 "register_operand" ""))
13044 (use (match_operand:XF 1 "general_operand" ""))
13045 (use (match_operand:XF 2 "general_operand" ""))]
13046 "TARGET_USE_FANCY_MATH_387"
13047 {
13048 rtx label = gen_label_rtx ();
13049
13050 rtx op1 = gen_reg_rtx (XFmode);
13051 rtx op2 = gen_reg_rtx (XFmode);
13052
13053 emit_move_insn (op2, operands[2]);
13054 emit_move_insn (op1, operands[1]);
13055
13056 emit_label (label);
13057 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13058 ix86_emit_fp_unordered_jump (label);
13059 LABEL_NUSES (label) = 1;
13060
13061 emit_move_insn (operands[0], op1);
13062 DONE;
13063 })
13064
13065 (define_expand "remainder<mode>3"
13066 [(use (match_operand:MODEF 0 "register_operand" ""))
13067 (use (match_operand:MODEF 1 "general_operand" ""))
13068 (use (match_operand:MODEF 2 "general_operand" ""))]
13069 "TARGET_USE_FANCY_MATH_387"
13070 {
13071 rtx label = gen_label_rtx ();
13072
13073 rtx op1 = gen_reg_rtx (XFmode);
13074 rtx op2 = gen_reg_rtx (XFmode);
13075
13076 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13077 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13078
13079 emit_label (label);
13080
13081 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13082 ix86_emit_fp_unordered_jump (label);
13083 LABEL_NUSES (label) = 1;
13084
13085 /* Truncate the result properly for strict SSE math. */
13086 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13087 && !TARGET_MIX_SSE_I387)
13088 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13089 else
13090 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13091
13092 DONE;
13093 })
13094
13095 (define_insn "*sinxf2_i387"
13096 [(set (match_operand:XF 0 "register_operand" "=f")
13097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13098 "TARGET_USE_FANCY_MATH_387
13099 && flag_unsafe_math_optimizations"
13100 "fsin"
13101 [(set_attr "type" "fpspc")
13102 (set_attr "mode" "XF")])
13103
13104 (define_insn "*sin_extend<mode>xf2_i387"
13105 [(set (match_operand:XF 0 "register_operand" "=f")
13106 (unspec:XF [(float_extend:XF
13107 (match_operand:MODEF 1 "register_operand" "0"))]
13108 UNSPEC_SIN))]
13109 "TARGET_USE_FANCY_MATH_387
13110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13111 || TARGET_MIX_SSE_I387)
13112 && flag_unsafe_math_optimizations"
13113 "fsin"
13114 [(set_attr "type" "fpspc")
13115 (set_attr "mode" "XF")])
13116
13117 (define_insn "*cosxf2_i387"
13118 [(set (match_operand:XF 0 "register_operand" "=f")
13119 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13120 "TARGET_USE_FANCY_MATH_387
13121 && flag_unsafe_math_optimizations"
13122 "fcos"
13123 [(set_attr "type" "fpspc")
13124 (set_attr "mode" "XF")])
13125
13126 (define_insn "*cos_extend<mode>xf2_i387"
13127 [(set (match_operand:XF 0 "register_operand" "=f")
13128 (unspec:XF [(float_extend:XF
13129 (match_operand:MODEF 1 "register_operand" "0"))]
13130 UNSPEC_COS))]
13131 "TARGET_USE_FANCY_MATH_387
13132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13133 || TARGET_MIX_SSE_I387)
13134 && flag_unsafe_math_optimizations"
13135 "fcos"
13136 [(set_attr "type" "fpspc")
13137 (set_attr "mode" "XF")])
13138
13139 ;; When sincos pattern is defined, sin and cos builtin functions will be
13140 ;; expanded to sincos pattern with one of its outputs left unused.
13141 ;; CSE pass will figure out if two sincos patterns can be combined,
13142 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13143 ;; depending on the unused output.
13144
13145 (define_insn "sincosxf3"
13146 [(set (match_operand:XF 0 "register_operand" "=f")
13147 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13148 UNSPEC_SINCOS_COS))
13149 (set (match_operand:XF 1 "register_operand" "=u")
13150 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13151 "TARGET_USE_FANCY_MATH_387
13152 && flag_unsafe_math_optimizations"
13153 "fsincos"
13154 [(set_attr "type" "fpspc")
13155 (set_attr "mode" "XF")])
13156
13157 (define_split
13158 [(set (match_operand:XF 0 "register_operand" "")
13159 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13160 UNSPEC_SINCOS_COS))
13161 (set (match_operand:XF 1 "register_operand" "")
13162 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13163 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13164 && !(reload_completed || reload_in_progress)"
13165 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13166 "")
13167
13168 (define_split
13169 [(set (match_operand:XF 0 "register_operand" "")
13170 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13171 UNSPEC_SINCOS_COS))
13172 (set (match_operand:XF 1 "register_operand" "")
13173 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13174 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13175 && !(reload_completed || reload_in_progress)"
13176 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13177 "")
13178
13179 (define_insn "sincos_extend<mode>xf3_i387"
13180 [(set (match_operand:XF 0 "register_operand" "=f")
13181 (unspec:XF [(float_extend:XF
13182 (match_operand:MODEF 2 "register_operand" "0"))]
13183 UNSPEC_SINCOS_COS))
13184 (set (match_operand:XF 1 "register_operand" "=u")
13185 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13186 "TARGET_USE_FANCY_MATH_387
13187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13188 || TARGET_MIX_SSE_I387)
13189 && flag_unsafe_math_optimizations"
13190 "fsincos"
13191 [(set_attr "type" "fpspc")
13192 (set_attr "mode" "XF")])
13193
13194 (define_split
13195 [(set (match_operand:XF 0 "register_operand" "")
13196 (unspec:XF [(float_extend:XF
13197 (match_operand:MODEF 2 "register_operand" ""))]
13198 UNSPEC_SINCOS_COS))
13199 (set (match_operand:XF 1 "register_operand" "")
13200 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13201 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13202 && !(reload_completed || reload_in_progress)"
13203 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13204 "")
13205
13206 (define_split
13207 [(set (match_operand:XF 0 "register_operand" "")
13208 (unspec:XF [(float_extend:XF
13209 (match_operand:MODEF 2 "register_operand" ""))]
13210 UNSPEC_SINCOS_COS))
13211 (set (match_operand:XF 1 "register_operand" "")
13212 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13213 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13214 && !(reload_completed || reload_in_progress)"
13215 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13216 "")
13217
13218 (define_expand "sincos<mode>3"
13219 [(use (match_operand:MODEF 0 "register_operand" ""))
13220 (use (match_operand:MODEF 1 "register_operand" ""))
13221 (use (match_operand:MODEF 2 "register_operand" ""))]
13222 "TARGET_USE_FANCY_MATH_387
13223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13224 || TARGET_MIX_SSE_I387)
13225 && flag_unsafe_math_optimizations"
13226 {
13227 rtx op0 = gen_reg_rtx (XFmode);
13228 rtx op1 = gen_reg_rtx (XFmode);
13229
13230 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13231 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13233 DONE;
13234 })
13235
13236 (define_insn "fptanxf4_i387"
13237 [(set (match_operand:XF 0 "register_operand" "=f")
13238 (match_operand:XF 3 "const_double_operand" "F"))
13239 (set (match_operand:XF 1 "register_operand" "=u")
13240 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13241 UNSPEC_TAN))]
13242 "TARGET_USE_FANCY_MATH_387
13243 && flag_unsafe_math_optimizations
13244 && standard_80387_constant_p (operands[3]) == 2"
13245 "fptan"
13246 [(set_attr "type" "fpspc")
13247 (set_attr "mode" "XF")])
13248
13249 (define_insn "fptan_extend<mode>xf4_i387"
13250 [(set (match_operand:MODEF 0 "register_operand" "=f")
13251 (match_operand:MODEF 3 "const_double_operand" "F"))
13252 (set (match_operand:XF 1 "register_operand" "=u")
13253 (unspec:XF [(float_extend:XF
13254 (match_operand:MODEF 2 "register_operand" "0"))]
13255 UNSPEC_TAN))]
13256 "TARGET_USE_FANCY_MATH_387
13257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13258 || TARGET_MIX_SSE_I387)
13259 && flag_unsafe_math_optimizations
13260 && standard_80387_constant_p (operands[3]) == 2"
13261 "fptan"
13262 [(set_attr "type" "fpspc")
13263 (set_attr "mode" "XF")])
13264
13265 (define_expand "tanxf2"
13266 [(use (match_operand:XF 0 "register_operand" ""))
13267 (use (match_operand:XF 1 "register_operand" ""))]
13268 "TARGET_USE_FANCY_MATH_387
13269 && flag_unsafe_math_optimizations"
13270 {
13271 rtx one = gen_reg_rtx (XFmode);
13272 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13273
13274 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13275 DONE;
13276 })
13277
13278 (define_expand "tan<mode>2"
13279 [(use (match_operand:MODEF 0 "register_operand" ""))
13280 (use (match_operand:MODEF 1 "register_operand" ""))]
13281 "TARGET_USE_FANCY_MATH_387
13282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13283 || TARGET_MIX_SSE_I387)
13284 && flag_unsafe_math_optimizations"
13285 {
13286 rtx op0 = gen_reg_rtx (XFmode);
13287
13288 rtx one = gen_reg_rtx (<MODE>mode);
13289 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13290
13291 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13292 operands[1], op2));
13293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13294 DONE;
13295 })
13296
13297 (define_insn "*fpatanxf3_i387"
13298 [(set (match_operand:XF 0 "register_operand" "=f")
13299 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13300 (match_operand:XF 2 "register_operand" "u")]
13301 UNSPEC_FPATAN))
13302 (clobber (match_scratch:XF 3 "=2"))]
13303 "TARGET_USE_FANCY_MATH_387
13304 && flag_unsafe_math_optimizations"
13305 "fpatan"
13306 [(set_attr "type" "fpspc")
13307 (set_attr "mode" "XF")])
13308
13309 (define_insn "fpatan_extend<mode>xf3_i387"
13310 [(set (match_operand:XF 0 "register_operand" "=f")
13311 (unspec:XF [(float_extend:XF
13312 (match_operand:MODEF 1 "register_operand" "0"))
13313 (float_extend:XF
13314 (match_operand:MODEF 2 "register_operand" "u"))]
13315 UNSPEC_FPATAN))
13316 (clobber (match_scratch:XF 3 "=2"))]
13317 "TARGET_USE_FANCY_MATH_387
13318 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13319 || TARGET_MIX_SSE_I387)
13320 && flag_unsafe_math_optimizations"
13321 "fpatan"
13322 [(set_attr "type" "fpspc")
13323 (set_attr "mode" "XF")])
13324
13325 (define_expand "atan2xf3"
13326 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13327 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13328 (match_operand:XF 1 "register_operand" "")]
13329 UNSPEC_FPATAN))
13330 (clobber (match_scratch:XF 3 ""))])]
13331 "TARGET_USE_FANCY_MATH_387
13332 && flag_unsafe_math_optimizations"
13333 "")
13334
13335 (define_expand "atan2<mode>3"
13336 [(use (match_operand:MODEF 0 "register_operand" ""))
13337 (use (match_operand:MODEF 1 "register_operand" ""))
13338 (use (match_operand:MODEF 2 "register_operand" ""))]
13339 "TARGET_USE_FANCY_MATH_387
13340 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13341 || TARGET_MIX_SSE_I387)
13342 && flag_unsafe_math_optimizations"
13343 {
13344 rtx op0 = gen_reg_rtx (XFmode);
13345
13346 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13348 DONE;
13349 })
13350
13351 (define_expand "atanxf2"
13352 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13353 (unspec:XF [(match_dup 2)
13354 (match_operand:XF 1 "register_operand" "")]
13355 UNSPEC_FPATAN))
13356 (clobber (match_scratch:XF 3 ""))])]
13357 "TARGET_USE_FANCY_MATH_387
13358 && flag_unsafe_math_optimizations"
13359 {
13360 operands[2] = gen_reg_rtx (XFmode);
13361 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13362 })
13363
13364 (define_expand "atan<mode>2"
13365 [(use (match_operand:MODEF 0 "register_operand" ""))
13366 (use (match_operand:MODEF 1 "register_operand" ""))]
13367 "TARGET_USE_FANCY_MATH_387
13368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13369 || TARGET_MIX_SSE_I387)
13370 && flag_unsafe_math_optimizations"
13371 {
13372 rtx op0 = gen_reg_rtx (XFmode);
13373
13374 rtx op2 = gen_reg_rtx (<MODE>mode);
13375 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13376
13377 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13379 DONE;
13380 })
13381
13382 (define_expand "asinxf2"
13383 [(set (match_dup 2)
13384 (mult:XF (match_operand:XF 1 "register_operand" "")
13385 (match_dup 1)))
13386 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13387 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13388 (parallel [(set (match_operand:XF 0 "register_operand" "")
13389 (unspec:XF [(match_dup 5) (match_dup 1)]
13390 UNSPEC_FPATAN))
13391 (clobber (match_scratch:XF 6 ""))])]
13392 "TARGET_USE_FANCY_MATH_387
13393 && flag_unsafe_math_optimizations"
13394 {
13395 int i;
13396
13397 if (optimize_insn_for_size_p ())
13398 FAIL;
13399
13400 for (i = 2; i < 6; i++)
13401 operands[i] = gen_reg_rtx (XFmode);
13402
13403 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13404 })
13405
13406 (define_expand "asin<mode>2"
13407 [(use (match_operand:MODEF 0 "register_operand" ""))
13408 (use (match_operand:MODEF 1 "general_operand" ""))]
13409 "TARGET_USE_FANCY_MATH_387
13410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13411 || TARGET_MIX_SSE_I387)
13412 && flag_unsafe_math_optimizations"
13413 {
13414 rtx op0 = gen_reg_rtx (XFmode);
13415 rtx op1 = gen_reg_rtx (XFmode);
13416
13417 if (optimize_insn_for_size_p ())
13418 FAIL;
13419
13420 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13421 emit_insn (gen_asinxf2 (op0, op1));
13422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13423 DONE;
13424 })
13425
13426 (define_expand "acosxf2"
13427 [(set (match_dup 2)
13428 (mult:XF (match_operand:XF 1 "register_operand" "")
13429 (match_dup 1)))
13430 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13431 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13432 (parallel [(set (match_operand:XF 0 "register_operand" "")
13433 (unspec:XF [(match_dup 1) (match_dup 5)]
13434 UNSPEC_FPATAN))
13435 (clobber (match_scratch:XF 6 ""))])]
13436 "TARGET_USE_FANCY_MATH_387
13437 && flag_unsafe_math_optimizations"
13438 {
13439 int i;
13440
13441 if (optimize_insn_for_size_p ())
13442 FAIL;
13443
13444 for (i = 2; i < 6; i++)
13445 operands[i] = gen_reg_rtx (XFmode);
13446
13447 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13448 })
13449
13450 (define_expand "acos<mode>2"
13451 [(use (match_operand:MODEF 0 "register_operand" ""))
13452 (use (match_operand:MODEF 1 "general_operand" ""))]
13453 "TARGET_USE_FANCY_MATH_387
13454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13455 || TARGET_MIX_SSE_I387)
13456 && flag_unsafe_math_optimizations"
13457 {
13458 rtx op0 = gen_reg_rtx (XFmode);
13459 rtx op1 = gen_reg_rtx (XFmode);
13460
13461 if (optimize_insn_for_size_p ())
13462 FAIL;
13463
13464 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13465 emit_insn (gen_acosxf2 (op0, op1));
13466 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13467 DONE;
13468 })
13469
13470 (define_insn "fyl2xxf3_i387"
13471 [(set (match_operand:XF 0 "register_operand" "=f")
13472 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13473 (match_operand:XF 2 "register_operand" "u")]
13474 UNSPEC_FYL2X))
13475 (clobber (match_scratch:XF 3 "=2"))]
13476 "TARGET_USE_FANCY_MATH_387
13477 && flag_unsafe_math_optimizations"
13478 "fyl2x"
13479 [(set_attr "type" "fpspc")
13480 (set_attr "mode" "XF")])
13481
13482 (define_insn "fyl2x_extend<mode>xf3_i387"
13483 [(set (match_operand:XF 0 "register_operand" "=f")
13484 (unspec:XF [(float_extend:XF
13485 (match_operand:MODEF 1 "register_operand" "0"))
13486 (match_operand:XF 2 "register_operand" "u")]
13487 UNSPEC_FYL2X))
13488 (clobber (match_scratch:XF 3 "=2"))]
13489 "TARGET_USE_FANCY_MATH_387
13490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13491 || TARGET_MIX_SSE_I387)
13492 && flag_unsafe_math_optimizations"
13493 "fyl2x"
13494 [(set_attr "type" "fpspc")
13495 (set_attr "mode" "XF")])
13496
13497 (define_expand "logxf2"
13498 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13499 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13500 (match_dup 2)] UNSPEC_FYL2X))
13501 (clobber (match_scratch:XF 3 ""))])]
13502 "TARGET_USE_FANCY_MATH_387
13503 && flag_unsafe_math_optimizations"
13504 {
13505 operands[2] = gen_reg_rtx (XFmode);
13506 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13507 })
13508
13509 (define_expand "log<mode>2"
13510 [(use (match_operand:MODEF 0 "register_operand" ""))
13511 (use (match_operand:MODEF 1 "register_operand" ""))]
13512 "TARGET_USE_FANCY_MATH_387
13513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13514 || TARGET_MIX_SSE_I387)
13515 && flag_unsafe_math_optimizations"
13516 {
13517 rtx op0 = gen_reg_rtx (XFmode);
13518
13519 rtx op2 = gen_reg_rtx (XFmode);
13520 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13521
13522 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13524 DONE;
13525 })
13526
13527 (define_expand "log10xf2"
13528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13530 (match_dup 2)] UNSPEC_FYL2X))
13531 (clobber (match_scratch:XF 3 ""))])]
13532 "TARGET_USE_FANCY_MATH_387
13533 && flag_unsafe_math_optimizations"
13534 {
13535 operands[2] = gen_reg_rtx (XFmode);
13536 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13537 })
13538
13539 (define_expand "log10<mode>2"
13540 [(use (match_operand:MODEF 0 "register_operand" ""))
13541 (use (match_operand:MODEF 1 "register_operand" ""))]
13542 "TARGET_USE_FANCY_MATH_387
13543 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13544 || TARGET_MIX_SSE_I387)
13545 && flag_unsafe_math_optimizations"
13546 {
13547 rtx op0 = gen_reg_rtx (XFmode);
13548
13549 rtx op2 = gen_reg_rtx (XFmode);
13550 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13551
13552 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13553 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13554 DONE;
13555 })
13556
13557 (define_expand "log2xf2"
13558 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13559 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13560 (match_dup 2)] UNSPEC_FYL2X))
13561 (clobber (match_scratch:XF 3 ""))])]
13562 "TARGET_USE_FANCY_MATH_387
13563 && flag_unsafe_math_optimizations"
13564 {
13565 operands[2] = gen_reg_rtx (XFmode);
13566 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13567 })
13568
13569 (define_expand "log2<mode>2"
13570 [(use (match_operand:MODEF 0 "register_operand" ""))
13571 (use (match_operand:MODEF 1 "register_operand" ""))]
13572 "TARGET_USE_FANCY_MATH_387
13573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13574 || TARGET_MIX_SSE_I387)
13575 && flag_unsafe_math_optimizations"
13576 {
13577 rtx op0 = gen_reg_rtx (XFmode);
13578
13579 rtx op2 = gen_reg_rtx (XFmode);
13580 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13581
13582 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13584 DONE;
13585 })
13586
13587 (define_insn "fyl2xp1xf3_i387"
13588 [(set (match_operand:XF 0 "register_operand" "=f")
13589 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13590 (match_operand:XF 2 "register_operand" "u")]
13591 UNSPEC_FYL2XP1))
13592 (clobber (match_scratch:XF 3 "=2"))]
13593 "TARGET_USE_FANCY_MATH_387
13594 && flag_unsafe_math_optimizations"
13595 "fyl2xp1"
13596 [(set_attr "type" "fpspc")
13597 (set_attr "mode" "XF")])
13598
13599 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13600 [(set (match_operand:XF 0 "register_operand" "=f")
13601 (unspec:XF [(float_extend:XF
13602 (match_operand:MODEF 1 "register_operand" "0"))
13603 (match_operand:XF 2 "register_operand" "u")]
13604 UNSPEC_FYL2XP1))
13605 (clobber (match_scratch:XF 3 "=2"))]
13606 "TARGET_USE_FANCY_MATH_387
13607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13608 || TARGET_MIX_SSE_I387)
13609 && flag_unsafe_math_optimizations"
13610 "fyl2xp1"
13611 [(set_attr "type" "fpspc")
13612 (set_attr "mode" "XF")])
13613
13614 (define_expand "log1pxf2"
13615 [(use (match_operand:XF 0 "register_operand" ""))
13616 (use (match_operand:XF 1 "register_operand" ""))]
13617 "TARGET_USE_FANCY_MATH_387
13618 && flag_unsafe_math_optimizations"
13619 {
13620 if (optimize_insn_for_size_p ())
13621 FAIL;
13622
13623 ix86_emit_i387_log1p (operands[0], operands[1]);
13624 DONE;
13625 })
13626
13627 (define_expand "log1p<mode>2"
13628 [(use (match_operand:MODEF 0 "register_operand" ""))
13629 (use (match_operand:MODEF 1 "register_operand" ""))]
13630 "TARGET_USE_FANCY_MATH_387
13631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13632 || TARGET_MIX_SSE_I387)
13633 && flag_unsafe_math_optimizations"
13634 {
13635 rtx op0;
13636
13637 if (optimize_insn_for_size_p ())
13638 FAIL;
13639
13640 op0 = gen_reg_rtx (XFmode);
13641
13642 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13643
13644 ix86_emit_i387_log1p (op0, operands[1]);
13645 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13646 DONE;
13647 })
13648
13649 (define_insn "fxtractxf3_i387"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13652 UNSPEC_XTRACT_FRACT))
13653 (set (match_operand:XF 1 "register_operand" "=u")
13654 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13655 "TARGET_USE_FANCY_MATH_387
13656 && flag_unsafe_math_optimizations"
13657 "fxtract"
13658 [(set_attr "type" "fpspc")
13659 (set_attr "mode" "XF")])
13660
13661 (define_insn "fxtract_extend<mode>xf3_i387"
13662 [(set (match_operand:XF 0 "register_operand" "=f")
13663 (unspec:XF [(float_extend:XF
13664 (match_operand:MODEF 2 "register_operand" "0"))]
13665 UNSPEC_XTRACT_FRACT))
13666 (set (match_operand:XF 1 "register_operand" "=u")
13667 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13668 "TARGET_USE_FANCY_MATH_387
13669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13670 || TARGET_MIX_SSE_I387)
13671 && flag_unsafe_math_optimizations"
13672 "fxtract"
13673 [(set_attr "type" "fpspc")
13674 (set_attr "mode" "XF")])
13675
13676 (define_expand "logbxf2"
13677 [(parallel [(set (match_dup 2)
13678 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13679 UNSPEC_XTRACT_FRACT))
13680 (set (match_operand:XF 0 "register_operand" "")
13681 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13682 "TARGET_USE_FANCY_MATH_387
13683 && flag_unsafe_math_optimizations"
13684 {
13685 operands[2] = gen_reg_rtx (XFmode);
13686 })
13687
13688 (define_expand "logb<mode>2"
13689 [(use (match_operand:MODEF 0 "register_operand" ""))
13690 (use (match_operand:MODEF 1 "register_operand" ""))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13695 {
13696 rtx op0 = gen_reg_rtx (XFmode);
13697 rtx op1 = gen_reg_rtx (XFmode);
13698
13699 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13700 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13701 DONE;
13702 })
13703
13704 (define_expand "ilogbxf2"
13705 [(use (match_operand:SI 0 "register_operand" ""))
13706 (use (match_operand:XF 1 "register_operand" ""))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && flag_unsafe_math_optimizations"
13709 {
13710 rtx op0, op1;
13711
13712 if (optimize_insn_for_size_p ())
13713 FAIL;
13714
13715 op0 = gen_reg_rtx (XFmode);
13716 op1 = gen_reg_rtx (XFmode);
13717
13718 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13719 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13720 DONE;
13721 })
13722
13723 (define_expand "ilogb<mode>2"
13724 [(use (match_operand:SI 0 "register_operand" ""))
13725 (use (match_operand:MODEF 1 "register_operand" ""))]
13726 "TARGET_USE_FANCY_MATH_387
13727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13728 || TARGET_MIX_SSE_I387)
13729 && flag_unsafe_math_optimizations"
13730 {
13731 rtx op0, op1;
13732
13733 if (optimize_insn_for_size_p ())
13734 FAIL;
13735
13736 op0 = gen_reg_rtx (XFmode);
13737 op1 = gen_reg_rtx (XFmode);
13738
13739 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13740 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13741 DONE;
13742 })
13743
13744 (define_insn "*f2xm1xf2_i387"
13745 [(set (match_operand:XF 0 "register_operand" "=f")
13746 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13747 UNSPEC_F2XM1))]
13748 "TARGET_USE_FANCY_MATH_387
13749 && flag_unsafe_math_optimizations"
13750 "f2xm1"
13751 [(set_attr "type" "fpspc")
13752 (set_attr "mode" "XF")])
13753
13754 (define_insn "*fscalexf4_i387"
13755 [(set (match_operand:XF 0 "register_operand" "=f")
13756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13757 (match_operand:XF 3 "register_operand" "1")]
13758 UNSPEC_FSCALE_FRACT))
13759 (set (match_operand:XF 1 "register_operand" "=u")
13760 (unspec:XF [(match_dup 2) (match_dup 3)]
13761 UNSPEC_FSCALE_EXP))]
13762 "TARGET_USE_FANCY_MATH_387
13763 && flag_unsafe_math_optimizations"
13764 "fscale"
13765 [(set_attr "type" "fpspc")
13766 (set_attr "mode" "XF")])
13767
13768 (define_expand "expNcorexf3"
13769 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13770 (match_operand:XF 2 "register_operand" "")))
13771 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13772 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13773 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13774 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13775 (parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_dup 8) (match_dup 4)]
13777 UNSPEC_FSCALE_FRACT))
13778 (set (match_dup 9)
13779 (unspec:XF [(match_dup 8) (match_dup 4)]
13780 UNSPEC_FSCALE_EXP))])]
13781 "TARGET_USE_FANCY_MATH_387
13782 && flag_unsafe_math_optimizations"
13783 {
13784 int i;
13785
13786 if (optimize_insn_for_size_p ())
13787 FAIL;
13788
13789 for (i = 3; i < 10; i++)
13790 operands[i] = gen_reg_rtx (XFmode);
13791
13792 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13793 })
13794
13795 (define_expand "expxf2"
13796 [(use (match_operand:XF 0 "register_operand" ""))
13797 (use (match_operand:XF 1 "register_operand" ""))]
13798 "TARGET_USE_FANCY_MATH_387
13799 && flag_unsafe_math_optimizations"
13800 {
13801 rtx op2;
13802
13803 if (optimize_insn_for_size_p ())
13804 FAIL;
13805
13806 op2 = gen_reg_rtx (XFmode);
13807 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13808
13809 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13810 DONE;
13811 })
13812
13813 (define_expand "exp<mode>2"
13814 [(use (match_operand:MODEF 0 "register_operand" ""))
13815 (use (match_operand:MODEF 1 "general_operand" ""))]
13816 "TARGET_USE_FANCY_MATH_387
13817 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13818 || TARGET_MIX_SSE_I387)
13819 && flag_unsafe_math_optimizations"
13820 {
13821 rtx op0, op1;
13822
13823 if (optimize_insn_for_size_p ())
13824 FAIL;
13825
13826 op0 = gen_reg_rtx (XFmode);
13827 op1 = gen_reg_rtx (XFmode);
13828
13829 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13830 emit_insn (gen_expxf2 (op0, op1));
13831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13832 DONE;
13833 })
13834
13835 (define_expand "exp10xf2"
13836 [(use (match_operand:XF 0 "register_operand" ""))
13837 (use (match_operand:XF 1 "register_operand" ""))]
13838 "TARGET_USE_FANCY_MATH_387
13839 && flag_unsafe_math_optimizations"
13840 {
13841 rtx op2;
13842
13843 if (optimize_insn_for_size_p ())
13844 FAIL;
13845
13846 op2 = gen_reg_rtx (XFmode);
13847 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13848
13849 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13850 DONE;
13851 })
13852
13853 (define_expand "exp10<mode>2"
13854 [(use (match_operand:MODEF 0 "register_operand" ""))
13855 (use (match_operand:MODEF 1 "general_operand" ""))]
13856 "TARGET_USE_FANCY_MATH_387
13857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13858 || TARGET_MIX_SSE_I387)
13859 && flag_unsafe_math_optimizations"
13860 {
13861 rtx op0, op1;
13862
13863 if (optimize_insn_for_size_p ())
13864 FAIL;
13865
13866 op0 = gen_reg_rtx (XFmode);
13867 op1 = gen_reg_rtx (XFmode);
13868
13869 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13870 emit_insn (gen_exp10xf2 (op0, op1));
13871 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13872 DONE;
13873 })
13874
13875 (define_expand "exp2xf2"
13876 [(use (match_operand:XF 0 "register_operand" ""))
13877 (use (match_operand:XF 1 "register_operand" ""))]
13878 "TARGET_USE_FANCY_MATH_387
13879 && flag_unsafe_math_optimizations"
13880 {
13881 rtx op2;
13882
13883 if (optimize_insn_for_size_p ())
13884 FAIL;
13885
13886 op2 = gen_reg_rtx (XFmode);
13887 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13888
13889 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13890 DONE;
13891 })
13892
13893 (define_expand "exp2<mode>2"
13894 [(use (match_operand:MODEF 0 "register_operand" ""))
13895 (use (match_operand:MODEF 1 "general_operand" ""))]
13896 "TARGET_USE_FANCY_MATH_387
13897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13898 || TARGET_MIX_SSE_I387)
13899 && flag_unsafe_math_optimizations"
13900 {
13901 rtx op0, op1;
13902
13903 if (optimize_insn_for_size_p ())
13904 FAIL;
13905
13906 op0 = gen_reg_rtx (XFmode);
13907 op1 = gen_reg_rtx (XFmode);
13908
13909 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13910 emit_insn (gen_exp2xf2 (op0, op1));
13911 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13912 DONE;
13913 })
13914
13915 (define_expand "expm1xf2"
13916 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13917 (match_dup 2)))
13918 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13919 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13920 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13921 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13922 (parallel [(set (match_dup 7)
13923 (unspec:XF [(match_dup 6) (match_dup 4)]
13924 UNSPEC_FSCALE_FRACT))
13925 (set (match_dup 8)
13926 (unspec:XF [(match_dup 6) (match_dup 4)]
13927 UNSPEC_FSCALE_EXP))])
13928 (parallel [(set (match_dup 10)
13929 (unspec:XF [(match_dup 9) (match_dup 8)]
13930 UNSPEC_FSCALE_FRACT))
13931 (set (match_dup 11)
13932 (unspec:XF [(match_dup 9) (match_dup 8)]
13933 UNSPEC_FSCALE_EXP))])
13934 (set (match_dup 12) (minus:XF (match_dup 10)
13935 (float_extend:XF (match_dup 13))))
13936 (set (match_operand:XF 0 "register_operand" "")
13937 (plus:XF (match_dup 12) (match_dup 7)))]
13938 "TARGET_USE_FANCY_MATH_387
13939 && flag_unsafe_math_optimizations"
13940 {
13941 int i;
13942
13943 if (optimize_insn_for_size_p ())
13944 FAIL;
13945
13946 for (i = 2; i < 13; i++)
13947 operands[i] = gen_reg_rtx (XFmode);
13948
13949 operands[13]
13950 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13951
13952 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13953 })
13954
13955 (define_expand "expm1<mode>2"
13956 [(use (match_operand:MODEF 0 "register_operand" ""))
13957 (use (match_operand:MODEF 1 "general_operand" ""))]
13958 "TARGET_USE_FANCY_MATH_387
13959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13960 || TARGET_MIX_SSE_I387)
13961 && flag_unsafe_math_optimizations"
13962 {
13963 rtx op0, op1;
13964
13965 if (optimize_insn_for_size_p ())
13966 FAIL;
13967
13968 op0 = gen_reg_rtx (XFmode);
13969 op1 = gen_reg_rtx (XFmode);
13970
13971 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13972 emit_insn (gen_expm1xf2 (op0, op1));
13973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13974 DONE;
13975 })
13976
13977 (define_expand "ldexpxf3"
13978 [(set (match_dup 3)
13979 (float:XF (match_operand:SI 2 "register_operand" "")))
13980 (parallel [(set (match_operand:XF 0 " register_operand" "")
13981 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13982 (match_dup 3)]
13983 UNSPEC_FSCALE_FRACT))
13984 (set (match_dup 4)
13985 (unspec:XF [(match_dup 1) (match_dup 3)]
13986 UNSPEC_FSCALE_EXP))])]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13989 {
13990 if (optimize_insn_for_size_p ())
13991 FAIL;
13992
13993 operands[3] = gen_reg_rtx (XFmode);
13994 operands[4] = gen_reg_rtx (XFmode);
13995 })
13996
13997 (define_expand "ldexp<mode>3"
13998 [(use (match_operand:MODEF 0 "register_operand" ""))
13999 (use (match_operand:MODEF 1 "general_operand" ""))
14000 (use (match_operand:SI 2 "register_operand" ""))]
14001 "TARGET_USE_FANCY_MATH_387
14002 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14003 || TARGET_MIX_SSE_I387)
14004 && flag_unsafe_math_optimizations"
14005 {
14006 rtx op0, op1;
14007
14008 if (optimize_insn_for_size_p ())
14009 FAIL;
14010
14011 op0 = gen_reg_rtx (XFmode);
14012 op1 = gen_reg_rtx (XFmode);
14013
14014 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14015 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14016 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14017 DONE;
14018 })
14019
14020 (define_expand "scalbxf3"
14021 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14022 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14023 (match_operand:XF 2 "register_operand" "")]
14024 UNSPEC_FSCALE_FRACT))
14025 (set (match_dup 3)
14026 (unspec:XF [(match_dup 1) (match_dup 2)]
14027 UNSPEC_FSCALE_EXP))])]
14028 "TARGET_USE_FANCY_MATH_387
14029 && flag_unsafe_math_optimizations"
14030 {
14031 if (optimize_insn_for_size_p ())
14032 FAIL;
14033
14034 operands[3] = gen_reg_rtx (XFmode);
14035 })
14036
14037 (define_expand "scalb<mode>3"
14038 [(use (match_operand:MODEF 0 "register_operand" ""))
14039 (use (match_operand:MODEF 1 "general_operand" ""))
14040 (use (match_operand:MODEF 2 "general_operand" ""))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043 || TARGET_MIX_SSE_I387)
14044 && flag_unsafe_math_optimizations"
14045 {
14046 rtx op0, op1, op2;
14047
14048 if (optimize_insn_for_size_p ())
14049 FAIL;
14050
14051 op0 = gen_reg_rtx (XFmode);
14052 op1 = gen_reg_rtx (XFmode);
14053 op2 = gen_reg_rtx (XFmode);
14054
14055 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14057 emit_insn (gen_scalbxf3 (op0, op1, op2));
14058 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14059 DONE;
14060 })
14061
14062 (define_expand "significandxf2"
14063 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14064 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14065 UNSPEC_XTRACT_FRACT))
14066 (set (match_dup 2)
14067 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14068 "TARGET_USE_FANCY_MATH_387
14069 && flag_unsafe_math_optimizations"
14070 {
14071 operands[2] = gen_reg_rtx (XFmode);
14072 })
14073
14074 (define_expand "significand<mode>2"
14075 [(use (match_operand:MODEF 0 "register_operand" ""))
14076 (use (match_operand:MODEF 1 "register_operand" ""))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14079 || TARGET_MIX_SSE_I387)
14080 && flag_unsafe_math_optimizations"
14081 {
14082 rtx op0 = gen_reg_rtx (XFmode);
14083 rtx op1 = gen_reg_rtx (XFmode);
14084
14085 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14086 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14087 DONE;
14088 })
14089 \f
14090
14091 (define_insn "sse4_1_round<mode>2"
14092 [(set (match_operand:MODEF 0 "register_operand" "=x")
14093 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14094 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14095 UNSPEC_ROUND))]
14096 "TARGET_ROUND"
14097 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14098 [(set_attr "type" "ssecvt")
14099 (set_attr "prefix_extra" "1")
14100 (set_attr "prefix" "maybe_vex")
14101 (set_attr "mode" "<MODE>")])
14102
14103 (define_insn "rintxf2"
14104 [(set (match_operand:XF 0 "register_operand" "=f")
14105 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14106 UNSPEC_FRNDINT))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && flag_unsafe_math_optimizations"
14109 "frndint"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14112
14113 (define_expand "rint<mode>2"
14114 [(use (match_operand:MODEF 0 "register_operand" ""))
14115 (use (match_operand:MODEF 1 "register_operand" ""))]
14116 "(TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations)
14120 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14121 && !flag_trapping_math)"
14122 {
14123 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14124 && !flag_trapping_math)
14125 {
14126 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14127 FAIL;
14128 if (TARGET_ROUND)
14129 emit_insn (gen_sse4_1_round<mode>2
14130 (operands[0], operands[1], GEN_INT (0x04)));
14131 else
14132 ix86_expand_rint (operand0, operand1);
14133 }
14134 else
14135 {
14136 rtx op0 = gen_reg_rtx (XFmode);
14137 rtx op1 = gen_reg_rtx (XFmode);
14138
14139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14140 emit_insn (gen_rintxf2 (op0, op1));
14141
14142 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14143 }
14144 DONE;
14145 })
14146
14147 (define_expand "round<mode>2"
14148 [(match_operand:MODEF 0 "register_operand" "")
14149 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14150 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14151 && !flag_trapping_math && !flag_rounding_math"
14152 {
14153 if (optimize_insn_for_size_p ())
14154 FAIL;
14155 if (TARGET_64BIT || (<MODE>mode != DFmode))
14156 ix86_expand_round (operand0, operand1);
14157 else
14158 ix86_expand_rounddf_32 (operand0, operand1);
14159 DONE;
14160 })
14161
14162 (define_insn_and_split "*fistdi2_1"
14163 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14164 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14165 UNSPEC_FIST))]
14166 "TARGET_USE_FANCY_MATH_387
14167 && can_create_pseudo_p ()"
14168 "#"
14169 "&& 1"
14170 [(const_int 0)]
14171 {
14172 if (memory_operand (operands[0], VOIDmode))
14173 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14174 else
14175 {
14176 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14177 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14178 operands[2]));
14179 }
14180 DONE;
14181 }
14182 [(set_attr "type" "fpspc")
14183 (set_attr "mode" "DI")])
14184
14185 (define_insn "fistdi2"
14186 [(set (match_operand:DI 0 "memory_operand" "=m")
14187 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14188 UNSPEC_FIST))
14189 (clobber (match_scratch:XF 2 "=&1f"))]
14190 "TARGET_USE_FANCY_MATH_387"
14191 "* return output_fix_trunc (insn, operands, 0);"
14192 [(set_attr "type" "fpspc")
14193 (set_attr "mode" "DI")])
14194
14195 (define_insn "fistdi2_with_temp"
14196 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14197 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14198 UNSPEC_FIST))
14199 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14200 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14201 "TARGET_USE_FANCY_MATH_387"
14202 "#"
14203 [(set_attr "type" "fpspc")
14204 (set_attr "mode" "DI")])
14205
14206 (define_split
14207 [(set (match_operand:DI 0 "register_operand" "")
14208 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14209 UNSPEC_FIST))
14210 (clobber (match_operand:DI 2 "memory_operand" ""))
14211 (clobber (match_scratch 3 ""))]
14212 "reload_completed"
14213 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14214 (clobber (match_dup 3))])
14215 (set (match_dup 0) (match_dup 2))]
14216 "")
14217
14218 (define_split
14219 [(set (match_operand:DI 0 "memory_operand" "")
14220 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14221 UNSPEC_FIST))
14222 (clobber (match_operand:DI 2 "memory_operand" ""))
14223 (clobber (match_scratch 3 ""))]
14224 "reload_completed"
14225 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14226 (clobber (match_dup 3))])]
14227 "")
14228
14229 (define_insn_and_split "*fist<mode>2_1"
14230 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14231 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14232 UNSPEC_FIST))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && can_create_pseudo_p ()"
14235 "#"
14236 "&& 1"
14237 [(const_int 0)]
14238 {
14239 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14240 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14241 operands[2]));
14242 DONE;
14243 }
14244 [(set_attr "type" "fpspc")
14245 (set_attr "mode" "<MODE>")])
14246
14247 (define_insn "fist<mode>2"
14248 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14249 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14250 UNSPEC_FIST))]
14251 "TARGET_USE_FANCY_MATH_387"
14252 "* return output_fix_trunc (insn, operands, 0);"
14253 [(set_attr "type" "fpspc")
14254 (set_attr "mode" "<MODE>")])
14255
14256 (define_insn "fist<mode>2_with_temp"
14257 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14258 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14259 UNSPEC_FIST))
14260 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14261 "TARGET_USE_FANCY_MATH_387"
14262 "#"
14263 [(set_attr "type" "fpspc")
14264 (set_attr "mode" "<MODE>")])
14265
14266 (define_split
14267 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14268 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14269 UNSPEC_FIST))
14270 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14271 "reload_completed"
14272 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14273 (set (match_dup 0) (match_dup 2))]
14274 "")
14275
14276 (define_split
14277 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14278 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14279 UNSPEC_FIST))
14280 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14281 "reload_completed"
14282 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14283 "")
14284
14285 (define_expand "lrintxf<mode>2"
14286 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14287 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14288 UNSPEC_FIST))]
14289 "TARGET_USE_FANCY_MATH_387"
14290 "")
14291
14292 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14293 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14294 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14295 UNSPEC_FIX_NOTRUNC))]
14296 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14297 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14298 "")
14299
14300 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14301 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14302 (match_operand:MODEF 1 "register_operand" "")]
14303 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14304 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14305 && !flag_trapping_math && !flag_rounding_math"
14306 {
14307 if (optimize_insn_for_size_p ())
14308 FAIL;
14309 ix86_expand_lround (operand0, operand1);
14310 DONE;
14311 })
14312
14313 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14314 (define_insn_and_split "frndintxf2_floor"
14315 [(set (match_operand:XF 0 "register_operand" "")
14316 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14317 UNSPEC_FRNDINT_FLOOR))
14318 (clobber (reg:CC FLAGS_REG))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && flag_unsafe_math_optimizations
14321 && can_create_pseudo_p ()"
14322 "#"
14323 "&& 1"
14324 [(const_int 0)]
14325 {
14326 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14327
14328 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14329 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14330
14331 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14332 operands[2], operands[3]));
14333 DONE;
14334 }
14335 [(set_attr "type" "frndint")
14336 (set_attr "i387_cw" "floor")
14337 (set_attr "mode" "XF")])
14338
14339 (define_insn "frndintxf2_floor_i387"
14340 [(set (match_operand:XF 0 "register_operand" "=f")
14341 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14342 UNSPEC_FRNDINT_FLOOR))
14343 (use (match_operand:HI 2 "memory_operand" "m"))
14344 (use (match_operand:HI 3 "memory_operand" "m"))]
14345 "TARGET_USE_FANCY_MATH_387
14346 && flag_unsafe_math_optimizations"
14347 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14348 [(set_attr "type" "frndint")
14349 (set_attr "i387_cw" "floor")
14350 (set_attr "mode" "XF")])
14351
14352 (define_expand "floorxf2"
14353 [(use (match_operand:XF 0 "register_operand" ""))
14354 (use (match_operand:XF 1 "register_operand" ""))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && flag_unsafe_math_optimizations"
14357 {
14358 if (optimize_insn_for_size_p ())
14359 FAIL;
14360 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14361 DONE;
14362 })
14363
14364 (define_expand "floor<mode>2"
14365 [(use (match_operand:MODEF 0 "register_operand" ""))
14366 (use (match_operand:MODEF 1 "register_operand" ""))]
14367 "(TARGET_USE_FANCY_MATH_387
14368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14369 || TARGET_MIX_SSE_I387)
14370 && flag_unsafe_math_optimizations)
14371 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14372 && !flag_trapping_math)"
14373 {
14374 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14375 && !flag_trapping_math
14376 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14377 {
14378 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14379 FAIL;
14380 if (TARGET_ROUND)
14381 emit_insn (gen_sse4_1_round<mode>2
14382 (operands[0], operands[1], GEN_INT (0x01)));
14383 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14384 ix86_expand_floorceil (operand0, operand1, true);
14385 else
14386 ix86_expand_floorceildf_32 (operand0, operand1, true);
14387 }
14388 else
14389 {
14390 rtx op0, op1;
14391
14392 if (optimize_insn_for_size_p ())
14393 FAIL;
14394
14395 op0 = gen_reg_rtx (XFmode);
14396 op1 = gen_reg_rtx (XFmode);
14397 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14398 emit_insn (gen_frndintxf2_floor (op0, op1));
14399
14400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 }
14402 DONE;
14403 })
14404
14405 (define_insn_and_split "*fist<mode>2_floor_1"
14406 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14407 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14408 UNSPEC_FIST_FLOOR))
14409 (clobber (reg:CC FLAGS_REG))]
14410 "TARGET_USE_FANCY_MATH_387
14411 && flag_unsafe_math_optimizations
14412 && can_create_pseudo_p ()"
14413 "#"
14414 "&& 1"
14415 [(const_int 0)]
14416 {
14417 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14418
14419 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14420 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14421 if (memory_operand (operands[0], VOIDmode))
14422 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14423 operands[2], operands[3]));
14424 else
14425 {
14426 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14427 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14428 operands[2], operands[3],
14429 operands[4]));
14430 }
14431 DONE;
14432 }
14433 [(set_attr "type" "fistp")
14434 (set_attr "i387_cw" "floor")
14435 (set_attr "mode" "<MODE>")])
14436
14437 (define_insn "fistdi2_floor"
14438 [(set (match_operand:DI 0 "memory_operand" "=m")
14439 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14440 UNSPEC_FIST_FLOOR))
14441 (use (match_operand:HI 2 "memory_operand" "m"))
14442 (use (match_operand:HI 3 "memory_operand" "m"))
14443 (clobber (match_scratch:XF 4 "=&1f"))]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations"
14446 "* return output_fix_trunc (insn, operands, 0);"
14447 [(set_attr "type" "fistp")
14448 (set_attr "i387_cw" "floor")
14449 (set_attr "mode" "DI")])
14450
14451 (define_insn "fistdi2_floor_with_temp"
14452 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14453 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14454 UNSPEC_FIST_FLOOR))
14455 (use (match_operand:HI 2 "memory_operand" "m,m"))
14456 (use (match_operand:HI 3 "memory_operand" "m,m"))
14457 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14458 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14459 "TARGET_USE_FANCY_MATH_387
14460 && flag_unsafe_math_optimizations"
14461 "#"
14462 [(set_attr "type" "fistp")
14463 (set_attr "i387_cw" "floor")
14464 (set_attr "mode" "DI")])
14465
14466 (define_split
14467 [(set (match_operand:DI 0 "register_operand" "")
14468 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14469 UNSPEC_FIST_FLOOR))
14470 (use (match_operand:HI 2 "memory_operand" ""))
14471 (use (match_operand:HI 3 "memory_operand" ""))
14472 (clobber (match_operand:DI 4 "memory_operand" ""))
14473 (clobber (match_scratch 5 ""))]
14474 "reload_completed"
14475 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14476 (use (match_dup 2))
14477 (use (match_dup 3))
14478 (clobber (match_dup 5))])
14479 (set (match_dup 0) (match_dup 4))]
14480 "")
14481
14482 (define_split
14483 [(set (match_operand:DI 0 "memory_operand" "")
14484 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14485 UNSPEC_FIST_FLOOR))
14486 (use (match_operand:HI 2 "memory_operand" ""))
14487 (use (match_operand:HI 3 "memory_operand" ""))
14488 (clobber (match_operand:DI 4 "memory_operand" ""))
14489 (clobber (match_scratch 5 ""))]
14490 "reload_completed"
14491 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14492 (use (match_dup 2))
14493 (use (match_dup 3))
14494 (clobber (match_dup 5))])]
14495 "")
14496
14497 (define_insn "fist<mode>2_floor"
14498 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14499 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14500 UNSPEC_FIST_FLOOR))
14501 (use (match_operand:HI 2 "memory_operand" "m"))
14502 (use (match_operand:HI 3 "memory_operand" "m"))]
14503 "TARGET_USE_FANCY_MATH_387
14504 && flag_unsafe_math_optimizations"
14505 "* return output_fix_trunc (insn, operands, 0);"
14506 [(set_attr "type" "fistp")
14507 (set_attr "i387_cw" "floor")
14508 (set_attr "mode" "<MODE>")])
14509
14510 (define_insn "fist<mode>2_floor_with_temp"
14511 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14512 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14513 UNSPEC_FIST_FLOOR))
14514 (use (match_operand:HI 2 "memory_operand" "m,m"))
14515 (use (match_operand:HI 3 "memory_operand" "m,m"))
14516 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14517 "TARGET_USE_FANCY_MATH_387
14518 && flag_unsafe_math_optimizations"
14519 "#"
14520 [(set_attr "type" "fistp")
14521 (set_attr "i387_cw" "floor")
14522 (set_attr "mode" "<MODE>")])
14523
14524 (define_split
14525 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14526 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14527 UNSPEC_FIST_FLOOR))
14528 (use (match_operand:HI 2 "memory_operand" ""))
14529 (use (match_operand:HI 3 "memory_operand" ""))
14530 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14531 "reload_completed"
14532 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14533 UNSPEC_FIST_FLOOR))
14534 (use (match_dup 2))
14535 (use (match_dup 3))])
14536 (set (match_dup 0) (match_dup 4))]
14537 "")
14538
14539 (define_split
14540 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14542 UNSPEC_FIST_FLOOR))
14543 (use (match_operand:HI 2 "memory_operand" ""))
14544 (use (match_operand:HI 3 "memory_operand" ""))
14545 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14546 "reload_completed"
14547 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14548 UNSPEC_FIST_FLOOR))
14549 (use (match_dup 2))
14550 (use (match_dup 3))])]
14551 "")
14552
14553 (define_expand "lfloorxf<mode>2"
14554 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14555 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14556 UNSPEC_FIST_FLOOR))
14557 (clobber (reg:CC FLAGS_REG))])]
14558 "TARGET_USE_FANCY_MATH_387
14559 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14560 && flag_unsafe_math_optimizations"
14561 "")
14562
14563 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14564 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14565 (match_operand:MODEF 1 "register_operand" "")]
14566 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14567 && !flag_trapping_math"
14568 {
14569 if (TARGET_64BIT && optimize_insn_for_size_p ())
14570 FAIL;
14571 ix86_expand_lfloorceil (operand0, operand1, true);
14572 DONE;
14573 })
14574
14575 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14576 (define_insn_and_split "frndintxf2_ceil"
14577 [(set (match_operand:XF 0 "register_operand" "")
14578 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14579 UNSPEC_FRNDINT_CEIL))
14580 (clobber (reg:CC FLAGS_REG))]
14581 "TARGET_USE_FANCY_MATH_387
14582 && flag_unsafe_math_optimizations
14583 && can_create_pseudo_p ()"
14584 "#"
14585 "&& 1"
14586 [(const_int 0)]
14587 {
14588 ix86_optimize_mode_switching[I387_CEIL] = 1;
14589
14590 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14591 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14592
14593 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14594 operands[2], operands[3]));
14595 DONE;
14596 }
14597 [(set_attr "type" "frndint")
14598 (set_attr "i387_cw" "ceil")
14599 (set_attr "mode" "XF")])
14600
14601 (define_insn "frndintxf2_ceil_i387"
14602 [(set (match_operand:XF 0 "register_operand" "=f")
14603 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14604 UNSPEC_FRNDINT_CEIL))
14605 (use (match_operand:HI 2 "memory_operand" "m"))
14606 (use (match_operand:HI 3 "memory_operand" "m"))]
14607 "TARGET_USE_FANCY_MATH_387
14608 && flag_unsafe_math_optimizations"
14609 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14610 [(set_attr "type" "frndint")
14611 (set_attr "i387_cw" "ceil")
14612 (set_attr "mode" "XF")])
14613
14614 (define_expand "ceilxf2"
14615 [(use (match_operand:XF 0 "register_operand" ""))
14616 (use (match_operand:XF 1 "register_operand" ""))]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations"
14619 {
14620 if (optimize_insn_for_size_p ())
14621 FAIL;
14622 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14623 DONE;
14624 })
14625
14626 (define_expand "ceil<mode>2"
14627 [(use (match_operand:MODEF 0 "register_operand" ""))
14628 (use (match_operand:MODEF 1 "register_operand" ""))]
14629 "(TARGET_USE_FANCY_MATH_387
14630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14631 || TARGET_MIX_SSE_I387)
14632 && flag_unsafe_math_optimizations)
14633 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14634 && !flag_trapping_math)"
14635 {
14636 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14637 && !flag_trapping_math
14638 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14639 {
14640 if (TARGET_ROUND)
14641 emit_insn (gen_sse4_1_round<mode>2
14642 (operands[0], operands[1], GEN_INT (0x02)));
14643 else if (optimize_insn_for_size_p ())
14644 FAIL;
14645 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14646 ix86_expand_floorceil (operand0, operand1, false);
14647 else
14648 ix86_expand_floorceildf_32 (operand0, operand1, false);
14649 }
14650 else
14651 {
14652 rtx op0, op1;
14653
14654 if (optimize_insn_for_size_p ())
14655 FAIL;
14656
14657 op0 = gen_reg_rtx (XFmode);
14658 op1 = gen_reg_rtx (XFmode);
14659 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14660 emit_insn (gen_frndintxf2_ceil (op0, op1));
14661
14662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14663 }
14664 DONE;
14665 })
14666
14667 (define_insn_and_split "*fist<mode>2_ceil_1"
14668 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14669 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14670 UNSPEC_FIST_CEIL))
14671 (clobber (reg:CC FLAGS_REG))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_unsafe_math_optimizations
14674 && can_create_pseudo_p ()"
14675 "#"
14676 "&& 1"
14677 [(const_int 0)]
14678 {
14679 ix86_optimize_mode_switching[I387_CEIL] = 1;
14680
14681 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14682 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14683 if (memory_operand (operands[0], VOIDmode))
14684 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14685 operands[2], operands[3]));
14686 else
14687 {
14688 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14689 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14690 operands[2], operands[3],
14691 operands[4]));
14692 }
14693 DONE;
14694 }
14695 [(set_attr "type" "fistp")
14696 (set_attr "i387_cw" "ceil")
14697 (set_attr "mode" "<MODE>")])
14698
14699 (define_insn "fistdi2_ceil"
14700 [(set (match_operand:DI 0 "memory_operand" "=m")
14701 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14702 UNSPEC_FIST_CEIL))
14703 (use (match_operand:HI 2 "memory_operand" "m"))
14704 (use (match_operand:HI 3 "memory_operand" "m"))
14705 (clobber (match_scratch:XF 4 "=&1f"))]
14706 "TARGET_USE_FANCY_MATH_387
14707 && flag_unsafe_math_optimizations"
14708 "* return output_fix_trunc (insn, operands, 0);"
14709 [(set_attr "type" "fistp")
14710 (set_attr "i387_cw" "ceil")
14711 (set_attr "mode" "DI")])
14712
14713 (define_insn "fistdi2_ceil_with_temp"
14714 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14715 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14716 UNSPEC_FIST_CEIL))
14717 (use (match_operand:HI 2 "memory_operand" "m,m"))
14718 (use (match_operand:HI 3 "memory_operand" "m,m"))
14719 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14720 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14721 "TARGET_USE_FANCY_MATH_387
14722 && flag_unsafe_math_optimizations"
14723 "#"
14724 [(set_attr "type" "fistp")
14725 (set_attr "i387_cw" "ceil")
14726 (set_attr "mode" "DI")])
14727
14728 (define_split
14729 [(set (match_operand:DI 0 "register_operand" "")
14730 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14731 UNSPEC_FIST_CEIL))
14732 (use (match_operand:HI 2 "memory_operand" ""))
14733 (use (match_operand:HI 3 "memory_operand" ""))
14734 (clobber (match_operand:DI 4 "memory_operand" ""))
14735 (clobber (match_scratch 5 ""))]
14736 "reload_completed"
14737 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14738 (use (match_dup 2))
14739 (use (match_dup 3))
14740 (clobber (match_dup 5))])
14741 (set (match_dup 0) (match_dup 4))]
14742 "")
14743
14744 (define_split
14745 [(set (match_operand:DI 0 "memory_operand" "")
14746 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14747 UNSPEC_FIST_CEIL))
14748 (use (match_operand:HI 2 "memory_operand" ""))
14749 (use (match_operand:HI 3 "memory_operand" ""))
14750 (clobber (match_operand:DI 4 "memory_operand" ""))
14751 (clobber (match_scratch 5 ""))]
14752 "reload_completed"
14753 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14754 (use (match_dup 2))
14755 (use (match_dup 3))
14756 (clobber (match_dup 5))])]
14757 "")
14758
14759 (define_insn "fist<mode>2_ceil"
14760 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14761 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14762 UNSPEC_FIST_CEIL))
14763 (use (match_operand:HI 2 "memory_operand" "m"))
14764 (use (match_operand:HI 3 "memory_operand" "m"))]
14765 "TARGET_USE_FANCY_MATH_387
14766 && flag_unsafe_math_optimizations"
14767 "* return output_fix_trunc (insn, operands, 0);"
14768 [(set_attr "type" "fistp")
14769 (set_attr "i387_cw" "ceil")
14770 (set_attr "mode" "<MODE>")])
14771
14772 (define_insn "fist<mode>2_ceil_with_temp"
14773 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14774 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14775 UNSPEC_FIST_CEIL))
14776 (use (match_operand:HI 2 "memory_operand" "m,m"))
14777 (use (match_operand:HI 3 "memory_operand" "m,m"))
14778 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14779 "TARGET_USE_FANCY_MATH_387
14780 && flag_unsafe_math_optimizations"
14781 "#"
14782 [(set_attr "type" "fistp")
14783 (set_attr "i387_cw" "ceil")
14784 (set_attr "mode" "<MODE>")])
14785
14786 (define_split
14787 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14788 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14789 UNSPEC_FIST_CEIL))
14790 (use (match_operand:HI 2 "memory_operand" ""))
14791 (use (match_operand:HI 3 "memory_operand" ""))
14792 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14793 "reload_completed"
14794 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14795 UNSPEC_FIST_CEIL))
14796 (use (match_dup 2))
14797 (use (match_dup 3))])
14798 (set (match_dup 0) (match_dup 4))]
14799 "")
14800
14801 (define_split
14802 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14804 UNSPEC_FIST_CEIL))
14805 (use (match_operand:HI 2 "memory_operand" ""))
14806 (use (match_operand:HI 3 "memory_operand" ""))
14807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14808 "reload_completed"
14809 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14810 UNSPEC_FIST_CEIL))
14811 (use (match_dup 2))
14812 (use (match_dup 3))])]
14813 "")
14814
14815 (define_expand "lceilxf<mode>2"
14816 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14817 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14818 UNSPEC_FIST_CEIL))
14819 (clobber (reg:CC FLAGS_REG))])]
14820 "TARGET_USE_FANCY_MATH_387
14821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14822 && flag_unsafe_math_optimizations"
14823 "")
14824
14825 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14826 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14827 (match_operand:MODEF 1 "register_operand" "")]
14828 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14829 && !flag_trapping_math"
14830 {
14831 ix86_expand_lfloorceil (operand0, operand1, false);
14832 DONE;
14833 })
14834
14835 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14836 (define_insn_and_split "frndintxf2_trunc"
14837 [(set (match_operand:XF 0 "register_operand" "")
14838 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14839 UNSPEC_FRNDINT_TRUNC))
14840 (clobber (reg:CC FLAGS_REG))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations
14843 && can_create_pseudo_p ()"
14844 "#"
14845 "&& 1"
14846 [(const_int 0)]
14847 {
14848 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14849
14850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14852
14853 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14854 operands[2], operands[3]));
14855 DONE;
14856 }
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "trunc")
14859 (set_attr "mode" "XF")])
14860
14861 (define_insn "frndintxf2_trunc_i387"
14862 [(set (match_operand:XF 0 "register_operand" "=f")
14863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14864 UNSPEC_FRNDINT_TRUNC))
14865 (use (match_operand:HI 2 "memory_operand" "m"))
14866 (use (match_operand:HI 3 "memory_operand" "m"))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && flag_unsafe_math_optimizations"
14869 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14870 [(set_attr "type" "frndint")
14871 (set_attr "i387_cw" "trunc")
14872 (set_attr "mode" "XF")])
14873
14874 (define_expand "btruncxf2"
14875 [(use (match_operand:XF 0 "register_operand" ""))
14876 (use (match_operand:XF 1 "register_operand" ""))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && flag_unsafe_math_optimizations"
14879 {
14880 if (optimize_insn_for_size_p ())
14881 FAIL;
14882 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14883 DONE;
14884 })
14885
14886 (define_expand "btrunc<mode>2"
14887 [(use (match_operand:MODEF 0 "register_operand" ""))
14888 (use (match_operand:MODEF 1 "register_operand" ""))]
14889 "(TARGET_USE_FANCY_MATH_387
14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891 || TARGET_MIX_SSE_I387)
14892 && flag_unsafe_math_optimizations)
14893 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14894 && !flag_trapping_math)"
14895 {
14896 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14897 && !flag_trapping_math
14898 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14899 {
14900 if (TARGET_ROUND)
14901 emit_insn (gen_sse4_1_round<mode>2
14902 (operands[0], operands[1], GEN_INT (0x03)));
14903 else if (optimize_insn_for_size_p ())
14904 FAIL;
14905 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14906 ix86_expand_trunc (operand0, operand1);
14907 else
14908 ix86_expand_truncdf_32 (operand0, operand1);
14909 }
14910 else
14911 {
14912 rtx op0, op1;
14913
14914 if (optimize_insn_for_size_p ())
14915 FAIL;
14916
14917 op0 = gen_reg_rtx (XFmode);
14918 op1 = gen_reg_rtx (XFmode);
14919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14920 emit_insn (gen_frndintxf2_trunc (op0, op1));
14921
14922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14923 }
14924 DONE;
14925 })
14926
14927 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14928 (define_insn_and_split "frndintxf2_mask_pm"
14929 [(set (match_operand:XF 0 "register_operand" "")
14930 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14931 UNSPEC_FRNDINT_MASK_PM))
14932 (clobber (reg:CC FLAGS_REG))]
14933 "TARGET_USE_FANCY_MATH_387
14934 && flag_unsafe_math_optimizations
14935 && can_create_pseudo_p ()"
14936 "#"
14937 "&& 1"
14938 [(const_int 0)]
14939 {
14940 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14941
14942 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14943 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14944
14945 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14946 operands[2], operands[3]));
14947 DONE;
14948 }
14949 [(set_attr "type" "frndint")
14950 (set_attr "i387_cw" "mask_pm")
14951 (set_attr "mode" "XF")])
14952
14953 (define_insn "frndintxf2_mask_pm_i387"
14954 [(set (match_operand:XF 0 "register_operand" "=f")
14955 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14956 UNSPEC_FRNDINT_MASK_PM))
14957 (use (match_operand:HI 2 "memory_operand" "m"))
14958 (use (match_operand:HI 3 "memory_operand" "m"))]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14961 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14962 [(set_attr "type" "frndint")
14963 (set_attr "i387_cw" "mask_pm")
14964 (set_attr "mode" "XF")])
14965
14966 (define_expand "nearbyintxf2"
14967 [(use (match_operand:XF 0 "register_operand" ""))
14968 (use (match_operand:XF 1 "register_operand" ""))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && flag_unsafe_math_optimizations"
14971 {
14972 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14973
14974 DONE;
14975 })
14976
14977 (define_expand "nearbyint<mode>2"
14978 [(use (match_operand:MODEF 0 "register_operand" ""))
14979 (use (match_operand:MODEF 1 "register_operand" ""))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14982 || TARGET_MIX_SSE_I387)
14983 && flag_unsafe_math_optimizations"
14984 {
14985 rtx op0 = gen_reg_rtx (XFmode);
14986 rtx op1 = gen_reg_rtx (XFmode);
14987
14988 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14989 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14990
14991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14992 DONE;
14993 })
14994
14995 (define_insn "fxam<mode>2_i387"
14996 [(set (match_operand:HI 0 "register_operand" "=a")
14997 (unspec:HI
14998 [(match_operand:X87MODEF 1 "register_operand" "f")]
14999 UNSPEC_FXAM))]
15000 "TARGET_USE_FANCY_MATH_387"
15001 "fxam\n\tfnstsw\t%0"
15002 [(set_attr "type" "multi")
15003 (set_attr "length" "4")
15004 (set_attr "unit" "i387")
15005 (set_attr "mode" "<MODE>")])
15006
15007 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15008 [(set (match_operand:HI 0 "register_operand" "")
15009 (unspec:HI
15010 [(match_operand:MODEF 1 "memory_operand" "")]
15011 UNSPEC_FXAM_MEM))]
15012 "TARGET_USE_FANCY_MATH_387
15013 && can_create_pseudo_p ()"
15014 "#"
15015 "&& 1"
15016 [(set (match_dup 2)(match_dup 1))
15017 (set (match_dup 0)
15018 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15019 {
15020 operands[2] = gen_reg_rtx (<MODE>mode);
15021
15022 MEM_VOLATILE_P (operands[1]) = 1;
15023 }
15024 [(set_attr "type" "multi")
15025 (set_attr "unit" "i387")
15026 (set_attr "mode" "<MODE>")])
15027
15028 (define_expand "isinfxf2"
15029 [(use (match_operand:SI 0 "register_operand" ""))
15030 (use (match_operand:XF 1 "register_operand" ""))]
15031 "TARGET_USE_FANCY_MATH_387
15032 && TARGET_C99_FUNCTIONS"
15033 {
15034 rtx mask = GEN_INT (0x45);
15035 rtx val = GEN_INT (0x05);
15036
15037 rtx cond;
15038
15039 rtx scratch = gen_reg_rtx (HImode);
15040 rtx res = gen_reg_rtx (QImode);
15041
15042 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15043
15044 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15045 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15046 cond = gen_rtx_fmt_ee (EQ, QImode,
15047 gen_rtx_REG (CCmode, FLAGS_REG),
15048 const0_rtx);
15049 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15050 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15051 DONE;
15052 })
15053
15054 (define_expand "isinf<mode>2"
15055 [(use (match_operand:SI 0 "register_operand" ""))
15056 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15057 "TARGET_USE_FANCY_MATH_387
15058 && TARGET_C99_FUNCTIONS
15059 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15060 {
15061 rtx mask = GEN_INT (0x45);
15062 rtx val = GEN_INT (0x05);
15063
15064 rtx cond;
15065
15066 rtx scratch = gen_reg_rtx (HImode);
15067 rtx res = gen_reg_rtx (QImode);
15068
15069 /* Remove excess precision by forcing value through memory. */
15070 if (memory_operand (operands[1], VOIDmode))
15071 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15072 else
15073 {
15074 enum ix86_stack_slot slot = (virtuals_instantiated
15075 ? SLOT_TEMP
15076 : SLOT_VIRTUAL);
15077 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15078
15079 emit_move_insn (temp, operands[1]);
15080 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15081 }
15082
15083 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15084 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15085 cond = gen_rtx_fmt_ee (EQ, QImode,
15086 gen_rtx_REG (CCmode, FLAGS_REG),
15087 const0_rtx);
15088 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15089 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15090 DONE;
15091 })
15092
15093 (define_expand "signbit<mode>2"
15094 [(use (match_operand:SI 0 "register_operand" ""))
15095 (use (match_operand:X87MODEF 1 "register_operand" ""))]
15096 "TARGET_USE_FANCY_MATH_387
15097 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15098 {
15099 rtx mask = GEN_INT (0x0200);
15100
15101 rtx scratch = gen_reg_rtx (HImode);
15102
15103 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15104 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15105 DONE;
15106 })
15107 \f
15108 ;; Block operation instructions
15109
15110 (define_insn "cld"
15111 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15112 ""
15113 "cld"
15114 [(set_attr "length" "1")
15115 (set_attr "length_immediate" "0")
15116 (set_attr "modrm" "0")])
15117
15118 (define_expand "movmemsi"
15119 [(use (match_operand:BLK 0 "memory_operand" ""))
15120 (use (match_operand:BLK 1 "memory_operand" ""))
15121 (use (match_operand:SI 2 "nonmemory_operand" ""))
15122 (use (match_operand:SI 3 "const_int_operand" ""))
15123 (use (match_operand:SI 4 "const_int_operand" ""))
15124 (use (match_operand:SI 5 "const_int_operand" ""))]
15125 ""
15126 {
15127 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15128 operands[4], operands[5]))
15129 DONE;
15130 else
15131 FAIL;
15132 })
15133
15134 (define_expand "movmemdi"
15135 [(use (match_operand:BLK 0 "memory_operand" ""))
15136 (use (match_operand:BLK 1 "memory_operand" ""))
15137 (use (match_operand:DI 2 "nonmemory_operand" ""))
15138 (use (match_operand:DI 3 "const_int_operand" ""))
15139 (use (match_operand:SI 4 "const_int_operand" ""))
15140 (use (match_operand:SI 5 "const_int_operand" ""))]
15141 "TARGET_64BIT"
15142 {
15143 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15144 operands[4], operands[5]))
15145 DONE;
15146 else
15147 FAIL;
15148 })
15149
15150 ;; Most CPUs don't like single string operations
15151 ;; Handle this case here to simplify previous expander.
15152
15153 (define_expand "strmov"
15154 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15155 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15156 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15157 (clobber (reg:CC FLAGS_REG))])
15158 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15159 (clobber (reg:CC FLAGS_REG))])]
15160 ""
15161 {
15162 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15163
15164 /* If .md ever supports :P for Pmode, these can be directly
15165 in the pattern above. */
15166 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15167 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15168
15169 /* Can't use this if the user has appropriated esi or edi. */
15170 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15171 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15172 {
15173 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15174 operands[2], operands[3],
15175 operands[5], operands[6]));
15176 DONE;
15177 }
15178
15179 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15180 })
15181
15182 (define_expand "strmov_singleop"
15183 [(parallel [(set (match_operand 1 "memory_operand" "")
15184 (match_operand 3 "memory_operand" ""))
15185 (set (match_operand 0 "register_operand" "")
15186 (match_operand 4 "" ""))
15187 (set (match_operand 2 "register_operand" "")
15188 (match_operand 5 "" ""))])]
15189 ""
15190 "ix86_current_function_needs_cld = 1;")
15191
15192 (define_insn "*strmovdi_rex_1"
15193 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15194 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15195 (set (match_operand:DI 0 "register_operand" "=D")
15196 (plus:DI (match_dup 2)
15197 (const_int 8)))
15198 (set (match_operand:DI 1 "register_operand" "=S")
15199 (plus:DI (match_dup 3)
15200 (const_int 8)))]
15201 "TARGET_64BIT"
15202 "movsq"
15203 [(set_attr "type" "str")
15204 (set_attr "mode" "DI")
15205 (set_attr "memory" "both")])
15206
15207 (define_insn "*strmovsi_1"
15208 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15209 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15210 (set (match_operand:SI 0 "register_operand" "=D")
15211 (plus:SI (match_dup 2)
15212 (const_int 4)))
15213 (set (match_operand:SI 1 "register_operand" "=S")
15214 (plus:SI (match_dup 3)
15215 (const_int 4)))]
15216 "!TARGET_64BIT"
15217 "movs{l|d}"
15218 [(set_attr "type" "str")
15219 (set_attr "mode" "SI")
15220 (set_attr "memory" "both")])
15221
15222 (define_insn "*strmovsi_rex_1"
15223 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15224 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15225 (set (match_operand:DI 0 "register_operand" "=D")
15226 (plus:DI (match_dup 2)
15227 (const_int 4)))
15228 (set (match_operand:DI 1 "register_operand" "=S")
15229 (plus:DI (match_dup 3)
15230 (const_int 4)))]
15231 "TARGET_64BIT"
15232 "movs{l|d}"
15233 [(set_attr "type" "str")
15234 (set_attr "mode" "SI")
15235 (set_attr "memory" "both")])
15236
15237 (define_insn "*strmovhi_1"
15238 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15239 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15240 (set (match_operand:SI 0 "register_operand" "=D")
15241 (plus:SI (match_dup 2)
15242 (const_int 2)))
15243 (set (match_operand:SI 1 "register_operand" "=S")
15244 (plus:SI (match_dup 3)
15245 (const_int 2)))]
15246 "!TARGET_64BIT"
15247 "movsw"
15248 [(set_attr "type" "str")
15249 (set_attr "memory" "both")
15250 (set_attr "mode" "HI")])
15251
15252 (define_insn "*strmovhi_rex_1"
15253 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15254 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15255 (set (match_operand:DI 0 "register_operand" "=D")
15256 (plus:DI (match_dup 2)
15257 (const_int 2)))
15258 (set (match_operand:DI 1 "register_operand" "=S")
15259 (plus:DI (match_dup 3)
15260 (const_int 2)))]
15261 "TARGET_64BIT"
15262 "movsw"
15263 [(set_attr "type" "str")
15264 (set_attr "memory" "both")
15265 (set_attr "mode" "HI")])
15266
15267 (define_insn "*strmovqi_1"
15268 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15269 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15270 (set (match_operand:SI 0 "register_operand" "=D")
15271 (plus:SI (match_dup 2)
15272 (const_int 1)))
15273 (set (match_operand:SI 1 "register_operand" "=S")
15274 (plus:SI (match_dup 3)
15275 (const_int 1)))]
15276 "!TARGET_64BIT"
15277 "movsb"
15278 [(set_attr "type" "str")
15279 (set_attr "memory" "both")
15280 (set_attr "mode" "QI")])
15281
15282 (define_insn "*strmovqi_rex_1"
15283 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15284 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15285 (set (match_operand:DI 0 "register_operand" "=D")
15286 (plus:DI (match_dup 2)
15287 (const_int 1)))
15288 (set (match_operand:DI 1 "register_operand" "=S")
15289 (plus:DI (match_dup 3)
15290 (const_int 1)))]
15291 "TARGET_64BIT"
15292 "movsb"
15293 [(set_attr "type" "str")
15294 (set_attr "memory" "both")
15295 (set_attr "prefix_rex" "0")
15296 (set_attr "mode" "QI")])
15297
15298 (define_expand "rep_mov"
15299 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15300 (set (match_operand 0 "register_operand" "")
15301 (match_operand 5 "" ""))
15302 (set (match_operand 2 "register_operand" "")
15303 (match_operand 6 "" ""))
15304 (set (match_operand 1 "memory_operand" "")
15305 (match_operand 3 "memory_operand" ""))
15306 (use (match_dup 4))])]
15307 ""
15308 "ix86_current_function_needs_cld = 1;")
15309
15310 (define_insn "*rep_movdi_rex64"
15311 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15312 (set (match_operand:DI 0 "register_operand" "=D")
15313 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15314 (const_int 3))
15315 (match_operand:DI 3 "register_operand" "0")))
15316 (set (match_operand:DI 1 "register_operand" "=S")
15317 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15318 (match_operand:DI 4 "register_operand" "1")))
15319 (set (mem:BLK (match_dup 3))
15320 (mem:BLK (match_dup 4)))
15321 (use (match_dup 5))]
15322 "TARGET_64BIT"
15323 "rep{%;} movsq"
15324 [(set_attr "type" "str")
15325 (set_attr "prefix_rep" "1")
15326 (set_attr "memory" "both")
15327 (set_attr "mode" "DI")])
15328
15329 (define_insn "*rep_movsi"
15330 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15331 (set (match_operand:SI 0 "register_operand" "=D")
15332 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15333 (const_int 2))
15334 (match_operand:SI 3 "register_operand" "0")))
15335 (set (match_operand:SI 1 "register_operand" "=S")
15336 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15337 (match_operand:SI 4 "register_operand" "1")))
15338 (set (mem:BLK (match_dup 3))
15339 (mem:BLK (match_dup 4)))
15340 (use (match_dup 5))]
15341 "!TARGET_64BIT"
15342 "rep{%;} movs{l|d}"
15343 [(set_attr "type" "str")
15344 (set_attr "prefix_rep" "1")
15345 (set_attr "memory" "both")
15346 (set_attr "mode" "SI")])
15347
15348 (define_insn "*rep_movsi_rex64"
15349 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15350 (set (match_operand:DI 0 "register_operand" "=D")
15351 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15352 (const_int 2))
15353 (match_operand:DI 3 "register_operand" "0")))
15354 (set (match_operand:DI 1 "register_operand" "=S")
15355 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15356 (match_operand:DI 4 "register_operand" "1")))
15357 (set (mem:BLK (match_dup 3))
15358 (mem:BLK (match_dup 4)))
15359 (use (match_dup 5))]
15360 "TARGET_64BIT"
15361 "rep{%;} movs{l|d}"
15362 [(set_attr "type" "str")
15363 (set_attr "prefix_rep" "1")
15364 (set_attr "memory" "both")
15365 (set_attr "mode" "SI")])
15366
15367 (define_insn "*rep_movqi"
15368 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15369 (set (match_operand:SI 0 "register_operand" "=D")
15370 (plus:SI (match_operand:SI 3 "register_operand" "0")
15371 (match_operand:SI 5 "register_operand" "2")))
15372 (set (match_operand:SI 1 "register_operand" "=S")
15373 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15374 (set (mem:BLK (match_dup 3))
15375 (mem:BLK (match_dup 4)))
15376 (use (match_dup 5))]
15377 "!TARGET_64BIT"
15378 "rep{%;} movsb"
15379 [(set_attr "type" "str")
15380 (set_attr "prefix_rep" "1")
15381 (set_attr "memory" "both")
15382 (set_attr "mode" "SI")])
15383
15384 (define_insn "*rep_movqi_rex64"
15385 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15386 (set (match_operand:DI 0 "register_operand" "=D")
15387 (plus:DI (match_operand:DI 3 "register_operand" "0")
15388 (match_operand:DI 5 "register_operand" "2")))
15389 (set (match_operand:DI 1 "register_operand" "=S")
15390 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15391 (set (mem:BLK (match_dup 3))
15392 (mem:BLK (match_dup 4)))
15393 (use (match_dup 5))]
15394 "TARGET_64BIT"
15395 "rep{%;} movsb"
15396 [(set_attr "type" "str")
15397 (set_attr "prefix_rep" "1")
15398 (set_attr "memory" "both")
15399 (set_attr "mode" "SI")])
15400
15401 (define_expand "setmemsi"
15402 [(use (match_operand:BLK 0 "memory_operand" ""))
15403 (use (match_operand:SI 1 "nonmemory_operand" ""))
15404 (use (match_operand 2 "const_int_operand" ""))
15405 (use (match_operand 3 "const_int_operand" ""))
15406 (use (match_operand:SI 4 "const_int_operand" ""))
15407 (use (match_operand:SI 5 "const_int_operand" ""))]
15408 ""
15409 {
15410 if (ix86_expand_setmem (operands[0], operands[1],
15411 operands[2], operands[3],
15412 operands[4], operands[5]))
15413 DONE;
15414 else
15415 FAIL;
15416 })
15417
15418 (define_expand "setmemdi"
15419 [(use (match_operand:BLK 0 "memory_operand" ""))
15420 (use (match_operand:DI 1 "nonmemory_operand" ""))
15421 (use (match_operand 2 "const_int_operand" ""))
15422 (use (match_operand 3 "const_int_operand" ""))
15423 (use (match_operand 4 "const_int_operand" ""))
15424 (use (match_operand 5 "const_int_operand" ""))]
15425 "TARGET_64BIT"
15426 {
15427 if (ix86_expand_setmem (operands[0], operands[1],
15428 operands[2], operands[3],
15429 operands[4], operands[5]))
15430 DONE;
15431 else
15432 FAIL;
15433 })
15434
15435 ;; Most CPUs don't like single string operations
15436 ;; Handle this case here to simplify previous expander.
15437
15438 (define_expand "strset"
15439 [(set (match_operand 1 "memory_operand" "")
15440 (match_operand 2 "register_operand" ""))
15441 (parallel [(set (match_operand 0 "register_operand" "")
15442 (match_dup 3))
15443 (clobber (reg:CC FLAGS_REG))])]
15444 ""
15445 {
15446 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15447 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15448
15449 /* If .md ever supports :P for Pmode, this can be directly
15450 in the pattern above. */
15451 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15452 GEN_INT (GET_MODE_SIZE (GET_MODE
15453 (operands[2]))));
15454 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15455 {
15456 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15457 operands[3]));
15458 DONE;
15459 }
15460 })
15461
15462 (define_expand "strset_singleop"
15463 [(parallel [(set (match_operand 1 "memory_operand" "")
15464 (match_operand 2 "register_operand" ""))
15465 (set (match_operand 0 "register_operand" "")
15466 (match_operand 3 "" ""))])]
15467 ""
15468 "ix86_current_function_needs_cld = 1;")
15469
15470 (define_insn "*strsetdi_rex_1"
15471 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15472 (match_operand:DI 2 "register_operand" "a"))
15473 (set (match_operand:DI 0 "register_operand" "=D")
15474 (plus:DI (match_dup 1)
15475 (const_int 8)))]
15476 "TARGET_64BIT"
15477 "stosq"
15478 [(set_attr "type" "str")
15479 (set_attr "memory" "store")
15480 (set_attr "mode" "DI")])
15481
15482 (define_insn "*strsetsi_1"
15483 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15484 (match_operand:SI 2 "register_operand" "a"))
15485 (set (match_operand:SI 0 "register_operand" "=D")
15486 (plus:SI (match_dup 1)
15487 (const_int 4)))]
15488 "!TARGET_64BIT"
15489 "stos{l|d}"
15490 [(set_attr "type" "str")
15491 (set_attr "memory" "store")
15492 (set_attr "mode" "SI")])
15493
15494 (define_insn "*strsetsi_rex_1"
15495 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15496 (match_operand:SI 2 "register_operand" "a"))
15497 (set (match_operand:DI 0 "register_operand" "=D")
15498 (plus:DI (match_dup 1)
15499 (const_int 4)))]
15500 "TARGET_64BIT"
15501 "stos{l|d}"
15502 [(set_attr "type" "str")
15503 (set_attr "memory" "store")
15504 (set_attr "mode" "SI")])
15505
15506 (define_insn "*strsethi_1"
15507 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15508 (match_operand:HI 2 "register_operand" "a"))
15509 (set (match_operand:SI 0 "register_operand" "=D")
15510 (plus:SI (match_dup 1)
15511 (const_int 2)))]
15512 "!TARGET_64BIT"
15513 "stosw"
15514 [(set_attr "type" "str")
15515 (set_attr "memory" "store")
15516 (set_attr "mode" "HI")])
15517
15518 (define_insn "*strsethi_rex_1"
15519 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15520 (match_operand:HI 2 "register_operand" "a"))
15521 (set (match_operand:DI 0 "register_operand" "=D")
15522 (plus:DI (match_dup 1)
15523 (const_int 2)))]
15524 "TARGET_64BIT"
15525 "stosw"
15526 [(set_attr "type" "str")
15527 (set_attr "memory" "store")
15528 (set_attr "mode" "HI")])
15529
15530 (define_insn "*strsetqi_1"
15531 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15532 (match_operand:QI 2 "register_operand" "a"))
15533 (set (match_operand:SI 0 "register_operand" "=D")
15534 (plus:SI (match_dup 1)
15535 (const_int 1)))]
15536 "!TARGET_64BIT"
15537 "stosb"
15538 [(set_attr "type" "str")
15539 (set_attr "memory" "store")
15540 (set_attr "mode" "QI")])
15541
15542 (define_insn "*strsetqi_rex_1"
15543 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15544 (match_operand:QI 2 "register_operand" "a"))
15545 (set (match_operand:DI 0 "register_operand" "=D")
15546 (plus:DI (match_dup 1)
15547 (const_int 1)))]
15548 "TARGET_64BIT"
15549 "stosb"
15550 [(set_attr "type" "str")
15551 (set_attr "memory" "store")
15552 (set_attr "prefix_rex" "0")
15553 (set_attr "mode" "QI")])
15554
15555 (define_expand "rep_stos"
15556 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15557 (set (match_operand 0 "register_operand" "")
15558 (match_operand 4 "" ""))
15559 (set (match_operand 2 "memory_operand" "") (const_int 0))
15560 (use (match_operand 3 "register_operand" ""))
15561 (use (match_dup 1))])]
15562 ""
15563 "ix86_current_function_needs_cld = 1;")
15564
15565 (define_insn "*rep_stosdi_rex64"
15566 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15567 (set (match_operand:DI 0 "register_operand" "=D")
15568 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15569 (const_int 3))
15570 (match_operand:DI 3 "register_operand" "0")))
15571 (set (mem:BLK (match_dup 3))
15572 (const_int 0))
15573 (use (match_operand:DI 2 "register_operand" "a"))
15574 (use (match_dup 4))]
15575 "TARGET_64BIT"
15576 "rep{%;} stosq"
15577 [(set_attr "type" "str")
15578 (set_attr "prefix_rep" "1")
15579 (set_attr "memory" "store")
15580 (set_attr "mode" "DI")])
15581
15582 (define_insn "*rep_stossi"
15583 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15584 (set (match_operand:SI 0 "register_operand" "=D")
15585 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15586 (const_int 2))
15587 (match_operand:SI 3 "register_operand" "0")))
15588 (set (mem:BLK (match_dup 3))
15589 (const_int 0))
15590 (use (match_operand:SI 2 "register_operand" "a"))
15591 (use (match_dup 4))]
15592 "!TARGET_64BIT"
15593 "rep{%;} stos{l|d}"
15594 [(set_attr "type" "str")
15595 (set_attr "prefix_rep" "1")
15596 (set_attr "memory" "store")
15597 (set_attr "mode" "SI")])
15598
15599 (define_insn "*rep_stossi_rex64"
15600 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15601 (set (match_operand:DI 0 "register_operand" "=D")
15602 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15603 (const_int 2))
15604 (match_operand:DI 3 "register_operand" "0")))
15605 (set (mem:BLK (match_dup 3))
15606 (const_int 0))
15607 (use (match_operand:SI 2 "register_operand" "a"))
15608 (use (match_dup 4))]
15609 "TARGET_64BIT"
15610 "rep{%;} stos{l|d}"
15611 [(set_attr "type" "str")
15612 (set_attr "prefix_rep" "1")
15613 (set_attr "memory" "store")
15614 (set_attr "mode" "SI")])
15615
15616 (define_insn "*rep_stosqi"
15617 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15618 (set (match_operand:SI 0 "register_operand" "=D")
15619 (plus:SI (match_operand:SI 3 "register_operand" "0")
15620 (match_operand:SI 4 "register_operand" "1")))
15621 (set (mem:BLK (match_dup 3))
15622 (const_int 0))
15623 (use (match_operand:QI 2 "register_operand" "a"))
15624 (use (match_dup 4))]
15625 "!TARGET_64BIT"
15626 "rep{%;} stosb"
15627 [(set_attr "type" "str")
15628 (set_attr "prefix_rep" "1")
15629 (set_attr "memory" "store")
15630 (set_attr "mode" "QI")])
15631
15632 (define_insn "*rep_stosqi_rex64"
15633 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15634 (set (match_operand:DI 0 "register_operand" "=D")
15635 (plus:DI (match_operand:DI 3 "register_operand" "0")
15636 (match_operand:DI 4 "register_operand" "1")))
15637 (set (mem:BLK (match_dup 3))
15638 (const_int 0))
15639 (use (match_operand:QI 2 "register_operand" "a"))
15640 (use (match_dup 4))]
15641 "TARGET_64BIT"
15642 "rep{%;} stosb"
15643 [(set_attr "type" "str")
15644 (set_attr "prefix_rep" "1")
15645 (set_attr "memory" "store")
15646 (set_attr "prefix_rex" "0")
15647 (set_attr "mode" "QI")])
15648
15649 (define_expand "cmpstrnsi"
15650 [(set (match_operand:SI 0 "register_operand" "")
15651 (compare:SI (match_operand:BLK 1 "general_operand" "")
15652 (match_operand:BLK 2 "general_operand" "")))
15653 (use (match_operand 3 "general_operand" ""))
15654 (use (match_operand 4 "immediate_operand" ""))]
15655 ""
15656 {
15657 rtx addr1, addr2, out, outlow, count, countreg, align;
15658
15659 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15660 FAIL;
15661
15662 /* Can't use this if the user has appropriated esi or edi. */
15663 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15664 FAIL;
15665
15666 out = operands[0];
15667 if (!REG_P (out))
15668 out = gen_reg_rtx (SImode);
15669
15670 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15671 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15672 if (addr1 != XEXP (operands[1], 0))
15673 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15674 if (addr2 != XEXP (operands[2], 0))
15675 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15676
15677 count = operands[3];
15678 countreg = ix86_zero_extend_to_Pmode (count);
15679
15680 /* %%% Iff we are testing strict equality, we can use known alignment
15681 to good advantage. This may be possible with combine, particularly
15682 once cc0 is dead. */
15683 align = operands[4];
15684
15685 if (CONST_INT_P (count))
15686 {
15687 if (INTVAL (count) == 0)
15688 {
15689 emit_move_insn (operands[0], const0_rtx);
15690 DONE;
15691 }
15692 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15693 operands[1], operands[2]));
15694 }
15695 else
15696 {
15697 rtx (*cmp_insn)(rtx, rtx);
15698
15699 if (TARGET_64BIT)
15700 cmp_insn = gen_cmpdi_1;
15701 else
15702 cmp_insn = gen_cmpsi_1;
15703 emit_insn (cmp_insn (countreg, countreg));
15704 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15705 operands[1], operands[2]));
15706 }
15707
15708 outlow = gen_lowpart (QImode, out);
15709 emit_insn (gen_cmpintqi (outlow));
15710 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15711
15712 if (operands[0] != out)
15713 emit_move_insn (operands[0], out);
15714
15715 DONE;
15716 })
15717
15718 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15719
15720 (define_expand "cmpintqi"
15721 [(set (match_dup 1)
15722 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15723 (set (match_dup 2)
15724 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15725 (parallel [(set (match_operand:QI 0 "register_operand" "")
15726 (minus:QI (match_dup 1)
15727 (match_dup 2)))
15728 (clobber (reg:CC FLAGS_REG))])]
15729 ""
15730 "operands[1] = gen_reg_rtx (QImode);
15731 operands[2] = gen_reg_rtx (QImode);")
15732
15733 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15734 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15735
15736 (define_expand "cmpstrnqi_nz_1"
15737 [(parallel [(set (reg:CC FLAGS_REG)
15738 (compare:CC (match_operand 4 "memory_operand" "")
15739 (match_operand 5 "memory_operand" "")))
15740 (use (match_operand 2 "register_operand" ""))
15741 (use (match_operand:SI 3 "immediate_operand" ""))
15742 (clobber (match_operand 0 "register_operand" ""))
15743 (clobber (match_operand 1 "register_operand" ""))
15744 (clobber (match_dup 2))])]
15745 ""
15746 "ix86_current_function_needs_cld = 1;")
15747
15748 (define_insn "*cmpstrnqi_nz_1"
15749 [(set (reg:CC FLAGS_REG)
15750 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15751 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15752 (use (match_operand:SI 6 "register_operand" "2"))
15753 (use (match_operand:SI 3 "immediate_operand" "i"))
15754 (clobber (match_operand:SI 0 "register_operand" "=S"))
15755 (clobber (match_operand:SI 1 "register_operand" "=D"))
15756 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15757 "!TARGET_64BIT"
15758 "repz{%;} cmpsb"
15759 [(set_attr "type" "str")
15760 (set_attr "mode" "QI")
15761 (set_attr "prefix_rep" "1")])
15762
15763 (define_insn "*cmpstrnqi_nz_rex_1"
15764 [(set (reg:CC FLAGS_REG)
15765 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15766 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15767 (use (match_operand:DI 6 "register_operand" "2"))
15768 (use (match_operand:SI 3 "immediate_operand" "i"))
15769 (clobber (match_operand:DI 0 "register_operand" "=S"))
15770 (clobber (match_operand:DI 1 "register_operand" "=D"))
15771 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15772 "TARGET_64BIT"
15773 "repz{%;} cmpsb"
15774 [(set_attr "type" "str")
15775 (set_attr "mode" "QI")
15776 (set_attr "prefix_rex" "0")
15777 (set_attr "prefix_rep" "1")])
15778
15779 ;; The same, but the count is not known to not be zero.
15780
15781 (define_expand "cmpstrnqi_1"
15782 [(parallel [(set (reg:CC FLAGS_REG)
15783 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15784 (const_int 0))
15785 (compare:CC (match_operand 4 "memory_operand" "")
15786 (match_operand 5 "memory_operand" ""))
15787 (const_int 0)))
15788 (use (match_operand:SI 3 "immediate_operand" ""))
15789 (use (reg:CC FLAGS_REG))
15790 (clobber (match_operand 0 "register_operand" ""))
15791 (clobber (match_operand 1 "register_operand" ""))
15792 (clobber (match_dup 2))])]
15793 ""
15794 "ix86_current_function_needs_cld = 1;")
15795
15796 (define_insn "*cmpstrnqi_1"
15797 [(set (reg:CC FLAGS_REG)
15798 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15799 (const_int 0))
15800 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15801 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15802 (const_int 0)))
15803 (use (match_operand:SI 3 "immediate_operand" "i"))
15804 (use (reg:CC FLAGS_REG))
15805 (clobber (match_operand:SI 0 "register_operand" "=S"))
15806 (clobber (match_operand:SI 1 "register_operand" "=D"))
15807 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15808 "!TARGET_64BIT"
15809 "repz{%;} cmpsb"
15810 [(set_attr "type" "str")
15811 (set_attr "mode" "QI")
15812 (set_attr "prefix_rep" "1")])
15813
15814 (define_insn "*cmpstrnqi_rex_1"
15815 [(set (reg:CC FLAGS_REG)
15816 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15817 (const_int 0))
15818 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15819 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15820 (const_int 0)))
15821 (use (match_operand:SI 3 "immediate_operand" "i"))
15822 (use (reg:CC FLAGS_REG))
15823 (clobber (match_operand:DI 0 "register_operand" "=S"))
15824 (clobber (match_operand:DI 1 "register_operand" "=D"))
15825 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15826 "TARGET_64BIT"
15827 "repz{%;} cmpsb"
15828 [(set_attr "type" "str")
15829 (set_attr "mode" "QI")
15830 (set_attr "prefix_rex" "0")
15831 (set_attr "prefix_rep" "1")])
15832
15833 (define_expand "strlensi"
15834 [(set (match_operand:SI 0 "register_operand" "")
15835 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15836 (match_operand:QI 2 "immediate_operand" "")
15837 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15838 ""
15839 {
15840 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15841 DONE;
15842 else
15843 FAIL;
15844 })
15845
15846 (define_expand "strlendi"
15847 [(set (match_operand:DI 0 "register_operand" "")
15848 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15849 (match_operand:QI 2 "immediate_operand" "")
15850 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15851 ""
15852 {
15853 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15854 DONE;
15855 else
15856 FAIL;
15857 })
15858
15859 (define_expand "strlenqi_1"
15860 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15861 (clobber (match_operand 1 "register_operand" ""))
15862 (clobber (reg:CC FLAGS_REG))])]
15863 ""
15864 "ix86_current_function_needs_cld = 1;")
15865
15866 (define_insn "*strlenqi_1"
15867 [(set (match_operand:SI 0 "register_operand" "=&c")
15868 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15869 (match_operand:QI 2 "register_operand" "a")
15870 (match_operand:SI 3 "immediate_operand" "i")
15871 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15872 (clobber (match_operand:SI 1 "register_operand" "=D"))
15873 (clobber (reg:CC FLAGS_REG))]
15874 "!TARGET_64BIT"
15875 "repnz{%;} scasb"
15876 [(set_attr "type" "str")
15877 (set_attr "mode" "QI")
15878 (set_attr "prefix_rep" "1")])
15879
15880 (define_insn "*strlenqi_rex_1"
15881 [(set (match_operand:DI 0 "register_operand" "=&c")
15882 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15883 (match_operand:QI 2 "register_operand" "a")
15884 (match_operand:DI 3 "immediate_operand" "i")
15885 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15886 (clobber (match_operand:DI 1 "register_operand" "=D"))
15887 (clobber (reg:CC FLAGS_REG))]
15888 "TARGET_64BIT"
15889 "repnz{%;} scasb"
15890 [(set_attr "type" "str")
15891 (set_attr "mode" "QI")
15892 (set_attr "prefix_rex" "0")
15893 (set_attr "prefix_rep" "1")])
15894
15895 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15896 ;; handled in combine, but it is not currently up to the task.
15897 ;; When used for their truth value, the cmpstrn* expanders generate
15898 ;; code like this:
15899 ;;
15900 ;; repz cmpsb
15901 ;; seta %al
15902 ;; setb %dl
15903 ;; cmpb %al, %dl
15904 ;; jcc label
15905 ;;
15906 ;; The intermediate three instructions are unnecessary.
15907
15908 ;; This one handles cmpstrn*_nz_1...
15909 (define_peephole2
15910 [(parallel[
15911 (set (reg:CC FLAGS_REG)
15912 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15913 (mem:BLK (match_operand 5 "register_operand" ""))))
15914 (use (match_operand 6 "register_operand" ""))
15915 (use (match_operand:SI 3 "immediate_operand" ""))
15916 (clobber (match_operand 0 "register_operand" ""))
15917 (clobber (match_operand 1 "register_operand" ""))
15918 (clobber (match_operand 2 "register_operand" ""))])
15919 (set (match_operand:QI 7 "register_operand" "")
15920 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15921 (set (match_operand:QI 8 "register_operand" "")
15922 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15923 (set (reg FLAGS_REG)
15924 (compare (match_dup 7) (match_dup 8)))
15925 ]
15926 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15927 [(parallel[
15928 (set (reg:CC FLAGS_REG)
15929 (compare:CC (mem:BLK (match_dup 4))
15930 (mem:BLK (match_dup 5))))
15931 (use (match_dup 6))
15932 (use (match_dup 3))
15933 (clobber (match_dup 0))
15934 (clobber (match_dup 1))
15935 (clobber (match_dup 2))])]
15936 "")
15937
15938 ;; ...and this one handles cmpstrn*_1.
15939 (define_peephole2
15940 [(parallel[
15941 (set (reg:CC FLAGS_REG)
15942 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15943 (const_int 0))
15944 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15945 (mem:BLK (match_operand 5 "register_operand" "")))
15946 (const_int 0)))
15947 (use (match_operand:SI 3 "immediate_operand" ""))
15948 (use (reg:CC FLAGS_REG))
15949 (clobber (match_operand 0 "register_operand" ""))
15950 (clobber (match_operand 1 "register_operand" ""))
15951 (clobber (match_operand 2 "register_operand" ""))])
15952 (set (match_operand:QI 7 "register_operand" "")
15953 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15954 (set (match_operand:QI 8 "register_operand" "")
15955 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15956 (set (reg FLAGS_REG)
15957 (compare (match_dup 7) (match_dup 8)))
15958 ]
15959 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15960 [(parallel[
15961 (set (reg:CC FLAGS_REG)
15962 (if_then_else:CC (ne (match_dup 6)
15963 (const_int 0))
15964 (compare:CC (mem:BLK (match_dup 4))
15965 (mem:BLK (match_dup 5)))
15966 (const_int 0)))
15967 (use (match_dup 3))
15968 (use (reg:CC FLAGS_REG))
15969 (clobber (match_dup 0))
15970 (clobber (match_dup 1))
15971 (clobber (match_dup 2))])]
15972 "")
15973
15974
15975 \f
15976 ;; Conditional move instructions.
15977
15978 (define_expand "mov<mode>cc"
15979 [(set (match_operand:SWIM 0 "register_operand" "")
15980 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
15981 (match_operand:SWIM 2 "general_operand" "")
15982 (match_operand:SWIM 3 "general_operand" "")))]
15983 ""
15984 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15985
15986 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15987 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15988 ;; So just document what we're doing explicitly.
15989
15990 (define_expand "x86_mov<mode>cc_0_m1"
15991 [(parallel
15992 [(set (match_operand:SWI48 0 "register_operand" "")
15993 (if_then_else:SWI48
15994 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15995 [(match_operand 1 "flags_reg_operand" "")
15996 (const_int 0)])
15997 (const_int -1)
15998 (const_int 0)))
15999 (clobber (reg:CC FLAGS_REG))])]
16000 ""
16001 "")
16002
16003 (define_insn "*x86_mov<mode>cc_0_m1"
16004 [(set (match_operand:SWI48 0 "register_operand" "=r")
16005 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16006 [(reg FLAGS_REG) (const_int 0)])
16007 (const_int -1)
16008 (const_int 0)))
16009 (clobber (reg:CC FLAGS_REG))]
16010 ""
16011 "sbb{<imodesuffix>}\t%0, %0"
16012 ; Since we don't have the proper number of operands for an alu insn,
16013 ; fill in all the blanks.
16014 [(set_attr "type" "alu")
16015 (set_attr "use_carry" "1")
16016 (set_attr "pent_pair" "pu")
16017 (set_attr "memory" "none")
16018 (set_attr "imm_disp" "false")
16019 (set_attr "mode" "<MODE>")
16020 (set_attr "length_immediate" "0")])
16021
16022 (define_insn "*x86_mov<mode>cc_0_m1_se"
16023 [(set (match_operand:SWI48 0 "register_operand" "=r")
16024 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16025 [(reg FLAGS_REG) (const_int 0)])
16026 (const_int 1)
16027 (const_int 0)))
16028 (clobber (reg:CC FLAGS_REG))]
16029 ""
16030 "sbb{<imodesuffix>}\t%0, %0"
16031 [(set_attr "type" "alu")
16032 (set_attr "use_carry" "1")
16033 (set_attr "pent_pair" "pu")
16034 (set_attr "memory" "none")
16035 (set_attr "imm_disp" "false")
16036 (set_attr "mode" "<MODE>")
16037 (set_attr "length_immediate" "0")])
16038
16039 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16040 [(set (match_operand:SWI48 0 "register_operand" "=r")
16041 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16042 [(reg FLAGS_REG) (const_int 0)])))]
16043 ""
16044 "sbb{<imodesuffix>}\t%0, %0"
16045 [(set_attr "type" "alu")
16046 (set_attr "use_carry" "1")
16047 (set_attr "pent_pair" "pu")
16048 (set_attr "memory" "none")
16049 (set_attr "imm_disp" "false")
16050 (set_attr "mode" "<MODE>")
16051 (set_attr "length_immediate" "0")])
16052
16053 (define_insn "*mov<mode>cc_noc"
16054 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16055 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16056 [(reg FLAGS_REG) (const_int 0)])
16057 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16058 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16059 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16060 "@
16061 cmov%O2%C1\t{%2, %0|%0, %2}
16062 cmov%O2%c1\t{%3, %0|%0, %3}"
16063 [(set_attr "type" "icmov")
16064 (set_attr "mode" "<MODE>")])
16065
16066 (define_insn_and_split "*movqicc_noc"
16067 [(set (match_operand:QI 0 "register_operand" "=r,r")
16068 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16069 [(match_operand 4 "flags_reg_operand" "")
16070 (const_int 0)])
16071 (match_operand:QI 2 "register_operand" "r,0")
16072 (match_operand:QI 3 "register_operand" "0,r")))]
16073 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16074 "#"
16075 "&& reload_completed"
16076 [(set (match_dup 0)
16077 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16078 (match_dup 2)
16079 (match_dup 3)))]
16080 "operands[0] = gen_lowpart (SImode, operands[0]);
16081 operands[2] = gen_lowpart (SImode, operands[2]);
16082 operands[3] = gen_lowpart (SImode, operands[3]);"
16083 [(set_attr "type" "icmov")
16084 (set_attr "mode" "SI")])
16085
16086 (define_expand "mov<mode>cc"
16087 [(set (match_operand:X87MODEF 0 "register_operand" "")
16088 (if_then_else:X87MODEF
16089 (match_operand 1 "ix86_fp_comparison_operator" "")
16090 (match_operand:X87MODEF 2 "register_operand" "")
16091 (match_operand:X87MODEF 3 "register_operand" "")))]
16092 "(TARGET_80387 && TARGET_CMOVE)
16093 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16094 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16095
16096 (define_insn "*movsfcc_1_387"
16097 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16098 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16099 [(reg FLAGS_REG) (const_int 0)])
16100 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16101 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16102 "TARGET_80387 && TARGET_CMOVE
16103 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16104 "@
16105 fcmov%F1\t{%2, %0|%0, %2}
16106 fcmov%f1\t{%3, %0|%0, %3}
16107 cmov%O2%C1\t{%2, %0|%0, %2}
16108 cmov%O2%c1\t{%3, %0|%0, %3}"
16109 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16110 (set_attr "mode" "SF,SF,SI,SI")])
16111
16112 (define_insn "*movdfcc_1"
16113 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16114 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16115 [(reg FLAGS_REG) (const_int 0)])
16116 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16117 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16118 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16119 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16120 "@
16121 fcmov%F1\t{%2, %0|%0, %2}
16122 fcmov%f1\t{%3, %0|%0, %3}
16123 #
16124 #"
16125 [(set_attr "type" "fcmov,fcmov,multi,multi")
16126 (set_attr "mode" "DF")])
16127
16128 (define_insn "*movdfcc_1_rex64"
16129 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16130 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16131 [(reg FLAGS_REG) (const_int 0)])
16132 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16133 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16134 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16135 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16136 "@
16137 fcmov%F1\t{%2, %0|%0, %2}
16138 fcmov%f1\t{%3, %0|%0, %3}
16139 cmov%O2%C1\t{%2, %0|%0, %2}
16140 cmov%O2%c1\t{%3, %0|%0, %3}"
16141 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16142 (set_attr "mode" "DF")])
16143
16144 (define_split
16145 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16146 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16147 [(match_operand 4 "flags_reg_operand" "")
16148 (const_int 0)])
16149 (match_operand:DF 2 "nonimmediate_operand" "")
16150 (match_operand:DF 3 "nonimmediate_operand" "")))]
16151 "!TARGET_64BIT && reload_completed"
16152 [(set (match_dup 2)
16153 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16154 (match_dup 5)
16155 (match_dup 6)))
16156 (set (match_dup 3)
16157 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16158 (match_dup 7)
16159 (match_dup 8)))]
16160 {
16161 split_di (&operands[2], 2, &operands[5], &operands[7]);
16162 split_di (&operands[0], 1, &operands[2], &operands[3]);
16163 })
16164
16165 (define_insn "*movxfcc_1"
16166 [(set (match_operand:XF 0 "register_operand" "=f,f")
16167 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16168 [(reg FLAGS_REG) (const_int 0)])
16169 (match_operand:XF 2 "register_operand" "f,0")
16170 (match_operand:XF 3 "register_operand" "0,f")))]
16171 "TARGET_80387 && TARGET_CMOVE"
16172 "@
16173 fcmov%F1\t{%2, %0|%0, %2}
16174 fcmov%f1\t{%3, %0|%0, %3}"
16175 [(set_attr "type" "fcmov")
16176 (set_attr "mode" "XF")])
16177
16178 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16179 ;; the scalar versions to have only XMM registers as operands.
16180
16181 ;; XOP conditional move
16182 (define_insn "*xop_pcmov_<mode>"
16183 [(set (match_operand:MODEF 0 "register_operand" "=x")
16184 (if_then_else:MODEF
16185 (match_operand:MODEF 1 "register_operand" "x")
16186 (match_operand:MODEF 2 "register_operand" "x")
16187 (match_operand:MODEF 3 "register_operand" "x")))]
16188 "TARGET_XOP"
16189 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16190 [(set_attr "type" "sse4arg")])
16191
16192 ;; These versions of the min/max patterns are intentionally ignorant of
16193 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16194 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16195 ;; are undefined in this condition, we're certain this is correct.
16196
16197 (define_insn "*avx_<code><mode>3"
16198 [(set (match_operand:MODEF 0 "register_operand" "=x")
16199 (smaxmin:MODEF
16200 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16201 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16202 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16203 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16204 [(set_attr "type" "sseadd")
16205 (set_attr "prefix" "vex")
16206 (set_attr "mode" "<MODE>")])
16207
16208 (define_insn "<code><mode>3"
16209 [(set (match_operand:MODEF 0 "register_operand" "=x")
16210 (smaxmin:MODEF
16211 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16212 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16213 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16214 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16215 [(set_attr "type" "sseadd")
16216 (set_attr "mode" "<MODE>")])
16217
16218 ;; These versions of the min/max patterns implement exactly the operations
16219 ;; min = (op1 < op2 ? op1 : op2)
16220 ;; max = (!(op1 < op2) ? op1 : op2)
16221 ;; Their operands are not commutative, and thus they may be used in the
16222 ;; presence of -0.0 and NaN.
16223
16224 (define_insn "*avx_ieee_smin<mode>3"
16225 [(set (match_operand:MODEF 0 "register_operand" "=x")
16226 (unspec:MODEF
16227 [(match_operand:MODEF 1 "register_operand" "x")
16228 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16229 UNSPEC_IEEE_MIN))]
16230 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16231 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16232 [(set_attr "type" "sseadd")
16233 (set_attr "prefix" "vex")
16234 (set_attr "mode" "<MODE>")])
16235
16236 (define_insn "*ieee_smin<mode>3"
16237 [(set (match_operand:MODEF 0 "register_operand" "=x")
16238 (unspec:MODEF
16239 [(match_operand:MODEF 1 "register_operand" "0")
16240 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16241 UNSPEC_IEEE_MIN))]
16242 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16243 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16244 [(set_attr "type" "sseadd")
16245 (set_attr "mode" "<MODE>")])
16246
16247 (define_insn "*avx_ieee_smax<mode>3"
16248 [(set (match_operand:MODEF 0 "register_operand" "=x")
16249 (unspec:MODEF
16250 [(match_operand:MODEF 1 "register_operand" "0")
16251 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16252 UNSPEC_IEEE_MAX))]
16253 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16254 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16255 [(set_attr "type" "sseadd")
16256 (set_attr "prefix" "vex")
16257 (set_attr "mode" "<MODE>")])
16258
16259 (define_insn "*ieee_smax<mode>3"
16260 [(set (match_operand:MODEF 0 "register_operand" "=x")
16261 (unspec:MODEF
16262 [(match_operand:MODEF 1 "register_operand" "0")
16263 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16264 UNSPEC_IEEE_MAX))]
16265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16266 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16267 [(set_attr "type" "sseadd")
16268 (set_attr "mode" "<MODE>")])
16269
16270 ;; Make two stack loads independent:
16271 ;; fld aa fld aa
16272 ;; fld %st(0) -> fld bb
16273 ;; fmul bb fmul %st(1), %st
16274 ;;
16275 ;; Actually we only match the last two instructions for simplicity.
16276 (define_peephole2
16277 [(set (match_operand 0 "fp_register_operand" "")
16278 (match_operand 1 "fp_register_operand" ""))
16279 (set (match_dup 0)
16280 (match_operator 2 "binary_fp_operator"
16281 [(match_dup 0)
16282 (match_operand 3 "memory_operand" "")]))]
16283 "REGNO (operands[0]) != REGNO (operands[1])"
16284 [(set (match_dup 0) (match_dup 3))
16285 (set (match_dup 0) (match_dup 4))]
16286
16287 ;; The % modifier is not operational anymore in peephole2's, so we have to
16288 ;; swap the operands manually in the case of addition and multiplication.
16289 "if (COMMUTATIVE_ARITH_P (operands[2]))
16290 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16291 operands[0], operands[1]);
16292 else
16293 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16294 operands[1], operands[0]);")
16295
16296 ;; Conditional addition patterns
16297 (define_expand "add<mode>cc"
16298 [(match_operand:SWI 0 "register_operand" "")
16299 (match_operand 1 "comparison_operator" "")
16300 (match_operand:SWI 2 "register_operand" "")
16301 (match_operand:SWI 3 "const_int_operand" "")]
16302 ""
16303 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16304
16305 \f
16306 ;; Misc patterns (?)
16307
16308 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16309 ;; Otherwise there will be nothing to keep
16310 ;;
16311 ;; [(set (reg ebp) (reg esp))]
16312 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16313 ;; (clobber (eflags)]
16314 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16315 ;;
16316 ;; in proper program order.
16317 (define_insn "pro_epilogue_adjust_stack_1"
16318 [(set (match_operand:SI 0 "register_operand" "=r,r")
16319 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
16320 (match_operand:SI 2 "immediate_operand" "i,i")))
16321 (clobber (reg:CC FLAGS_REG))
16322 (clobber (mem:BLK (scratch)))]
16323 "!TARGET_64BIT"
16324 {
16325 switch (get_attr_type (insn))
16326 {
16327 case TYPE_IMOV:
16328 return "mov{l}\t{%1, %0|%0, %1}";
16329
16330 case TYPE_ALU:
16331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16332 if (x86_maybe_negate_const_int (&operands[2], SImode))
16333 return "sub{l}\t{%2, %0|%0, %2}";
16334
16335 return "add{l}\t{%2, %0|%0, %2}";
16336
16337 default:
16338 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16339 return "lea{l}\t{%a2, %0|%0, %a2}";
16340 }
16341 }
16342 [(set (attr "type")
16343 (cond [(and (eq_attr "alternative" "0")
16344 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16345 (const_string "alu")
16346 (match_operand:SI 2 "const0_operand" "")
16347 (const_string "imov")
16348 ]
16349 (const_string "lea")))
16350 (set (attr "length_immediate")
16351 (cond [(eq_attr "type" "imov")
16352 (const_string "0")
16353 (and (eq_attr "type" "alu")
16354 (match_operand 2 "const128_operand" ""))
16355 (const_string "1")
16356 ]
16357 (const_string "*")))
16358 (set_attr "mode" "SI")])
16359
16360 (define_insn "pro_epilogue_adjust_stack_rex64"
16361 [(set (match_operand:DI 0 "register_operand" "=r,r")
16362 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16363 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
16364 (clobber (reg:CC FLAGS_REG))
16365 (clobber (mem:BLK (scratch)))]
16366 "TARGET_64BIT"
16367 {
16368 switch (get_attr_type (insn))
16369 {
16370 case TYPE_IMOV:
16371 return "mov{q}\t{%1, %0|%0, %1}";
16372
16373 case TYPE_ALU:
16374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16375 if (x86_maybe_negate_const_int (&operands[2], DImode))
16376 return "sub{q}\t{%2, %0|%0, %2}";
16377
16378 return "add{q}\t{%2, %0|%0, %2}";
16379
16380 default:
16381 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16382 return "lea{q}\t{%a2, %0|%0, %a2}";
16383 }
16384 }
16385 [(set (attr "type")
16386 (cond [(and (eq_attr "alternative" "0")
16387 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16388 (const_string "alu")
16389 (match_operand:DI 2 "const0_operand" "")
16390 (const_string "imov")
16391 ]
16392 (const_string "lea")))
16393 (set (attr "length_immediate")
16394 (cond [(eq_attr "type" "imov")
16395 (const_string "0")
16396 (and (eq_attr "type" "alu")
16397 (match_operand 2 "const128_operand" ""))
16398 (const_string "1")
16399 ]
16400 (const_string "*")))
16401 (set_attr "mode" "DI")])
16402
16403 (define_insn "pro_epilogue_adjust_stack_rex64_2"
16404 [(set (match_operand:DI 0 "register_operand" "=r,r")
16405 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16406 (match_operand:DI 3 "immediate_operand" "i,i")))
16407 (use (match_operand:DI 2 "register_operand" "r,r"))
16408 (clobber (reg:CC FLAGS_REG))
16409 (clobber (mem:BLK (scratch)))]
16410 "TARGET_64BIT"
16411 {
16412 switch (get_attr_type (insn))
16413 {
16414 case TYPE_ALU:
16415 return "add{q}\t{%2, %0|%0, %2}";
16416
16417 case TYPE_LEA:
16418 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16419 return "lea{q}\t{%a2, %0|%0, %a2}";
16420
16421 default:
16422 gcc_unreachable ();
16423 }
16424 }
16425 [(set_attr "type" "alu,lea")
16426 (set_attr "mode" "DI")])
16427
16428 (define_insn "allocate_stack_worker_32"
16429 [(set (match_operand:SI 0 "register_operand" "=a")
16430 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16431 UNSPECV_STACK_PROBE))
16432 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16433 (clobber (reg:CC FLAGS_REG))]
16434 "!TARGET_64BIT && TARGET_STACK_PROBE"
16435 "call\t___chkstk"
16436 [(set_attr "type" "multi")
16437 (set_attr "length" "5")])
16438
16439 (define_insn "allocate_stack_worker_64"
16440 [(set (match_operand:DI 0 "register_operand" "=a")
16441 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16442 UNSPECV_STACK_PROBE))
16443 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16444 (clobber (reg:DI R10_REG))
16445 (clobber (reg:DI R11_REG))
16446 (clobber (reg:CC FLAGS_REG))]
16447 "TARGET_64BIT && TARGET_STACK_PROBE"
16448 "call\t___chkstk"
16449 [(set_attr "type" "multi")
16450 (set_attr "length" "5")])
16451
16452 (define_expand "allocate_stack"
16453 [(match_operand 0 "register_operand" "")
16454 (match_operand 1 "general_operand" "")]
16455 "TARGET_STACK_PROBE"
16456 {
16457 rtx x;
16458
16459 #ifndef CHECK_STACK_LIMIT
16460 #define CHECK_STACK_LIMIT 0
16461 #endif
16462
16463 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16464 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16465 {
16466 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16467 stack_pointer_rtx, 0, OPTAB_DIRECT);
16468 if (x != stack_pointer_rtx)
16469 emit_move_insn (stack_pointer_rtx, x);
16470 }
16471 else
16472 {
16473 x = copy_to_mode_reg (Pmode, operands[1]);
16474 if (TARGET_64BIT)
16475 x = gen_allocate_stack_worker_64 (x, x);
16476 else
16477 x = gen_allocate_stack_worker_32 (x, x);
16478 emit_insn (x);
16479 }
16480
16481 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16482 DONE;
16483 })
16484
16485 ;; Use IOR for stack probes, this is shorter.
16486 (define_expand "probe_stack"
16487 [(match_operand 0 "memory_operand" "")]
16488 ""
16489 {
16490 if (GET_MODE (operands[0]) == DImode)
16491 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
16492 else
16493 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
16494 DONE;
16495 })
16496
16497 (define_expand "builtin_setjmp_receiver"
16498 [(label_ref (match_operand 0 "" ""))]
16499 "!TARGET_64BIT && flag_pic"
16500 {
16501 #if TARGET_MACHO
16502 if (TARGET_MACHO)
16503 {
16504 rtx xops[3];
16505 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16506 rtx label_rtx = gen_label_rtx ();
16507 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16508 xops[0] = xops[1] = picreg;
16509 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16510 ix86_expand_binary_operator (MINUS, SImode, xops);
16511 }
16512 else
16513 #endif
16514 emit_insn (gen_set_got (pic_offset_table_rtx));
16515 DONE;
16516 })
16517 \f
16518 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16519
16520 (define_split
16521 [(set (match_operand 0 "register_operand" "")
16522 (match_operator 3 "promotable_binary_operator"
16523 [(match_operand 1 "register_operand" "")
16524 (match_operand 2 "aligned_operand" "")]))
16525 (clobber (reg:CC FLAGS_REG))]
16526 "! TARGET_PARTIAL_REG_STALL && reload_completed
16527 && ((GET_MODE (operands[0]) == HImode
16528 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16529 /* ??? next two lines just !satisfies_constraint_K (...) */
16530 || !CONST_INT_P (operands[2])
16531 || satisfies_constraint_K (operands[2])))
16532 || (GET_MODE (operands[0]) == QImode
16533 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16534 [(parallel [(set (match_dup 0)
16535 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16536 (clobber (reg:CC FLAGS_REG))])]
16537 "operands[0] = gen_lowpart (SImode, operands[0]);
16538 operands[1] = gen_lowpart (SImode, operands[1]);
16539 if (GET_CODE (operands[3]) != ASHIFT)
16540 operands[2] = gen_lowpart (SImode, operands[2]);
16541 PUT_MODE (operands[3], SImode);")
16542
16543 ; Promote the QImode tests, as i386 has encoding of the AND
16544 ; instruction with 32-bit sign-extended immediate and thus the
16545 ; instruction size is unchanged, except in the %eax case for
16546 ; which it is increased by one byte, hence the ! optimize_size.
16547 (define_split
16548 [(set (match_operand 0 "flags_reg_operand" "")
16549 (match_operator 2 "compare_operator"
16550 [(and (match_operand 3 "aligned_operand" "")
16551 (match_operand 4 "const_int_operand" ""))
16552 (const_int 0)]))
16553 (set (match_operand 1 "register_operand" "")
16554 (and (match_dup 3) (match_dup 4)))]
16555 "! TARGET_PARTIAL_REG_STALL && reload_completed
16556 && optimize_insn_for_speed_p ()
16557 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16558 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16559 /* Ensure that the operand will remain sign-extended immediate. */
16560 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16561 [(parallel [(set (match_dup 0)
16562 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16563 (const_int 0)]))
16564 (set (match_dup 1)
16565 (and:SI (match_dup 3) (match_dup 4)))])]
16566 {
16567 operands[4]
16568 = gen_int_mode (INTVAL (operands[4])
16569 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16570 operands[1] = gen_lowpart (SImode, operands[1]);
16571 operands[3] = gen_lowpart (SImode, operands[3]);
16572 })
16573
16574 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16575 ; the TEST instruction with 32-bit sign-extended immediate and thus
16576 ; the instruction size would at least double, which is not what we
16577 ; want even with ! optimize_size.
16578 (define_split
16579 [(set (match_operand 0 "flags_reg_operand" "")
16580 (match_operator 1 "compare_operator"
16581 [(and (match_operand:HI 2 "aligned_operand" "")
16582 (match_operand:HI 3 "const_int_operand" ""))
16583 (const_int 0)]))]
16584 "! TARGET_PARTIAL_REG_STALL && reload_completed
16585 && ! TARGET_FAST_PREFIX
16586 && optimize_insn_for_speed_p ()
16587 /* Ensure that the operand will remain sign-extended immediate. */
16588 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16589 [(set (match_dup 0)
16590 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16591 (const_int 0)]))]
16592 {
16593 operands[3]
16594 = gen_int_mode (INTVAL (operands[3])
16595 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16596 operands[2] = gen_lowpart (SImode, operands[2]);
16597 })
16598
16599 (define_split
16600 [(set (match_operand 0 "register_operand" "")
16601 (neg (match_operand 1 "register_operand" "")))
16602 (clobber (reg:CC FLAGS_REG))]
16603 "! TARGET_PARTIAL_REG_STALL && reload_completed
16604 && (GET_MODE (operands[0]) == HImode
16605 || (GET_MODE (operands[0]) == QImode
16606 && (TARGET_PROMOTE_QImode
16607 || optimize_insn_for_size_p ())))"
16608 [(parallel [(set (match_dup 0)
16609 (neg:SI (match_dup 1)))
16610 (clobber (reg:CC FLAGS_REG))])]
16611 "operands[0] = gen_lowpart (SImode, operands[0]);
16612 operands[1] = gen_lowpart (SImode, operands[1]);")
16613
16614 (define_split
16615 [(set (match_operand 0 "register_operand" "")
16616 (not (match_operand 1 "register_operand" "")))]
16617 "! TARGET_PARTIAL_REG_STALL && reload_completed
16618 && (GET_MODE (operands[0]) == HImode
16619 || (GET_MODE (operands[0]) == QImode
16620 && (TARGET_PROMOTE_QImode
16621 || optimize_insn_for_size_p ())))"
16622 [(set (match_dup 0)
16623 (not:SI (match_dup 1)))]
16624 "operands[0] = gen_lowpart (SImode, operands[0]);
16625 operands[1] = gen_lowpart (SImode, operands[1]);")
16626
16627 (define_split
16628 [(set (match_operand 0 "register_operand" "")
16629 (if_then_else (match_operator 1 "comparison_operator"
16630 [(reg FLAGS_REG) (const_int 0)])
16631 (match_operand 2 "register_operand" "")
16632 (match_operand 3 "register_operand" "")))]
16633 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16634 && (GET_MODE (operands[0]) == HImode
16635 || (GET_MODE (operands[0]) == QImode
16636 && (TARGET_PROMOTE_QImode
16637 || optimize_insn_for_size_p ())))"
16638 [(set (match_dup 0)
16639 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16640 "operands[0] = gen_lowpart (SImode, operands[0]);
16641 operands[2] = gen_lowpart (SImode, operands[2]);
16642 operands[3] = gen_lowpart (SImode, operands[3]);")
16643
16644 \f
16645 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16646 ;; transform a complex memory operation into two memory to register operations.
16647
16648 ;; Don't push memory operands
16649 (define_peephole2
16650 [(set (match_operand:SI 0 "push_operand" "")
16651 (match_operand:SI 1 "memory_operand" ""))
16652 (match_scratch:SI 2 "r")]
16653 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16654 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16655 [(set (match_dup 2) (match_dup 1))
16656 (set (match_dup 0) (match_dup 2))]
16657 "")
16658
16659 (define_peephole2
16660 [(set (match_operand:DI 0 "push_operand" "")
16661 (match_operand:DI 1 "memory_operand" ""))
16662 (match_scratch:DI 2 "r")]
16663 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16664 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16665 [(set (match_dup 2) (match_dup 1))
16666 (set (match_dup 0) (match_dup 2))]
16667 "")
16668
16669 ;; We need to handle SFmode only, because DFmode and XFmode is split to
16670 ;; SImode pushes.
16671 (define_peephole2
16672 [(set (match_operand:SF 0 "push_operand" "")
16673 (match_operand:SF 1 "memory_operand" ""))
16674 (match_scratch:SF 2 "r")]
16675 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16676 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16677 [(set (match_dup 2) (match_dup 1))
16678 (set (match_dup 0) (match_dup 2))]
16679 "")
16680
16681 (define_peephole2
16682 [(set (match_operand:HI 0 "push_operand" "")
16683 (match_operand:HI 1 "memory_operand" ""))
16684 (match_scratch:HI 2 "r")]
16685 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16686 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16687 [(set (match_dup 2) (match_dup 1))
16688 (set (match_dup 0) (match_dup 2))]
16689 "")
16690
16691 (define_peephole2
16692 [(set (match_operand:QI 0 "push_operand" "")
16693 (match_operand:QI 1 "memory_operand" ""))
16694 (match_scratch:QI 2 "q")]
16695 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16696 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16697 [(set (match_dup 2) (match_dup 1))
16698 (set (match_dup 0) (match_dup 2))]
16699 "")
16700
16701 ;; Don't move an immediate directly to memory when the instruction
16702 ;; gets too big.
16703 (define_peephole2
16704 [(match_scratch:SI 1 "r")
16705 (set (match_operand:SI 0 "memory_operand" "")
16706 (const_int 0))]
16707 "optimize_insn_for_speed_p ()
16708 && ! TARGET_USE_MOV0
16709 && TARGET_SPLIT_LONG_MOVES
16710 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16711 && peep2_regno_dead_p (0, FLAGS_REG)"
16712 [(parallel [(set (match_dup 1) (const_int 0))
16713 (clobber (reg:CC FLAGS_REG))])
16714 (set (match_dup 0) (match_dup 1))]
16715 "")
16716
16717 (define_peephole2
16718 [(match_scratch:HI 1 "r")
16719 (set (match_operand:HI 0 "memory_operand" "")
16720 (const_int 0))]
16721 "optimize_insn_for_speed_p ()
16722 && ! TARGET_USE_MOV0
16723 && TARGET_SPLIT_LONG_MOVES
16724 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16725 && peep2_regno_dead_p (0, FLAGS_REG)"
16726 [(parallel [(set (match_dup 2) (const_int 0))
16727 (clobber (reg:CC FLAGS_REG))])
16728 (set (match_dup 0) (match_dup 1))]
16729 "operands[2] = gen_lowpart (SImode, operands[1]);")
16730
16731 (define_peephole2
16732 [(match_scratch:QI 1 "q")
16733 (set (match_operand:QI 0 "memory_operand" "")
16734 (const_int 0))]
16735 "optimize_insn_for_speed_p ()
16736 && ! TARGET_USE_MOV0
16737 && TARGET_SPLIT_LONG_MOVES
16738 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16739 && peep2_regno_dead_p (0, FLAGS_REG)"
16740 [(parallel [(set (match_dup 2) (const_int 0))
16741 (clobber (reg:CC FLAGS_REG))])
16742 (set (match_dup 0) (match_dup 1))]
16743 "operands[2] = gen_lowpart (SImode, operands[1]);")
16744
16745 (define_peephole2
16746 [(match_scratch:SI 2 "r")
16747 (set (match_operand:SI 0 "memory_operand" "")
16748 (match_operand:SI 1 "immediate_operand" ""))]
16749 "optimize_insn_for_speed_p ()
16750 && TARGET_SPLIT_LONG_MOVES
16751 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16752 [(set (match_dup 2) (match_dup 1))
16753 (set (match_dup 0) (match_dup 2))]
16754 "")
16755
16756 (define_peephole2
16757 [(match_scratch:HI 2 "r")
16758 (set (match_operand:HI 0 "memory_operand" "")
16759 (match_operand:HI 1 "immediate_operand" ""))]
16760 "optimize_insn_for_speed_p ()
16761 && TARGET_SPLIT_LONG_MOVES
16762 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16763 [(set (match_dup 2) (match_dup 1))
16764 (set (match_dup 0) (match_dup 2))]
16765 "")
16766
16767 (define_peephole2
16768 [(match_scratch:QI 2 "q")
16769 (set (match_operand:QI 0 "memory_operand" "")
16770 (match_operand:QI 1 "immediate_operand" ""))]
16771 "optimize_insn_for_speed_p ()
16772 && TARGET_SPLIT_LONG_MOVES
16773 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16774 [(set (match_dup 2) (match_dup 1))
16775 (set (match_dup 0) (match_dup 2))]
16776 "")
16777
16778 ;; Don't compare memory with zero, load and use a test instead.
16779 (define_peephole2
16780 [(set (match_operand 0 "flags_reg_operand" "")
16781 (match_operator 1 "compare_operator"
16782 [(match_operand:SI 2 "memory_operand" "")
16783 (const_int 0)]))
16784 (match_scratch:SI 3 "r")]
16785 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16786 [(set (match_dup 3) (match_dup 2))
16787 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
16788 "")
16789
16790 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16791 ;; Don't split NOTs with a displacement operand, because resulting XOR
16792 ;; will not be pairable anyway.
16793 ;;
16794 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16795 ;; represented using a modRM byte. The XOR replacement is long decoded,
16796 ;; so this split helps here as well.
16797 ;;
16798 ;; Note: Can't do this as a regular split because we can't get proper
16799 ;; lifetime information then.
16800
16801 (define_peephole2
16802 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16803 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
16804 "optimize_insn_for_speed_p ()
16805 && ((TARGET_NOT_UNPAIRABLE
16806 && (!MEM_P (operands[0])
16807 || !memory_displacement_operand (operands[0], SImode)))
16808 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
16809 && peep2_regno_dead_p (0, FLAGS_REG)"
16810 [(parallel [(set (match_dup 0)
16811 (xor:SI (match_dup 1) (const_int -1)))
16812 (clobber (reg:CC FLAGS_REG))])]
16813 "")
16814
16815 (define_peephole2
16816 [(set (match_operand:HI 0 "nonimmediate_operand" "")
16817 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
16818 "optimize_insn_for_speed_p ()
16819 && ((TARGET_NOT_UNPAIRABLE
16820 && (!MEM_P (operands[0])
16821 || !memory_displacement_operand (operands[0], HImode)))
16822 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
16823 && peep2_regno_dead_p (0, FLAGS_REG)"
16824 [(parallel [(set (match_dup 0)
16825 (xor:HI (match_dup 1) (const_int -1)))
16826 (clobber (reg:CC FLAGS_REG))])]
16827 "")
16828
16829 (define_peephole2
16830 [(set (match_operand:QI 0 "nonimmediate_operand" "")
16831 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
16832 "optimize_insn_for_speed_p ()
16833 && ((TARGET_NOT_UNPAIRABLE
16834 && (!MEM_P (operands[0])
16835 || !memory_displacement_operand (operands[0], QImode)))
16836 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
16837 && peep2_regno_dead_p (0, FLAGS_REG)"
16838 [(parallel [(set (match_dup 0)
16839 (xor:QI (match_dup 1) (const_int -1)))
16840 (clobber (reg:CC FLAGS_REG))])]
16841 "")
16842
16843 ;; Non pairable "test imm, reg" instructions can be translated to
16844 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16845 ;; byte opcode instead of two, have a short form for byte operands),
16846 ;; so do it for other CPUs as well. Given that the value was dead,
16847 ;; this should not create any new dependencies. Pass on the sub-word
16848 ;; versions if we're concerned about partial register stalls.
16849
16850 (define_peephole2
16851 [(set (match_operand 0 "flags_reg_operand" "")
16852 (match_operator 1 "compare_operator"
16853 [(and:SI (match_operand:SI 2 "register_operand" "")
16854 (match_operand:SI 3 "immediate_operand" ""))
16855 (const_int 0)]))]
16856 "ix86_match_ccmode (insn, CCNOmode)
16857 && (true_regnum (operands[2]) != AX_REG
16858 || satisfies_constraint_K (operands[3]))
16859 && peep2_reg_dead_p (1, operands[2])"
16860 [(parallel
16861 [(set (match_dup 0)
16862 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16863 (const_int 0)]))
16864 (set (match_dup 2)
16865 (and:SI (match_dup 2) (match_dup 3)))])]
16866 "")
16867
16868 ;; We don't need to handle HImode case, because it will be promoted to SImode
16869 ;; on ! TARGET_PARTIAL_REG_STALL
16870
16871 (define_peephole2
16872 [(set (match_operand 0 "flags_reg_operand" "")
16873 (match_operator 1 "compare_operator"
16874 [(and:QI (match_operand:QI 2 "register_operand" "")
16875 (match_operand:QI 3 "immediate_operand" ""))
16876 (const_int 0)]))]
16877 "! TARGET_PARTIAL_REG_STALL
16878 && ix86_match_ccmode (insn, CCNOmode)
16879 && true_regnum (operands[2]) != AX_REG
16880 && peep2_reg_dead_p (1, operands[2])"
16881 [(parallel
16882 [(set (match_dup 0)
16883 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16884 (const_int 0)]))
16885 (set (match_dup 2)
16886 (and:QI (match_dup 2) (match_dup 3)))])]
16887 "")
16888
16889 (define_peephole2
16890 [(set (match_operand 0 "flags_reg_operand" "")
16891 (match_operator 1 "compare_operator"
16892 [(and:SI
16893 (zero_extract:SI
16894 (match_operand 2 "ext_register_operand" "")
16895 (const_int 8)
16896 (const_int 8))
16897 (match_operand 3 "const_int_operand" ""))
16898 (const_int 0)]))]
16899 "! TARGET_PARTIAL_REG_STALL
16900 && ix86_match_ccmode (insn, CCNOmode)
16901 && true_regnum (operands[2]) != AX_REG
16902 && peep2_reg_dead_p (1, operands[2])"
16903 [(parallel [(set (match_dup 0)
16904 (match_op_dup 1
16905 [(and:SI
16906 (zero_extract:SI
16907 (match_dup 2)
16908 (const_int 8)
16909 (const_int 8))
16910 (match_dup 3))
16911 (const_int 0)]))
16912 (set (zero_extract:SI (match_dup 2)
16913 (const_int 8)
16914 (const_int 8))
16915 (and:SI
16916 (zero_extract:SI
16917 (match_dup 2)
16918 (const_int 8)
16919 (const_int 8))
16920 (match_dup 3)))])]
16921 "")
16922
16923 ;; Don't do logical operations with memory inputs.
16924 (define_peephole2
16925 [(match_scratch:SI 2 "r")
16926 (parallel [(set (match_operand:SI 0 "register_operand" "")
16927 (match_operator:SI 3 "arith_or_logical_operator"
16928 [(match_dup 0)
16929 (match_operand:SI 1 "memory_operand" "")]))
16930 (clobber (reg:CC FLAGS_REG))])]
16931 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16932 [(set (match_dup 2) (match_dup 1))
16933 (parallel [(set (match_dup 0)
16934 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16935 (clobber (reg:CC FLAGS_REG))])]
16936 "")
16937
16938 (define_peephole2
16939 [(match_scratch:SI 2 "r")
16940 (parallel [(set (match_operand:SI 0 "register_operand" "")
16941 (match_operator:SI 3 "arith_or_logical_operator"
16942 [(match_operand:SI 1 "memory_operand" "")
16943 (match_dup 0)]))
16944 (clobber (reg:CC FLAGS_REG))])]
16945 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16946 [(set (match_dup 2) (match_dup 1))
16947 (parallel [(set (match_dup 0)
16948 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16949 (clobber (reg:CC FLAGS_REG))])]
16950 "")
16951
16952 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16953 ;; refers to the destination of the load!
16954
16955 (define_peephole2
16956 [(set (match_operand:SI 0 "register_operand" "")
16957 (match_operand:SI 1 "register_operand" ""))
16958 (parallel [(set (match_dup 0)
16959 (match_operator:SI 3 "commutative_operator"
16960 [(match_dup 0)
16961 (match_operand:SI 2 "memory_operand" "")]))
16962 (clobber (reg:CC FLAGS_REG))])]
16963 "REGNO (operands[0]) != REGNO (operands[1])
16964 && GENERAL_REGNO_P (REGNO (operands[0]))
16965 && GENERAL_REGNO_P (REGNO (operands[1]))"
16966 [(set (match_dup 0) (match_dup 4))
16967 (parallel [(set (match_dup 0)
16968 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16969 (clobber (reg:CC FLAGS_REG))])]
16970 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16971
16972 (define_peephole2
16973 [(set (match_operand 0 "register_operand" "")
16974 (match_operand 1 "register_operand" ""))
16975 (set (match_dup 0)
16976 (match_operator 3 "commutative_operator"
16977 [(match_dup 0)
16978 (match_operand 2 "memory_operand" "")]))]
16979 "REGNO (operands[0]) != REGNO (operands[1])
16980 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16981 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16982 [(set (match_dup 0) (match_dup 2))
16983 (set (match_dup 0)
16984 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
16985 "")
16986
16987 ; Don't do logical operations with memory outputs
16988 ;
16989 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16990 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16991 ; the same decoder scheduling characteristics as the original.
16992
16993 (define_peephole2
16994 [(match_scratch:SI 2 "r")
16995 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16996 (match_operator:SI 3 "arith_or_logical_operator"
16997 [(match_dup 0)
16998 (match_operand:SI 1 "nonmemory_operand" "")]))
16999 (clobber (reg:CC FLAGS_REG))])]
17000 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17001 /* Do not split stack checking probes. */
17002 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17003 [(set (match_dup 2) (match_dup 0))
17004 (parallel [(set (match_dup 2)
17005 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17006 (clobber (reg:CC FLAGS_REG))])
17007 (set (match_dup 0) (match_dup 2))]
17008 "")
17009
17010 (define_peephole2
17011 [(match_scratch:SI 2 "r")
17012 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17013 (match_operator:SI 3 "arith_or_logical_operator"
17014 [(match_operand:SI 1 "nonmemory_operand" "")
17015 (match_dup 0)]))
17016 (clobber (reg:CC FLAGS_REG))])]
17017 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17018 /* Do not split stack checking probes. */
17019 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17020 [(set (match_dup 2) (match_dup 0))
17021 (parallel [(set (match_dup 2)
17022 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17023 (clobber (reg:CC FLAGS_REG))])
17024 (set (match_dup 0) (match_dup 2))]
17025 "")
17026
17027 ;; Attempt to always use XOR for zeroing registers.
17028 (define_peephole2
17029 [(set (match_operand 0 "register_operand" "")
17030 (match_operand 1 "const0_operand" ""))]
17031 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17032 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17033 && GENERAL_REG_P (operands[0])
17034 && peep2_regno_dead_p (0, FLAGS_REG)"
17035 [(parallel [(set (match_dup 0) (const_int 0))
17036 (clobber (reg:CC FLAGS_REG))])]
17037 {
17038 operands[0] = gen_lowpart (word_mode, operands[0]);
17039 })
17040
17041 (define_peephole2
17042 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17043 (const_int 0))]
17044 "(GET_MODE (operands[0]) == QImode
17045 || GET_MODE (operands[0]) == HImode)
17046 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17047 && peep2_regno_dead_p (0, FLAGS_REG)"
17048 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17049 (clobber (reg:CC FLAGS_REG))])])
17050
17051 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17052 (define_peephole2
17053 [(set (match_operand 0 "register_operand" "")
17054 (const_int -1))]
17055 "(GET_MODE (operands[0]) == HImode
17056 || GET_MODE (operands[0]) == SImode
17057 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17058 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17059 && peep2_regno_dead_p (0, FLAGS_REG)"
17060 [(parallel [(set (match_dup 0) (const_int -1))
17061 (clobber (reg:CC FLAGS_REG))])]
17062 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17063 operands[0]);")
17064
17065 ;; Attempt to convert simple leas to adds. These can be created by
17066 ;; move expanders.
17067 (define_peephole2
17068 [(set (match_operand:SI 0 "register_operand" "")
17069 (plus:SI (match_dup 0)
17070 (match_operand:SI 1 "nonmemory_operand" "")))]
17071 "peep2_regno_dead_p (0, FLAGS_REG)"
17072 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17073 (clobber (reg:CC FLAGS_REG))])]
17074 "")
17075
17076 (define_peephole2
17077 [(set (match_operand:SI 0 "register_operand" "")
17078 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17079 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17080 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17081 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17082 (clobber (reg:CC FLAGS_REG))])]
17083 "operands[2] = gen_lowpart (SImode, operands[2]);")
17084
17085 (define_peephole2
17086 [(set (match_operand:DI 0 "register_operand" "")
17087 (plus:DI (match_dup 0)
17088 (match_operand:DI 1 "x86_64_general_operand" "")))]
17089 "peep2_regno_dead_p (0, FLAGS_REG)"
17090 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17091 (clobber (reg:CC FLAGS_REG))])]
17092 "")
17093
17094 (define_peephole2
17095 [(set (match_operand:SI 0 "register_operand" "")
17096 (mult:SI (match_dup 0)
17097 (match_operand:SI 1 "const_int_operand" "")))]
17098 "exact_log2 (INTVAL (operands[1])) >= 0
17099 && peep2_regno_dead_p (0, FLAGS_REG)"
17100 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17101 (clobber (reg:CC FLAGS_REG))])]
17102 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17103
17104 (define_peephole2
17105 [(set (match_operand:DI 0 "register_operand" "")
17106 (mult:DI (match_dup 0)
17107 (match_operand:DI 1 "const_int_operand" "")))]
17108 "exact_log2 (INTVAL (operands[1])) >= 0
17109 && peep2_regno_dead_p (0, FLAGS_REG)"
17110 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17111 (clobber (reg:CC FLAGS_REG))])]
17112 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17113
17114 (define_peephole2
17115 [(set (match_operand:SI 0 "register_operand" "")
17116 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17117 (match_operand:DI 2 "const_int_operand" "")) 0))]
17118 "exact_log2 (INTVAL (operands[2])) >= 0
17119 && REGNO (operands[0]) == REGNO (operands[1])
17120 && peep2_regno_dead_p (0, FLAGS_REG)"
17121 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17124
17125 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17126 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
17127 ;; many CPUs it is also faster, since special hardware to avoid esp
17128 ;; dependencies is present.
17129
17130 ;; While some of these conversions may be done using splitters, we use peepholes
17131 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17132
17133 ;; Convert prologue esp subtractions to push.
17134 ;; We need register to push. In order to keep verify_flow_info happy we have
17135 ;; two choices
17136 ;; - use scratch and clobber it in order to avoid dependencies
17137 ;; - use already live register
17138 ;; We can't use the second way right now, since there is no reliable way how to
17139 ;; verify that given register is live. First choice will also most likely in
17140 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17141 ;; call clobbered registers are dead. We may want to use base pointer as an
17142 ;; alternative when no register is available later.
17143
17144 (define_peephole2
17145 [(match_scratch:SI 0 "r")
17146 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17147 (clobber (reg:CC FLAGS_REG))
17148 (clobber (mem:BLK (scratch)))])]
17149 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17150 [(clobber (match_dup 0))
17151 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17152 (clobber (mem:BLK (scratch)))])])
17153
17154 (define_peephole2
17155 [(match_scratch:SI 0 "r")
17156 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17157 (clobber (reg:CC FLAGS_REG))
17158 (clobber (mem:BLK (scratch)))])]
17159 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17160 [(clobber (match_dup 0))
17161 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17162 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17163 (clobber (mem:BLK (scratch)))])])
17164
17165 ;; Convert esp subtractions to push.
17166 (define_peephole2
17167 [(match_scratch:SI 0 "r")
17168 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17171 [(clobber (match_dup 0))
17172 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17173
17174 (define_peephole2
17175 [(match_scratch:SI 0 "r")
17176 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17177 (clobber (reg:CC FLAGS_REG))])]
17178 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17179 [(clobber (match_dup 0))
17180 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17181 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17182
17183 ;; Convert epilogue deallocator to pop.
17184 (define_peephole2
17185 [(match_scratch:SI 0 "r")
17186 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17187 (clobber (reg:CC FLAGS_REG))
17188 (clobber (mem:BLK (scratch)))])]
17189 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17190 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17191 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17192 (clobber (mem:BLK (scratch)))])]
17193 "")
17194
17195 ;; Two pops case is tricky, since pop causes dependency on destination register.
17196 ;; We use two registers if available.
17197 (define_peephole2
17198 [(match_scratch:SI 0 "r")
17199 (match_scratch:SI 1 "r")
17200 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17201 (clobber (reg:CC FLAGS_REG))
17202 (clobber (mem:BLK (scratch)))])]
17203 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17204 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17205 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17206 (clobber (mem:BLK (scratch)))])
17207 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17208 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17209 "")
17210
17211 (define_peephole2
17212 [(match_scratch:SI 0 "r")
17213 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17214 (clobber (reg:CC FLAGS_REG))
17215 (clobber (mem:BLK (scratch)))])]
17216 "optimize_insn_for_size_p ()"
17217 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17218 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17219 (clobber (mem:BLK (scratch)))])
17220 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17221 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17222 "")
17223
17224 ;; Convert esp additions to pop.
17225 (define_peephole2
17226 [(match_scratch:SI 0 "r")
17227 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17228 (clobber (reg:CC FLAGS_REG))])]
17229 ""
17230 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17231 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17232 "")
17233
17234 ;; Two pops case is tricky, since pop causes dependency on destination register.
17235 ;; We use two registers if available.
17236 (define_peephole2
17237 [(match_scratch:SI 0 "r")
17238 (match_scratch:SI 1 "r")
17239 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17240 (clobber (reg:CC FLAGS_REG))])]
17241 ""
17242 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17243 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17244 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17245 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17246 "")
17247
17248 (define_peephole2
17249 [(match_scratch:SI 0 "r")
17250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17251 (clobber (reg:CC FLAGS_REG))])]
17252 "optimize_insn_for_size_p ()"
17253 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17254 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17255 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17256 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17257 "")
17258 \f
17259 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17260 ;; required and register dies. Similarly for 128 to -128.
17261 (define_peephole2
17262 [(set (match_operand 0 "flags_reg_operand" "")
17263 (match_operator 1 "compare_operator"
17264 [(match_operand 2 "register_operand" "")
17265 (match_operand 3 "const_int_operand" "")]))]
17266 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17267 && incdec_operand (operands[3], GET_MODE (operands[3])))
17268 || (!TARGET_FUSE_CMP_AND_BRANCH
17269 && INTVAL (operands[3]) == 128))
17270 && ix86_match_ccmode (insn, CCGCmode)
17271 && peep2_reg_dead_p (1, operands[2])"
17272 [(parallel [(set (match_dup 0)
17273 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17274 (clobber (match_dup 2))])]
17275 "")
17276 \f
17277 (define_peephole2
17278 [(match_scratch:DI 0 "r")
17279 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17280 (clobber (reg:CC FLAGS_REG))
17281 (clobber (mem:BLK (scratch)))])]
17282 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17283 [(clobber (match_dup 0))
17284 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17285 (clobber (mem:BLK (scratch)))])])
17286
17287 (define_peephole2
17288 [(match_scratch:DI 0 "r")
17289 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17290 (clobber (reg:CC FLAGS_REG))
17291 (clobber (mem:BLK (scratch)))])]
17292 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17293 [(clobber (match_dup 0))
17294 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17295 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17296 (clobber (mem:BLK (scratch)))])])
17297
17298 ;; Convert esp subtractions to push.
17299 (define_peephole2
17300 [(match_scratch:DI 0 "r")
17301 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17304 [(clobber (match_dup 0))
17305 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17306
17307 (define_peephole2
17308 [(match_scratch:DI 0 "r")
17309 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
17310 (clobber (reg:CC FLAGS_REG))])]
17311 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17312 [(clobber (match_dup 0))
17313 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17314 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
17315
17316 ;; Convert epilogue deallocator to pop.
17317 (define_peephole2
17318 [(match_scratch:DI 0 "r")
17319 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17320 (clobber (reg:CC FLAGS_REG))
17321 (clobber (mem:BLK (scratch)))])]
17322 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17323 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17324 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17325 (clobber (mem:BLK (scratch)))])]
17326 "")
17327
17328 ;; Two pops case is tricky, since pop causes dependency on destination register.
17329 ;; We use two registers if available.
17330 (define_peephole2
17331 [(match_scratch:DI 0 "r")
17332 (match_scratch:DI 1 "r")
17333 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17334 (clobber (reg:CC FLAGS_REG))
17335 (clobber (mem:BLK (scratch)))])]
17336 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17337 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17338 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17339 (clobber (mem:BLK (scratch)))])
17340 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17341 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17342 "")
17343
17344 (define_peephole2
17345 [(match_scratch:DI 0 "r")
17346 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17347 (clobber (reg:CC FLAGS_REG))
17348 (clobber (mem:BLK (scratch)))])]
17349 "optimize_insn_for_size_p ()"
17350 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17351 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17352 (clobber (mem:BLK (scratch)))])
17353 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17354 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17355 "")
17356
17357 ;; Convert esp additions to pop.
17358 (define_peephole2
17359 [(match_scratch:DI 0 "r")
17360 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
17361 (clobber (reg:CC FLAGS_REG))])]
17362 ""
17363 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17364 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17365 "")
17366
17367 ;; Two pops case is tricky, since pop causes dependency on destination register.
17368 ;; We use two registers if available.
17369 (define_peephole2
17370 [(match_scratch:DI 0 "r")
17371 (match_scratch:DI 1 "r")
17372 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17373 (clobber (reg:CC FLAGS_REG))])]
17374 ""
17375 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17376 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17377 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
17378 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17379 "")
17380
17381 (define_peephole2
17382 [(match_scratch:DI 0 "r")
17383 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
17384 (clobber (reg:CC FLAGS_REG))])]
17385 "optimize_insn_for_size_p ()"
17386 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17387 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
17388 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
17389 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
17390 "")
17391 \f
17392 ;; Convert imul by three, five and nine into lea
17393 (define_peephole2
17394 [(parallel
17395 [(set (match_operand:SI 0 "register_operand" "")
17396 (mult:SI (match_operand:SI 1 "register_operand" "")
17397 (match_operand:SI 2 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))])]
17399 "INTVAL (operands[2]) == 3
17400 || INTVAL (operands[2]) == 5
17401 || INTVAL (operands[2]) == 9"
17402 [(set (match_dup 0)
17403 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
17404 (match_dup 1)))]
17405 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17406
17407 (define_peephole2
17408 [(parallel
17409 [(set (match_operand:SI 0 "register_operand" "")
17410 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17411 (match_operand:SI 2 "const_int_operand" "")))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "optimize_insn_for_speed_p ()
17414 && (INTVAL (operands[2]) == 3
17415 || INTVAL (operands[2]) == 5
17416 || INTVAL (operands[2]) == 9)"
17417 [(set (match_dup 0) (match_dup 1))
17418 (set (match_dup 0)
17419 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
17420 (match_dup 0)))]
17421 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17422
17423 (define_peephole2
17424 [(parallel
17425 [(set (match_operand:DI 0 "register_operand" "")
17426 (mult:DI (match_operand:DI 1 "register_operand" "")
17427 (match_operand:DI 2 "const_int_operand" "")))
17428 (clobber (reg:CC FLAGS_REG))])]
17429 "TARGET_64BIT
17430 && (INTVAL (operands[2]) == 3
17431 || INTVAL (operands[2]) == 5
17432 || INTVAL (operands[2]) == 9)"
17433 [(set (match_dup 0)
17434 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
17435 (match_dup 1)))]
17436 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17437
17438 (define_peephole2
17439 [(parallel
17440 [(set (match_operand:DI 0 "register_operand" "")
17441 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17442 (match_operand:DI 2 "const_int_operand" "")))
17443 (clobber (reg:CC FLAGS_REG))])]
17444 "TARGET_64BIT
17445 && optimize_insn_for_speed_p ()
17446 && (INTVAL (operands[2]) == 3
17447 || INTVAL (operands[2]) == 5
17448 || INTVAL (operands[2]) == 9)"
17449 [(set (match_dup 0) (match_dup 1))
17450 (set (match_dup 0)
17451 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
17452 (match_dup 0)))]
17453 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
17454
17455 ;; Imul $32bit_imm, mem, reg is vector decoded, while
17456 ;; imul $32bit_imm, reg, reg is direct decoded.
17457 (define_peephole2
17458 [(match_scratch:DI 3 "r")
17459 (parallel [(set (match_operand:DI 0 "register_operand" "")
17460 (mult:DI (match_operand:DI 1 "memory_operand" "")
17461 (match_operand:DI 2 "immediate_operand" "")))
17462 (clobber (reg:CC FLAGS_REG))])]
17463 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17464 && !satisfies_constraint_K (operands[2])"
17465 [(set (match_dup 3) (match_dup 1))
17466 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
17467 (clobber (reg:CC FLAGS_REG))])]
17468 "")
17469
17470 (define_peephole2
17471 [(match_scratch:SI 3 "r")
17472 (parallel [(set (match_operand:SI 0 "register_operand" "")
17473 (mult:SI (match_operand:SI 1 "memory_operand" "")
17474 (match_operand:SI 2 "immediate_operand" "")))
17475 (clobber (reg:CC FLAGS_REG))])]
17476 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17477 && !satisfies_constraint_K (operands[2])"
17478 [(set (match_dup 3) (match_dup 1))
17479 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
17480 (clobber (reg:CC FLAGS_REG))])]
17481 "")
17482
17483 (define_peephole2
17484 [(match_scratch:SI 3 "r")
17485 (parallel [(set (match_operand:DI 0 "register_operand" "")
17486 (zero_extend:DI
17487 (mult:SI (match_operand:SI 1 "memory_operand" "")
17488 (match_operand:SI 2 "immediate_operand" ""))))
17489 (clobber (reg:CC FLAGS_REG))])]
17490 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17491 && !satisfies_constraint_K (operands[2])"
17492 [(set (match_dup 3) (match_dup 1))
17493 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17494 (clobber (reg:CC FLAGS_REG))])]
17495 "")
17496
17497 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17498 ;; Convert it into imul reg, reg
17499 ;; It would be better to force assembler to encode instruction using long
17500 ;; immediate, but there is apparently no way to do so.
17501 (define_peephole2
17502 [(parallel [(set (match_operand:DI 0 "register_operand" "")
17503 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
17504 (match_operand:DI 2 "const_int_operand" "")))
17505 (clobber (reg:CC FLAGS_REG))])
17506 (match_scratch:DI 3 "r")]
17507 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17508 && satisfies_constraint_K (operands[2])"
17509 [(set (match_dup 3) (match_dup 2))
17510 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
17511 (clobber (reg:CC FLAGS_REG))])]
17512 {
17513 if (!rtx_equal_p (operands[0], operands[1]))
17514 emit_move_insn (operands[0], operands[1]);
17515 })
17516
17517 (define_peephole2
17518 [(parallel [(set (match_operand:SI 0 "register_operand" "")
17519 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
17520 (match_operand:SI 2 "const_int_operand" "")))
17521 (clobber (reg:CC FLAGS_REG))])
17522 (match_scratch:SI 3 "r")]
17523 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17524 && satisfies_constraint_K (operands[2])"
17525 [(set (match_dup 3) (match_dup 2))
17526 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
17527 (clobber (reg:CC FLAGS_REG))])]
17528 {
17529 if (!rtx_equal_p (operands[0], operands[1]))
17530 emit_move_insn (operands[0], operands[1]);
17531 })
17532
17533 (define_peephole2
17534 [(parallel [(set (match_operand:HI 0 "register_operand" "")
17535 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
17536 (match_operand:HI 2 "immediate_operand" "")))
17537 (clobber (reg:CC FLAGS_REG))])
17538 (match_scratch:HI 3 "r")]
17539 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
17540 [(set (match_dup 3) (match_dup 2))
17541 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
17542 (clobber (reg:CC FLAGS_REG))])]
17543 {
17544 if (!rtx_equal_p (operands[0], operands[1]))
17545 emit_move_insn (operands[0], operands[1]);
17546 })
17547
17548 ;; After splitting up read-modify operations, array accesses with memory
17549 ;; operands might end up in form:
17550 ;; sall $2, %eax
17551 ;; movl 4(%esp), %edx
17552 ;; addl %edx, %eax
17553 ;; instead of pre-splitting:
17554 ;; sall $2, %eax
17555 ;; addl 4(%esp), %eax
17556 ;; Turn it into:
17557 ;; movl 4(%esp), %edx
17558 ;; leal (%edx,%eax,4), %eax
17559
17560 (define_peephole2
17561 [(parallel [(set (match_operand 0 "register_operand" "")
17562 (ashift (match_operand 1 "register_operand" "")
17563 (match_operand 2 "const_int_operand" "")))
17564 (clobber (reg:CC FLAGS_REG))])
17565 (set (match_operand 3 "register_operand")
17566 (match_operand 4 "x86_64_general_operand" ""))
17567 (parallel [(set (match_operand 5 "register_operand" "")
17568 (plus (match_operand 6 "register_operand" "")
17569 (match_operand 7 "register_operand" "")))
17570 (clobber (reg:CC FLAGS_REG))])]
17571 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17572 /* Validate MODE for lea. */
17573 && ((!TARGET_PARTIAL_REG_STALL
17574 && (GET_MODE (operands[0]) == QImode
17575 || GET_MODE (operands[0]) == HImode))
17576 || GET_MODE (operands[0]) == SImode
17577 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17578 /* We reorder load and the shift. */
17579 && !rtx_equal_p (operands[1], operands[3])
17580 && !reg_overlap_mentioned_p (operands[0], operands[4])
17581 /* Last PLUS must consist of operand 0 and 3. */
17582 && !rtx_equal_p (operands[0], operands[3])
17583 && (rtx_equal_p (operands[3], operands[6])
17584 || rtx_equal_p (operands[3], operands[7]))
17585 && (rtx_equal_p (operands[0], operands[6])
17586 || rtx_equal_p (operands[0], operands[7]))
17587 /* The intermediate operand 0 must die or be same as output. */
17588 && (rtx_equal_p (operands[0], operands[5])
17589 || peep2_reg_dead_p (3, operands[0]))"
17590 [(set (match_dup 3) (match_dup 4))
17591 (set (match_dup 0) (match_dup 1))]
17592 {
17593 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
17594 int scale = 1 << INTVAL (operands[2]);
17595 rtx index = gen_lowpart (Pmode, operands[1]);
17596 rtx base = gen_lowpart (Pmode, operands[3]);
17597 rtx dest = gen_lowpart (mode, operands[5]);
17598
17599 operands[1] = gen_rtx_PLUS (Pmode, base,
17600 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17601 if (mode != Pmode)
17602 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17603 operands[0] = dest;
17604 })
17605 \f
17606 ;; Call-value patterns last so that the wildcard operand does not
17607 ;; disrupt insn-recog's switch tables.
17608
17609 (define_insn "*call_value_pop_0"
17610 [(set (match_operand 0 "" "")
17611 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17612 (match_operand:SI 2 "" "")))
17613 (set (reg:SI SP_REG)
17614 (plus:SI (reg:SI SP_REG)
17615 (match_operand:SI 3 "immediate_operand" "")))]
17616 "!TARGET_64BIT"
17617 {
17618 if (SIBLING_CALL_P (insn))
17619 return "jmp\t%P1";
17620 else
17621 return "call\t%P1";
17622 }
17623 [(set_attr "type" "callv")])
17624
17625 (define_insn "*call_value_pop_1"
17626 [(set (match_operand 0 "" "")
17627 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17628 (match_operand:SI 2 "" "")))
17629 (set (reg:SI SP_REG)
17630 (plus:SI (reg:SI SP_REG)
17631 (match_operand:SI 3 "immediate_operand" "i")))]
17632 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17633 {
17634 if (constant_call_address_operand (operands[1], Pmode))
17635 return "call\t%P1";
17636 return "call\t%A1";
17637 }
17638 [(set_attr "type" "callv")])
17639
17640 (define_insn "*sibcall_value_pop_1"
17641 [(set (match_operand 0 "" "")
17642 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17643 (match_operand:SI 2 "" "")))
17644 (set (reg:SI SP_REG)
17645 (plus:SI (reg:SI SP_REG)
17646 (match_operand:SI 3 "immediate_operand" "i,i")))]
17647 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17648 "@
17649 jmp\t%P1
17650 jmp\t%A1"
17651 [(set_attr "type" "callv")])
17652
17653 (define_insn "*call_value_0"
17654 [(set (match_operand 0 "" "")
17655 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17656 (match_operand:SI 2 "" "")))]
17657 "!TARGET_64BIT"
17658 {
17659 if (SIBLING_CALL_P (insn))
17660 return "jmp\t%P1";
17661 else
17662 return "call\t%P1";
17663 }
17664 [(set_attr "type" "callv")])
17665
17666 (define_insn "*call_value_0_rex64"
17667 [(set (match_operand 0 "" "")
17668 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17669 (match_operand:DI 2 "const_int_operand" "")))]
17670 "TARGET_64BIT"
17671 {
17672 if (SIBLING_CALL_P (insn))
17673 return "jmp\t%P1";
17674 else
17675 return "call\t%P1";
17676 }
17677 [(set_attr "type" "callv")])
17678
17679 (define_insn "*call_value_0_rex64_ms_sysv"
17680 [(set (match_operand 0 "" "")
17681 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17682 (match_operand:DI 2 "const_int_operand" "")))
17683 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17684 (clobber (reg:TI XMM6_REG))
17685 (clobber (reg:TI XMM7_REG))
17686 (clobber (reg:TI XMM8_REG))
17687 (clobber (reg:TI XMM9_REG))
17688 (clobber (reg:TI XMM10_REG))
17689 (clobber (reg:TI XMM11_REG))
17690 (clobber (reg:TI XMM12_REG))
17691 (clobber (reg:TI XMM13_REG))
17692 (clobber (reg:TI XMM14_REG))
17693 (clobber (reg:TI XMM15_REG))
17694 (clobber (reg:DI SI_REG))
17695 (clobber (reg:DI DI_REG))]
17696 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17697 {
17698 if (SIBLING_CALL_P (insn))
17699 return "jmp\t%P1";
17700 else
17701 return "call\t%P1";
17702 }
17703 [(set_attr "type" "callv")])
17704
17705 (define_insn "*call_value_1"
17706 [(set (match_operand 0 "" "")
17707 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17708 (match_operand:SI 2 "" "")))]
17709 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17710 {
17711 if (constant_call_address_operand (operands[1], Pmode))
17712 return "call\t%P1";
17713 return "call\t%A1";
17714 }
17715 [(set_attr "type" "callv")])
17716
17717 (define_insn "*sibcall_value_1"
17718 [(set (match_operand 0 "" "")
17719 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17720 (match_operand:SI 2 "" "")))]
17721 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17722 "@
17723 jmp\t%P1
17724 jmp\t%A1"
17725 [(set_attr "type" "callv")])
17726
17727 (define_insn "*call_value_1_rex64"
17728 [(set (match_operand 0 "" "")
17729 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17730 (match_operand:DI 2 "" "")))]
17731 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17732 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17733 {
17734 if (constant_call_address_operand (operands[1], Pmode))
17735 return "call\t%P1";
17736 return "call\t%A1";
17737 }
17738 [(set_attr "type" "callv")])
17739
17740 (define_insn "*call_value_1_rex64_ms_sysv"
17741 [(set (match_operand 0 "" "")
17742 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17743 (match_operand:DI 2 "" "")))
17744 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17745 (clobber (reg:TI XMM6_REG))
17746 (clobber (reg:TI XMM7_REG))
17747 (clobber (reg:TI XMM8_REG))
17748 (clobber (reg:TI XMM9_REG))
17749 (clobber (reg:TI XMM10_REG))
17750 (clobber (reg:TI XMM11_REG))
17751 (clobber (reg:TI XMM12_REG))
17752 (clobber (reg:TI XMM13_REG))
17753 (clobber (reg:TI XMM14_REG))
17754 (clobber (reg:TI XMM15_REG))
17755 (clobber (reg:DI SI_REG))
17756 (clobber (reg:DI DI_REG))]
17757 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17758 {
17759 if (constant_call_address_operand (operands[1], Pmode))
17760 return "call\t%P1";
17761 return "call\t%A1";
17762 }
17763 [(set_attr "type" "callv")])
17764
17765 (define_insn "*call_value_1_rex64_large"
17766 [(set (match_operand 0 "" "")
17767 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17768 (match_operand:DI 2 "" "")))]
17769 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17770 "call\t%A1"
17771 [(set_attr "type" "callv")])
17772
17773 (define_insn "*sibcall_value_1_rex64"
17774 [(set (match_operand 0 "" "")
17775 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17776 (match_operand:DI 2 "" "")))]
17777 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17778 "@
17779 jmp\t%P1
17780 jmp\t%A1"
17781 [(set_attr "type" "callv")])
17782 \f
17783 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17784 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17785 ;; caught for use by garbage collectors and the like. Using an insn that
17786 ;; maps to SIGILL makes it more likely the program will rightfully die.
17787 ;; Keeping with tradition, "6" is in honor of #UD.
17788 (define_insn "trap"
17789 [(trap_if (const_int 1) (const_int 6))]
17790 ""
17791 { return ASM_SHORT "0x0b0f"; }
17792 [(set_attr "length" "2")])
17793
17794 (define_expand "sse_prologue_save"
17795 [(parallel [(set (match_operand:BLK 0 "" "")
17796 (unspec:BLK [(reg:DI XMM0_REG)
17797 (reg:DI XMM1_REG)
17798 (reg:DI XMM2_REG)
17799 (reg:DI XMM3_REG)
17800 (reg:DI XMM4_REG)
17801 (reg:DI XMM5_REG)
17802 (reg:DI XMM6_REG)
17803 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17804 (clobber (reg:CC FLAGS_REG))
17805 (clobber (match_operand:DI 1 "register_operand" ""))
17806 (use (match_operand:DI 2 "immediate_operand" ""))
17807 (use (label_ref:DI (match_operand 3 "" "")))
17808 (clobber (match_operand:DI 4 "register_operand" ""))
17809 (use (match_dup 1))])]
17810 "TARGET_64BIT"
17811 "")
17812
17813 ;; Pre-reload version of prologue save. Until after prologue generation we don't know
17814 ;; what the size of save instruction will be.
17815 ;; Operand 0+operand 6 is the memory save area
17816 ;; Operand 1 is number of registers to save (will get overwritten to operand 5)
17817 ;; Operand 2 is number of non-vaargs SSE arguments
17818 ;; Operand 3 is label starting the save block
17819 ;; Operand 4 is used for temporary computation of jump address
17820 (define_insn "*sse_prologue_save_insn1"
17821 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17822 (match_operand:DI 6 "const_int_operand" "n")))
17823 (unspec:BLK [(reg:DI XMM0_REG)
17824 (reg:DI XMM1_REG)
17825 (reg:DI XMM2_REG)
17826 (reg:DI XMM3_REG)
17827 (reg:DI XMM4_REG)
17828 (reg:DI XMM5_REG)
17829 (reg:DI XMM6_REG)
17830 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17831 (clobber (reg:CC FLAGS_REG))
17832 (clobber (match_operand:DI 1 "register_operand" "=r"))
17833 (use (match_operand:DI 2 "const_int_operand" "i"))
17834 (use (label_ref:DI (match_operand 3 "" "X")))
17835 (clobber (match_operand:DI 4 "register_operand" "=&r"))
17836 (use (match_operand:DI 5 "register_operand" "1"))]
17837 "TARGET_64BIT
17838 && INTVAL (operands[6]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17839 && INTVAL (operands[6]) + INTVAL (operands[2]) * 16 >= -128"
17840 "#"
17841 [(set_attr "type" "other")
17842 (set_attr "memory" "store")
17843 (set_attr "mode" "DI")])
17844
17845 ;; We know size of save instruction; expand the computation of jump address
17846 ;; in the jumptable.
17847 (define_split
17848 [(parallel [(set (match_operand:BLK 0 "" "")
17849 (unspec:BLK [(reg:DI XMM0_REG)
17850 (reg:DI XMM1_REG)
17851 (reg:DI XMM2_REG)
17852 (reg:DI XMM3_REG)
17853 (reg:DI XMM4_REG)
17854 (reg:DI XMM5_REG)
17855 (reg:DI XMM6_REG)
17856 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
17857 (clobber (reg:CC FLAGS_REG))
17858 (clobber (match_operand:DI 1 "register_operand" ""))
17859 (use (match_operand:DI 2 "const_int_operand" ""))
17860 (use (match_operand 3 "" ""))
17861 (clobber (match_operand:DI 4 "register_operand" ""))
17862 (use (match_operand:DI 5 "register_operand" ""))])]
17863 "reload_completed"
17864 [(parallel [(set (match_dup 0)
17865 (unspec:BLK [(reg:DI XMM0_REG)
17866 (reg:DI XMM1_REG)
17867 (reg:DI XMM2_REG)
17868 (reg:DI XMM3_REG)
17869 (reg:DI XMM4_REG)
17870 (reg:DI XMM5_REG)
17871 (reg:DI XMM6_REG)
17872 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17873 (use (match_dup 1))
17874 (use (match_dup 2))
17875 (use (match_dup 3))
17876 (use (match_dup 5))])]
17877 {
17878 /* Movaps is 4 bytes, AVX and movsd is 5 bytes. */
17879 int size = 4 + (TARGET_AVX || crtl->stack_alignment_needed < 128);
17880
17881 /* Compute address to jump to:
17882 label - eax*size + nnamed_sse_arguments*size. */
17883 if (size == 5)
17884 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17885 gen_rtx_PLUS
17886 (Pmode,
17887 gen_rtx_MULT (Pmode, operands[1],
17888 GEN_INT (4)),
17889 operands[1])));
17890 else if (size == 4)
17891 emit_insn (gen_rtx_SET (VOIDmode, operands[4],
17892 gen_rtx_MULT (Pmode, operands[1],
17893 GEN_INT (4))));
17894 else
17895 gcc_unreachable ();
17896 if (INTVAL (operands[2]))
17897 emit_move_insn
17898 (operands[1],
17899 gen_rtx_CONST (DImode,
17900 gen_rtx_PLUS (DImode,
17901 operands[3],
17902 GEN_INT (INTVAL (operands[2])
17903 * size))));
17904 else
17905 emit_move_insn (operands[1], operands[3]);
17906 emit_insn (gen_subdi3 (operands[1], operands[1], operands[4]));
17907 operands[5] = GEN_INT (size);
17908 })
17909
17910 (define_insn "sse_prologue_save_insn"
17911 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
17912 (match_operand:DI 4 "const_int_operand" "n")))
17913 (unspec:BLK [(reg:DI XMM0_REG)
17914 (reg:DI XMM1_REG)
17915 (reg:DI XMM2_REG)
17916 (reg:DI XMM3_REG)
17917 (reg:DI XMM4_REG)
17918 (reg:DI XMM5_REG)
17919 (reg:DI XMM6_REG)
17920 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE_LOW))
17921 (use (match_operand:DI 1 "register_operand" "r"))
17922 (use (match_operand:DI 2 "const_int_operand" "i"))
17923 (use (label_ref:DI (match_operand 3 "" "X")))
17924 (use (match_operand:DI 5 "const_int_operand" "i"))]
17925 "TARGET_64BIT
17926 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
17927 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
17928 {
17929 int i;
17930 operands[0] = gen_rtx_MEM (Pmode,
17931 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
17932 /* VEX instruction with a REX prefix will #UD. */
17933 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
17934 gcc_unreachable ();
17935
17936 output_asm_insn ("jmp\t%A1", operands);
17937 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
17938 {
17939 operands[4] = adjust_address (operands[0], DImode, i*16);
17940 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
17941 PUT_MODE (operands[4], TImode);
17942 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
17943 output_asm_insn ("rex", operands);
17944 if (crtl->stack_alignment_needed < 128)
17945 output_asm_insn ("%vmovsd\t{%5, %4|%4, %5}", operands);
17946 else
17947 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
17948 }
17949 (*targetm.asm_out.internal_label) (asm_out_file, "L",
17950 CODE_LABEL_NUMBER (operands[3]));
17951 return "";
17952 }
17953 [(set_attr "type" "other")
17954 (set_attr "length_immediate" "0")
17955 (set_attr "length_address" "0")
17956 ;; 2 bytes for jump and opernds[4] bytes for each save.
17957 (set (attr "length")
17958 (plus (const_int 2)
17959 (mult (symbol_ref ("INTVAL (operands[5])"))
17960 (symbol_ref ("X86_64_SSE_REGPARM_MAX - INTVAL (operands[2])")))))
17961 (set_attr "memory" "store")
17962 (set_attr "modrm" "0")
17963 (set_attr "prefix" "maybe_vex")
17964 (set_attr "mode" "DI")])
17965
17966 (define_expand "prefetch"
17967 [(prefetch (match_operand 0 "address_operand" "")
17968 (match_operand:SI 1 "const_int_operand" "")
17969 (match_operand:SI 2 "const_int_operand" ""))]
17970 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17971 {
17972 int rw = INTVAL (operands[1]);
17973 int locality = INTVAL (operands[2]);
17974
17975 gcc_assert (rw == 0 || rw == 1);
17976 gcc_assert (locality >= 0 && locality <= 3);
17977 gcc_assert (GET_MODE (operands[0]) == Pmode
17978 || GET_MODE (operands[0]) == VOIDmode);
17979
17980 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17981 supported by SSE counterpart or the SSE prefetch is not available
17982 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17983 of locality. */
17984 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17985 operands[2] = GEN_INT (3);
17986 else
17987 operands[1] = const0_rtx;
17988 })
17989
17990 (define_insn "*prefetch_sse_<mode>"
17991 [(prefetch (match_operand:P 0 "address_operand" "p")
17992 (const_int 0)
17993 (match_operand:SI 1 "const_int_operand" ""))]
17994 "TARGET_PREFETCH_SSE"
17995 {
17996 static const char * const patterns[4] = {
17997 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17998 };
17999
18000 int locality = INTVAL (operands[1]);
18001 gcc_assert (locality >= 0 && locality <= 3);
18002
18003 return patterns[locality];
18004 }
18005 [(set_attr "type" "sse")
18006 (set_attr "atom_sse_attr" "prefetch")
18007 (set (attr "length_address")
18008 (symbol_ref "memory_address_length (operands[0])"))
18009 (set_attr "memory" "none")])
18010
18011 (define_insn "*prefetch_3dnow_<mode>"
18012 [(prefetch (match_operand:P 0 "address_operand" "p")
18013 (match_operand:SI 1 "const_int_operand" "n")
18014 (const_int 3))]
18015 "TARGET_3DNOW"
18016 {
18017 if (INTVAL (operands[1]) == 0)
18018 return "prefetch\t%a0";
18019 else
18020 return "prefetchw\t%a0";
18021 }
18022 [(set_attr "type" "mmx")
18023 (set (attr "length_address")
18024 (symbol_ref "memory_address_length (operands[0])"))
18025 (set_attr "memory" "none")])
18026
18027 (define_expand "stack_protect_set"
18028 [(match_operand 0 "memory_operand" "")
18029 (match_operand 1 "memory_operand" "")]
18030 ""
18031 {
18032 #ifdef TARGET_THREAD_SSP_OFFSET
18033 if (TARGET_64BIT)
18034 emit_insn (gen_stack_tls_protect_set_di (operands[0],
18035 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18036 else
18037 emit_insn (gen_stack_tls_protect_set_si (operands[0],
18038 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18039 #else
18040 if (TARGET_64BIT)
18041 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18042 else
18043 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18044 #endif
18045 DONE;
18046 })
18047
18048 (define_insn "stack_protect_set_si"
18049 [(set (match_operand:SI 0 "memory_operand" "=m")
18050 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18051 (set (match_scratch:SI 2 "=&r") (const_int 0))
18052 (clobber (reg:CC FLAGS_REG))]
18053 ""
18054 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18055 [(set_attr "type" "multi")])
18056
18057 (define_insn "stack_protect_set_di"
18058 [(set (match_operand:DI 0 "memory_operand" "=m")
18059 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18060 (set (match_scratch:DI 2 "=&r") (const_int 0))
18061 (clobber (reg:CC FLAGS_REG))]
18062 "TARGET_64BIT"
18063 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18064 [(set_attr "type" "multi")])
18065
18066 (define_insn "stack_tls_protect_set_si"
18067 [(set (match_operand:SI 0 "memory_operand" "=m")
18068 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
18069 UNSPEC_SP_TLS_SET))
18070 (set (match_scratch:SI 2 "=&r") (const_int 0))
18071 (clobber (reg:CC FLAGS_REG))]
18072 ""
18073 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18074 [(set_attr "type" "multi")])
18075
18076 (define_insn "stack_tls_protect_set_di"
18077 [(set (match_operand:DI 0 "memory_operand" "=m")
18078 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
18079 UNSPEC_SP_TLS_SET))
18080 (set (match_scratch:DI 2 "=&r") (const_int 0))
18081 (clobber (reg:CC FLAGS_REG))]
18082 "TARGET_64BIT"
18083 {
18084 /* The kernel uses a different segment register for performance reasons; a
18085 system call would not have to trash the userspace segment register,
18086 which would be expensive */
18087 if (ix86_cmodel != CM_KERNEL)
18088 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18089 else
18090 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18091 }
18092 [(set_attr "type" "multi")])
18093
18094 (define_expand "stack_protect_test"
18095 [(match_operand 0 "memory_operand" "")
18096 (match_operand 1 "memory_operand" "")
18097 (match_operand 2 "" "")]
18098 ""
18099 {
18100 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18101
18102 #ifdef TARGET_THREAD_SSP_OFFSET
18103 if (TARGET_64BIT)
18104 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18105 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18106 else
18107 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18108 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18109 #else
18110 if (TARGET_64BIT)
18111 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18112 else
18113 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18114 #endif
18115
18116 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18117 flags, const0_rtx, operands[2]));
18118 DONE;
18119 })
18120
18121 (define_insn "stack_protect_test_si"
18122 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18123 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18124 (match_operand:SI 2 "memory_operand" "m")]
18125 UNSPEC_SP_TEST))
18126 (clobber (match_scratch:SI 3 "=&r"))]
18127 ""
18128 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18129 [(set_attr "type" "multi")])
18130
18131 (define_insn "stack_protect_test_di"
18132 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18133 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18134 (match_operand:DI 2 "memory_operand" "m")]
18135 UNSPEC_SP_TEST))
18136 (clobber (match_scratch:DI 3 "=&r"))]
18137 "TARGET_64BIT"
18138 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18139 [(set_attr "type" "multi")])
18140
18141 (define_insn "stack_tls_protect_test_si"
18142 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18143 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18144 (match_operand:SI 2 "const_int_operand" "i")]
18145 UNSPEC_SP_TLS_TEST))
18146 (clobber (match_scratch:SI 3 "=r"))]
18147 ""
18148 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18149 [(set_attr "type" "multi")])
18150
18151 (define_insn "stack_tls_protect_test_di"
18152 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18153 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18154 (match_operand:DI 2 "const_int_operand" "i")]
18155 UNSPEC_SP_TLS_TEST))
18156 (clobber (match_scratch:DI 3 "=r"))]
18157 "TARGET_64BIT"
18158 {
18159 /* The kernel uses a different segment register for performance reasons; a
18160 system call would not have to trash the userspace segment register,
18161 which would be expensive */
18162 if (ix86_cmodel != CM_KERNEL)
18163 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18164 else
18165 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18166 }
18167 [(set_attr "type" "multi")])
18168
18169 (define_insn "sse4_2_crc32<mode>"
18170 [(set (match_operand:SI 0 "register_operand" "=r")
18171 (unspec:SI
18172 [(match_operand:SI 1 "register_operand" "0")
18173 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18174 UNSPEC_CRC32))]
18175 "TARGET_SSE4_2 || TARGET_CRC32"
18176 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18177 [(set_attr "type" "sselog1")
18178 (set_attr "prefix_rep" "1")
18179 (set_attr "prefix_extra" "1")
18180 (set (attr "prefix_data16")
18181 (if_then_else (match_operand:HI 2 "" "")
18182 (const_string "1")
18183 (const_string "*")))
18184 (set (attr "prefix_rex")
18185 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18186 (const_string "1")
18187 (const_string "*")))
18188 (set_attr "mode" "SI")])
18189
18190 (define_insn "sse4_2_crc32di"
18191 [(set (match_operand:DI 0 "register_operand" "=r")
18192 (unspec:DI
18193 [(match_operand:DI 1 "register_operand" "0")
18194 (match_operand:DI 2 "nonimmediate_operand" "rm")]
18195 UNSPEC_CRC32))]
18196 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18197 "crc32{q}\t{%2, %0|%0, %2}"
18198 [(set_attr "type" "sselog1")
18199 (set_attr "prefix_rep" "1")
18200 (set_attr "prefix_extra" "1")
18201 (set_attr "mode" "DI")])
18202
18203 (define_expand "rdpmc"
18204 [(match_operand:DI 0 "register_operand" "")
18205 (match_operand:SI 1 "register_operand" "")]
18206 ""
18207 {
18208 rtx reg = gen_reg_rtx (DImode);
18209 rtx si;
18210
18211 /* Force operand 1 into ECX. */
18212 rtx ecx = gen_rtx_REG (SImode, CX_REG);
18213 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18214 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18215 UNSPECV_RDPMC);
18216
18217 if (TARGET_64BIT)
18218 {
18219 rtvec vec = rtvec_alloc (2);
18220 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18221 rtx upper = gen_reg_rtx (DImode);
18222 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18223 gen_rtvec (1, const0_rtx),
18224 UNSPECV_RDPMC);
18225 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18226 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18227 emit_insn (load);
18228 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18229 NULL, 1, OPTAB_DIRECT);
18230 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18231 OPTAB_DIRECT);
18232 }
18233 else
18234 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18235 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18236 DONE;
18237 })
18238
18239 (define_insn "*rdpmc"
18240 [(set (match_operand:DI 0 "register_operand" "=A")
18241 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18242 UNSPECV_RDPMC))]
18243 "!TARGET_64BIT"
18244 "rdpmc"
18245 [(set_attr "type" "other")
18246 (set_attr "length" "2")])
18247
18248 (define_insn "*rdpmc_rex64"
18249 [(set (match_operand:DI 0 "register_operand" "=a")
18250 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18251 UNSPECV_RDPMC))
18252 (set (match_operand:DI 1 "register_operand" "=d")
18253 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18254 "TARGET_64BIT"
18255 "rdpmc"
18256 [(set_attr "type" "other")
18257 (set_attr "length" "2")])
18258
18259 (define_expand "rdtsc"
18260 [(set (match_operand:DI 0 "register_operand" "")
18261 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18262 ""
18263 {
18264 if (TARGET_64BIT)
18265 {
18266 rtvec vec = rtvec_alloc (2);
18267 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18268 rtx upper = gen_reg_rtx (DImode);
18269 rtx lower = gen_reg_rtx (DImode);
18270 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18271 gen_rtvec (1, const0_rtx),
18272 UNSPECV_RDTSC);
18273 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18274 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18275 emit_insn (load);
18276 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18277 NULL, 1, OPTAB_DIRECT);
18278 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18279 OPTAB_DIRECT);
18280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18281 DONE;
18282 }
18283 })
18284
18285 (define_insn "*rdtsc"
18286 [(set (match_operand:DI 0 "register_operand" "=A")
18287 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18288 "!TARGET_64BIT"
18289 "rdtsc"
18290 [(set_attr "type" "other")
18291 (set_attr "length" "2")])
18292
18293 (define_insn "*rdtsc_rex64"
18294 [(set (match_operand:DI 0 "register_operand" "=a")
18295 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18296 (set (match_operand:DI 1 "register_operand" "=d")
18297 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18298 "TARGET_64BIT"
18299 "rdtsc"
18300 [(set_attr "type" "other")
18301 (set_attr "length" "2")])
18302
18303 (define_expand "rdtscp"
18304 [(match_operand:DI 0 "register_operand" "")
18305 (match_operand:SI 1 "memory_operand" "")]
18306 ""
18307 {
18308 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18309 gen_rtvec (1, const0_rtx),
18310 UNSPECV_RDTSCP);
18311 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18312 gen_rtvec (1, const0_rtx),
18313 UNSPECV_RDTSCP);
18314 rtx reg = gen_reg_rtx (DImode);
18315 rtx tmp = gen_reg_rtx (SImode);
18316
18317 if (TARGET_64BIT)
18318 {
18319 rtvec vec = rtvec_alloc (3);
18320 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18321 rtx upper = gen_reg_rtx (DImode);
18322 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18323 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18324 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18325 emit_insn (load);
18326 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18327 NULL, 1, OPTAB_DIRECT);
18328 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18329 OPTAB_DIRECT);
18330 }
18331 else
18332 {
18333 rtvec vec = rtvec_alloc (2);
18334 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18335 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18336 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18337 emit_insn (load);
18338 }
18339 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18340 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18341 DONE;
18342 })
18343
18344 (define_insn "*rdtscp"
18345 [(set (match_operand:DI 0 "register_operand" "=A")
18346 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18347 (set (match_operand:SI 1 "register_operand" "=c")
18348 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18349 "!TARGET_64BIT"
18350 "rdtscp"
18351 [(set_attr "type" "other")
18352 (set_attr "length" "3")])
18353
18354 (define_insn "*rdtscp_rex64"
18355 [(set (match_operand:DI 0 "register_operand" "=a")
18356 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18357 (set (match_operand:DI 1 "register_operand" "=d")
18358 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18359 (set (match_operand:SI 2 "register_operand" "=c")
18360 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18361 "TARGET_64BIT"
18362 "rdtscp"
18363 [(set_attr "type" "other")
18364 (set_attr "length" "3")])
18365
18366 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18367 ;;
18368 ;; LWP instructions
18369 ;;
18370 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18371
18372 (define_expand "lwp_llwpcb"
18373 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18374 UNSPECV_LLWP_INTRINSIC)]
18375 "TARGET_LWP"
18376 "")
18377
18378 (define_insn "*lwp_llwpcb<mode>1"
18379 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18380 UNSPECV_LLWP_INTRINSIC)]
18381 "TARGET_LWP"
18382 "llwpcb\t%0"
18383 [(set_attr "type" "lwp")
18384 (set_attr "mode" "<MODE>")
18385 (set_attr "length" "5")])
18386
18387 (define_expand "lwp_slwpcb"
18388 [(set (match_operand 0 "register_operand" "=r")
18389 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18390 "TARGET_LWP"
18391 {
18392 if (TARGET_64BIT)
18393 emit_insn (gen_lwp_slwpcbdi (operands[0]));
18394 else
18395 emit_insn (gen_lwp_slwpcbsi (operands[0]));
18396 DONE;
18397 })
18398
18399 (define_insn "lwp_slwpcb<mode>"
18400 [(set (match_operand:P 0 "register_operand" "=r")
18401 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18402 "TARGET_LWP"
18403 "slwpcb\t%0"
18404 [(set_attr "type" "lwp")
18405 (set_attr "mode" "<MODE>")
18406 (set_attr "length" "5")])
18407
18408 (define_expand "lwp_lwpval<mode>3"
18409 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18410 (match_operand:SI 2 "nonimmediate_operand" "rm")
18411 (match_operand:SI 3 "const_int_operand" "i")]
18412 UNSPECV_LWPVAL_INTRINSIC)]
18413 "TARGET_LWP"
18414 "/* Avoid unused variable warning. */
18415 (void) operand0;")
18416
18417 (define_insn "*lwp_lwpval<mode>3_1"
18418 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18419 (match_operand:SI 1 "nonimmediate_operand" "rm")
18420 (match_operand:SI 2 "const_int_operand" "i")]
18421 UNSPECV_LWPVAL_INTRINSIC)]
18422 "TARGET_LWP"
18423 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18424 [(set_attr "type" "lwp")
18425 (set_attr "mode" "<MODE>")
18426 (set (attr "length")
18427 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18428
18429 (define_expand "lwp_lwpins<mode>3"
18430 [(set (reg:CCC FLAGS_REG)
18431 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18432 (match_operand:SI 2 "nonimmediate_operand" "rm")
18433 (match_operand:SI 3 "const_int_operand" "i")]
18434 UNSPECV_LWPINS_INTRINSIC))
18435 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18436 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18437 "TARGET_LWP"
18438 "")
18439
18440 (define_insn "*lwp_lwpins<mode>3_1"
18441 [(set (reg:CCC FLAGS_REG)
18442 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18443 (match_operand:SI 1 "nonimmediate_operand" "rm")
18444 (match_operand:SI 2 "const_int_operand" "i")]
18445 UNSPECV_LWPINS_INTRINSIC))]
18446 "TARGET_LWP"
18447 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18448 [(set_attr "type" "lwp")
18449 (set_attr "mode" "<MODE>")
18450 (set (attr "length")
18451 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18452
18453 (include "mmx.md")
18454 (include "sse.md")
18455 (include "sync.md")